Литмир - Электронная Библиотека

Чтобы решить задачу с ограничением на длину имени логина в запросе, нужно определить следующее ограничение в свойстве Constraints при создании маршрута:

var constraint = new RouteValueDictionary {

                         {"user", "\\w{4,}"}

                     };

routes.Add(new Route(

    "{controller}/{action}/{user}/",

    defaults,

    constraint,

    null,

    new MvcRouteHandler()

));

Ограничение определяется как элемент словаря RouteValueDictionary, где ключом является имя параметра, а значением регулярное выражение, описывающее правило для параметра. В данном случае регулярное выражение \w{4,} предполагает, что строка должна содержать буквы и цифры в размере от 4 элементов.

После такого определения маршрута, если вы попытаетесь обратиться по следующему адресу http://sample.domain/Home/Index/foo, вы получите стандартное сообщение браузера о возвращенной сервером ошибке с кодом 404 "Страница не найдена".

Ранее в этой главе мы рассмотрели ограничения параметров как коллекцию регулярных выражений в свойстве Constraints класса Route. Однако существует еще один, альтернативный, способ создания маршрута на базе интерфейса iRouteConstraint. Он также описан в этой главе. Вместо того чтобы добавлять в коллекцию Constraints строки с регулярными выражениями, можно воспользоваться интерфейсом IRouteConstraint и реализовать класс, который будет выполнять проверку параметров на соответствие условиям. Добавляется такой класс похожим на обычный способом:

routes.MapRoute("Default",

                "{controller}/{action}/{user}",

                new {controller = "Home",

                     action = "Index",

                     id = ""},

                new {user = new SampleConstraint()}

);

Здесь SampleConstraint — это класс, который реализует интерфейс IRouteConstraint.

Параметры маршрута и свойство DataTokens

В механизме маршрутизации ASP.NET при создании маршрута можно указать набор параметров DataTokens. Используя DataTokens, разработчик может передать в маршрут набор данных, которые позднее будут использованы пользовательским вариантом обработчика маршрута при сопоставлении клиентского запроса маршруту. Иными словами, DataTokens помогает определить больше данных для маршрутов в случае, когда пользователь сам определяет обработчик маршрута. В MVC Framework каждому маршруту сопоставляется уже готовый обработчик MvcHandler. Поэтому надобность в пользовательских параметрах, передаваемых через DataTokens, отпадает, очевидно, что эти данные MvcHandler использовать не сможет. В связи с тем, что данные DataTokens в проектах MVC Framework по умолчанию не нужны, в методе расширения MapRoute создание такого набора вовсе отсутствует.

Однако есть исключение, делающее свойство DataTokens экземпляра маршрута полезным даже для проектов MVC Framework. Дело в том, что фабрика контроллеров по умолчанию проверяет DataTokens на наличие параметра Namespaces, от которого в дальнейшем зависит, какие контроллеры могут быть выбраны для инстанцирования.

Параметр Namespaces может содержать строки в виде перечисления типа iEnumerable<string>. Когда фабрика контроллеров находит такой параметр в свойстве DataTokens, она предполагает, что в нем перечислены наименования пространств имен, в которых можно искать контроллеры для инстанцирования в ответ на клиентский запрос.

Наличие такого механизма, как ограничение поиска контроллеров для маршрута определенным списком пространств имен, нельзя переоценить. В крупных проектах, в которых могут создаваться десятки или сотни пространств имен, поиск типа контроллера через механизм отражений может занимать неоправданно много процессорного времени. Ограничив маршрут набором пространств имен, вы поможете фабрике контроллеров более быстро найти и инстанцировать необходимый для обработки маршрута контроллер.

Для того чтобы указать определенный набор пространств имен при создании маршрута, необходимо проделать примерно такие действия:

var route = routes.MapRoute(

      "AccountLogOn",

      "LogOn",

      new { controller = "Account", action = "LogOn" }

    );

route.DataTokens = new RouteValueDictionary();

List<string> nsList = new List<string>();

nsList.Add("SomeNamespace");

nsList.Add("SomeNamespace2");

route.DataTokens.Add("Namespaces", nsList);

Здесь после создания собственно маршрута, у него инициализируется свойство DataTokens и заполняется ключом Namespaces со значением списка из двух строк с именами пространств имен SomeNamespace и SomeNamespace2. Такие действия с маршрутом подразумевают, что контроллер для него будет искаться в пространствах имен SomeNamespace и SomeNamespace2.

Еще одна возможность ограничить список пространств имен, в которых фабрика контроллеров ищет контроллеры для инстанцирования, — это свойство DefaultNamespaces класса ControllerBuilder. В каждом приложении MVC Framework существует экземпляр ControllerBuilder в виде статического свойства Current класса ControllerBuilder. Используя свойство DefaultNamespaces, вы можете определить пространства имен по умолчанию, в которых фабрика контроллеров будет искать контроллеры.

ControllerBuilder.Current.DefaultNamespaces.Add("SomeNamespaces3");

DataTokens и DefaultNamespaces можно использовать вместе. В целом очередность работы механизмов DataTokens и DefaultNamespaces в процессе поиска контроллера следующая:

1. Фабрика контроллеров пытается найти контроллер в пространствах имен, определенных в DataTokens маршрута, поиск прекращается, если такой контроллер найден.

2. Фабрика контроллеров пытается найти контроллер в пространствах имен, определенных через DefaultNamespaces, поиск прекращается, если контроллер найден.

3. В конце концов, фабрика контроллеров просматривает все пространства имен в поиске необходимого контроллера.

Здесь следует обратить внимание на то, что определение неверных пространств имен в DataTokens и DefaultNamespaces может привести к тому, что поиск вместо ускорения замедлится, поскольку будет проходить трижды, согласно информации каждого механизма.

Игнорирование маршрутов

Игнорирование маршрутов — это необходимый инструмент, позволяющий указать маршрут, т. е. группу клиентских запросов, которые не будут обрабатываться MVC Framework. Есть множество случаев, когда запрос не должен обрабатываться как запрос к MVC Framework. Например, запросы к изображениям, находящимся на сервере, или к любым другим статическим ресурсам, таким как файлы скриптов или стилей. Нет совершенно никакой необходимости в том, чтобы такие запросы проходили через многоступенчатую обработку MVC Framework. Вместо этого файлы изображений или стилей должны отдаваться клиентам напрямую.

По умолчанию механизмы маршрутизации ASP.NET, а следовательно, и MVC Framework исключают запросы к существующим локальным файлам из обработки механизмом маршрутизации. Но, как будет показано далее, существует возможность гибко управлять тем, какие файлы пропускать, а какие — нет.

Чтобы создать правило игнорирования маршрута, MVC Framework содержит IgnoreRoute — метод расширения класса RouteCollection. Этот метод имеет следующие входные параметры:

□ url — указывает шаблон маршрута, все запросы, которые подпадают под этот маршрут, будут игнорироваться MVC Framework;

48
{"b":"971383","o":1}