Механизм MVC Framework определяет два базовых параметра маршрутов: controller и action, которые предназначены для определения разработчиком месторасположения наименования контроллера и действия в строке запроса. Остальные параметры являются пользовательскими и определяются разработчиком. Например, следующий маршрут {controller}/{action}/{user}/{page} определяет кроме базовых параметров controller и action еще два пользовательских: user и page. Такому маршруту может соответствовать строка запроса http://sample.domain/User/GetUserMessages/user1/2/. Механизм MVC Framework при сопоставлении данных маршрутов и строки запроса определит, что требуется вызвать действие с именем GetUserMessages в контроллере с именем UserController, которому нужно передать два параметра: user со значением user1 и page со значением 2.
Одним из базовых классов маршрутизации ASP.NET является класс Route, который позволяет разработчику определить свойства маршрута. Рассмотрим основные свойства, которые содержит класс Route:
□ Constraints — свойство типа RouteValueDictionary, которое хранит все ограничения, накладываемые разработчиком на маршрут;
□ DataTokens — свойство типа RouteValueDictionary, которое хранит набор параметров, не участвующих в разборе шаблона, но передающихся обработчику маршрута как дополнительная информация;
□ Defaults — свойство типа RouteValueDictionary, которое хранит значения параметров маршрута по умолчанию. Данные значения используются, когда определенная для маршрута строка URL не содержит необходимого параметра;
□ RouteHandler — свойство, реализующее интерфейс IRouteHandler, является обработчиком маршрута, который определяет, подходит или нет заданный URL запроса к маршруту;
□ Url — строковое свойство, которое содержит определение шаблона маршрута.
Создание экземпляра Route не вызывает трудностей, например, в следующем фрагменте представлено создание маршрута, аналогичного тому, что создается в проекте MVC Framework по умолчанию:
var defaults = new RouteValueDictionary
{
{"controller", "Home"},
{"action", "Index"},
{"id", ""}
};
routes.Add(new Route(
"{controller}/{action}/{id}",
defaults,
null,
null,
new MvcRouteHandler()
));
Класс Route имеет несколько конструкторов, конструктор с самым большим числом параметров определен так:
public Route(string url,
RouteValueDictionary defaults,
RouteValueDictionary constraints,
RouteValueDictionary dataTokens,
IRouteHandler routeHandler
)
Рассмотрим параметры, которые передаются в этот конструктор:
□ url — обязательный параметр, определяет строку шаблона для маршрута;
□ defaults — необязательный параметр, определяет значения по умолчанию для параметров маршрута;
□ constraints — необязательный параметр, определяет ограничения для маршрута;
□ dataTokens — необязательный параметр, определяет дополнительные данные для маршрута;
□ routeHandler — обязательный параметр, определяет обработчик, реализующий интерфейс IRouteHandler для обработки маршрута. В MVC Framework обработчиком по умолчанию является класс MVCRouteHandler.
Коллекция маршрутов и класс RouteCollection
Для того чтобы механизм MVC Framework начал работать с маршрутом, который определяет пользователь, необходимо, чтобы маршрут попал в таблицу маршрутизации. Такая таблица основывается на классе RouteCollection, который представляет собой коллекцию маршрутов.
По существу класс RouteCollection представляет собой класс, наследующий от класса Collection<BaseRoute>. То есть RouteCollection содержит все методы по управлению коллекций элементов, такие как Add, Clear, Remove, SetItem и пр. Кроме того, из определения понятно, что RouteCollection может оперировать только элементами типа BaseRoute и его производными, которым является класс Route.
Кроме базовых методов, унаследованных от Collection, в RouteCollection определены следующие методы и свойства:
□ Add — перегруженный метод, который позволяет не просто добавить в коллекцию элемент маршрута, но добавить его и сопоставить ему наименование;
□ GetReadLock, GetWriteLock — методы, которые позволяют организовать потокобезопасные операции с коллекцией маршрутов;
□ GetRouteData — метод, который возвращает информацию о маршруте в виде экземпляра типа RouteData;
□ GetVirtualPath — метод, который возвращает объект типа VirtualPathData, который позволяет получить URL, соответствующий заданным параметрам маршрута;
□ RouteExistingFile — булево свойство, которое позволяет определить, следует ли обрабатывать запросы к локальным файлам, таким как вебстраницы, скрипты, стили или изображения в виде запросов к механизму маршрутизации, или отдавать их, минуя этот механизм.
Работа с коллекцией маршрутов в MVC Framework происходит через таблицу маршрутизации RouteTable и статическое свойство Routes, которое является экземпляром RouteCollection.
Для упрощения работы с коллекцией RouteCollection механизм MVC Framework определяет два метода расширения:
□ MapRoute — позволяет добавлять в коллекцию маршрутов новый маршрут;
□ IgnoreRoute — позволяет добавлять в коллекцию маршрутов новый маршрут, который, однако, добавляется с обработчиком маршрутов StopRoutingHandler, что означает игнорирование механизмом маршрутизации указанного маршрута.
Рассмотрим, как работают эти методы расширения. Метод MapRoute имеет несколько вариантов, далее представлено определение для метода с самым большим числом параметров:
public static Route MapRoute(
this RouteCollection routes,
string name,
string url,
object defaults,
object constraints,
string[] namespaces
)
Все варианты метода расширения MapRoute, определенные в MVC Framework, для добавления маршрута требуют указания наименования маршрута, которое задается через параметр name. Параметр url определяет шаблон маршрута, а параметры defaults и constraints — словари с набором параметров по умолчанию и ограничений. Методы расширения MapRoute не содержат возможности задавать значения для свойства DataTokens, как это делает настоящий конструктор маршрута, и на это есть причина. Поскольку MVC Framework имеет работающий по умолчанию обработчик для маршрутов в виде класса MvcRouteHandler, надобность в пользовательских параметрах, которые передаются для обработчика через DataTokens, отпадает. Однако такие параметры и DataTokens обработчик MvcRouteHandler все же использует. Через параметр namespaces метода расширения MapRoute разработчик может задать массив наименований пространств имен. Этот массив передается в DataTokens и в дальнейшем используется механизмом MVC Framework для поиска классов контроллеров только в тех пространствах имен, которые в нем определены.
Метод IgnoreRoute, в своем самом большом варианте, определен следующим образом:
public static void IgnoreRoute(
this RouteCollection routes,
string url,
object constraints
)
Параметров у метода всего два. Первый — url — определяет маршрут, который подлежит игнорировать. Второй — constraints — содержит словарь ограничений для параметров маршрута, что позволяет более гибко настраивать игнорирование маршрутов. На самом деле IgnoreRoute создает маршрут, но сопоставляет ему не стандартный для MVC Framework обработчик MvcRouteHandler, а обработчик StopRoutingHandler, определенный в механизме маршрутизации ASP.NET, который предназначен для пропуска маршрутов механизмом маршрутизации.