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

Таблица маршрутизации и класс RouteTable

Как уже сообщалось, одним из основных классов механизма маршрутизации является класс RouteTable. Вместе с этим RouteTable — один из самых простых классов, он содержит только одно свойство Routes. Это статическое свойство, которое содержит коллекцию маршрутов в виде экземпляра класса RouteCollection.

Для работы MVC Framework необходимо, чтобы свойство Routes содержало хотя бы один маршрут. RouteTable можно считать контейнером для маршрутов всего приложения. Так как коллекция маршрутов типа RouteCollection определена в нем в виде статического свойства Routes, доступ ко всем маршрутам будет иметь любая часть приложения.

Ограничения и интерфейс IRouteConstraint

Интерфейс IRouteConstraint предназначен для определения объекта ограничения, который, основываясь на некоторой логике, определяет, подходит или нет значение параметра URL маршруту, которому присваивается это ограничение. Проще говоря, IRouteConstraint позволяет определить объект и сопоставить его имени параметра маршрута. Задачей этого объекта является проверка значений параметра на соответствие неким условиям. MVC Framework при сопоставлении URL запроса маршруту последовательно вызывает все зарегистрированные объекты, реализующие IRouteConstraint, и таким образом проверяет, подходит ли данный набор параметров URL рассматриваемому маршруту.

Интерфейс IRouteConstraint задает всего один метод Match, который имеет следующее определение:

bool Match(

  HttpContextBase httpContext,

  Route route, string parameterName,

  RouteValueDictionary values,

  RouteDirection routeDirection

)

Метод Match должен содержать логику проверки параметра строки URL запроса на соответствие некоторым условиям. Match должен вернуть true в случае, когда значение параметра соответствует условиям, и false в обратном случае. При вызове методу Match передаются следующие параметры:

□ httpContext — контекст запроса в виде экземпляра класса HttpContextBase;

□ route — маршрут, к которому применяется данное ограничение;

□ parameterName — имя параметра, значение которого следует проверить на условия ограничения;

□ values — коллекция значений параметров запроса;

□ routeDirection — параметр, определяющий текущее поведение механизма маршрутизации: обработку клиентского запроса или создание строки URL на базе маршрутов.

Основываясь на перечисленных параметрах, метод Match должен определить, подходит ли значение параметра из строки URL для параметра маршрута.

Рассмотрим работу интерфейса на примере:

public class SampleConstraint : IRouteConstraint

{

  public bool Match(HttpContextBase httpContext,

       Route route,

       string parameterName,

       RouteValueDictionary values,

       RouteDirection routeDirection)

  {

    bool result = false;

    if (parameterName == "user")

    {

      if (values["user"].ToString().Length >= 4) result = true;

    }

    return result;

  }

}

Данный класс SampleConstraint реализует интерфейс IRouteConstraint и определяет метод Match. В этом методе происходит проверка значения параметра под именем user. Если длина значения параметра менее 4 символов, то возвращается false, который указывает, что параметр не прошел проверку, в ином случае возвращается true, что говорит о прохождении параметров проверки на условия. Образно говоря, этот класс проверяет длину строки имени пользователя, которая была передана в строке URL запроса.

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

routes.MapRoute("Default",

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

    new {controller = "Home", action = "Index", id = ""},

    new {user = new SampleConstraint() }

);

По этому определению маршрута будет следовать, что запрос со строкой URL http://sample.domain/Home/Index/user1 обработается, а запрос http://sample.domain/Home/Index/foo будет отклонен на этапе работы ограничения SampleConstraint, т. к. значение foo, определяющее параметр маршрута user, содержит менее 4 символов.

Обработчик маршрутов и интерфейс IRouteHandler

Интерфейс IRouteHandler предназначен для определения обработчика маршрута. Такой обработчик нужен для того, чтобы обработать запрос после определения маршрута. Иными словами, после клиентского запроса и определения подходящего для него маршрута механизм маршрутизации создает сопоставленный найденному маршруту обработчик и вызывает его. Обработчик должен содержать некую логику, которая исполняется в ответ на клиентский запрос. Для MVC Framework такая логика реализуется с помощью двух классов: MvcRouteHandler и MvcHandler.

Задача класса, реализующего iRouteHandler, состоит в том, чтобы вернуть подходящий экземпляр класса HTTP-обработчика, реализующего iHttpHandler. Для этого интерфейс IRouteHandler определяет всего один метод GetHttpHandler:

IHttpHandler GetHttpHandler(RequestContext requestContext)

Любой класс, реализующий IRouteHandler, должен реализовать метод GetHttpHandler, который должен возвращать инстанцированный объект HTTP-обработчика. В механизме MVC Framework за это отвечает класс MvcRouteHandler, который через GetHttpHandler возвращает экземпляр другого класса MvcHandler. Класс MvcRouteHandler сопоставляется через метод расширения MapRoute всем маршрутам по умолчанию, поэтому разработчику нет нужды напрямую его использовать.

Таким образом, механизм MVC Framework уже содержит предопределенные элементы в виде реализации интерфейса IRouteHandler и HTTP-обработчика, и в общем случае разработчик использует их. Но вы можете определить свой вариант IRouteHandler, который будет возвращать ваш собственный HTTP-обработчик, отличающийся от MvcHandler. Так вы сможете переопределить поведение механизма MVC Framework на этапе связывания маршрута и объектов модели MVC-приложения.

Создание маршрутов

В предыдущей части этой главы мы уже рассмотрели простой пример создания маршрута и класс Route, который используется для этих целей. При создании маршрута с помощью класса Route важную роль играют параметры имени маршрута, Url и три словаря параметров, определенные свойствами Defaults, Constraints и DataTokens. Рассмотрим их назначение и применение более подробно.

Наименование маршрута

В MVC Framework добавление маршрута реализуется путем вызова одного из вариантов MapRoute, методов расширения RouteCollection. Одним из отличиев MapRoute является требование к обязательному указанию имени маршрута, тогда как стандартные средства RouteCollection позволяют добавить маршрут без указания имени.

 Примечание

Следует учесть, что имена для маршрутов должны быть уникальными. При попытке добавить в таблицу маршрутизации маршрут с именем, которое уже существует в таблице, будет вызвано исключение.

********************************

Имя маршрута — это достаточно важная часть маршрутизации в MVC Framework. Есть несколько полезных вариантов использования имени маршрута, рассмотрим их по порядку.

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