412 000 произведений, 108 200 авторов.

Электронная библиотека книг » Гайдар Магдануров » Asp.net mvc framework » Текст книги (страница 10)
Asp.net mvc framework
  • Текст добавлен: 8 июля 2026, 17:38

Текст книги "Asp.net mvc framework"


Автор книги: Гайдар Магдануров



сообщить о нарушении

Текущая страница: 10 (всего у книги 17 страниц)

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<

                        MvcViewsDemo.Models.Product>" %>

 

    <%= Html.ActionLink("Изменить", "Edit", new { id=Model.ProductID }) %>

  

 

    <%= Html.Encode(Model.ProductID)%>

 

 

    <%= Html.Encode(Model.ProductName)%>

 

 

    <%= Html.Encode(String.Format("{0:F}", Model.UnitPrice))%>

 

 

    <%= Html.Encode(Model.UnitsInStock)%>

 

 

    <%= Html.Encode(Model.UnitsOnOrder)%>

 

Листинг 5.16. Представление Index.aspx

<%@ Page Title="" Language="C#"

         MasterPageFile="~/Views/Shared/Site.Master"

         Inherits="System.Web.Mvc.ViewPage

                      MvcViewsDemo.Models. Product»" %>

             runat="server">

  Список товаров

             runat="server">

 

    Список товаров

 

 

   

     

     

     

     

     

     

   

    <% foreach (var item in Model)

    { %>

      <% Html.RenderPartial("ProductListItem", item); %>

    <% } %>

 

     

        Код товара

        Название

     

        Цена

     

        На складе

      

        Заказано

     

Вынесение оформления элемента списка в частичное представление позволяет разгрузить код разметки самого представления, а также повторно использовать оформление элемента представления на других представлениях, если это разумно с точки зрения логики приложения.

Создание гаджетов

Частичные представления также могут быть использованы для создания гаджетов – элементов страницы, содержащих данные, не связанные с основным представлением. Гаджеты находят широкое применение на страницaх всевозможных порталов – когда есть основная страница, с которой работает пользователь, и куда выводятся дополнительные независимые информационные блоки, например, баннеры или текстовые ссылки рекламных сетей.

Разумеется, можно реализовать похожую функциональность так, как это показано в листингах 5.1—5.3, разместив частичные представления на мастерской странице. Однако часто оказывается удобным вынести функциональность гаджета в отдельное представление и полностью отделить логику гаджета от основных представлений. В поставку MVC Framewrok функциональность по созданию гаджетов не входит, однако она доступна в проекте MVC Futures. Скачать код и сборку MVC Futures (http://aspnet.codeplex.com/Release/ProjectReleases.aspx?ReleaseId=24471) можно на странице проекта MVC Framework на портале CodePlex. После подключения этой сборки к проекту функциональность по созданию гаджетов будет доступна в проекте.

Примечание

В проект MVC Futures входит код, не вошедший по каким-либо причинам в основную поставку MVC Framework. Причины могут быть разными – от недостаточной стабильности кода до желания разработчиков придумать лучшее решение в следующей версии. Однако вас не должна страшить потенциальная возможность того, что поддержка гаджетов никогда не будет включена в том виде, в котором она представлена в MVC Futures, в сам MVC Framework, поскольку вам доступен полный исходный MVC Futures, и вы можете использовать его непосредственно в ваших проектах. Более того, вы можете выделить только ту часть исходного кода, которая используется в ваших проектах, и перенести его из сборки MVC Futures Microsoft.Web.Mvc.dll в сборку вашего проекта.

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

Собственно все, что необходимо для создания гаджетов – это вспомогательный метод Html.RenderAction(), который позволяет включить на страницу вывод произвольного действия произвольного контроллера. Например, на некоторых страницах сайта нужно добавить независимый блок, выводящий информацию о текущем курсе доллара. Для этого создается частичное представление, разметка которого приведена в листинге 5.17, и контроллер, код которого приведен в листинге 5.18.

Листинг 5.17. Частичное представление ExchangeRates.ascx

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl" %>

 

   

   

 

      1 USD =

   

      <%= ViewData["USD"] %> RUB

      RUB

   

Листинг 5.18. Контроллер GadgetsController

using System.Web.Mvc;

using MvcViewsDemo.Services;

namespace MvcViewsDemo.Controllers

{

  public class GadgetsController : Controller

  {

    public ActionResult ExchangeRates()

    {

      ViewData["USD"] = ExchangeRatesService.GetRate("USD");

      return View();

    }

  }

}

Использовать гаджет ExchangeRates можно в любом представлении. Например, при использовании в представлении Index, код которого показан в листинге 5.19, получается результат, приведенный на рис. 5.4.

Листинг 5.19. Представление Index.aspx, использующее гаджет ExchangeRates

<%@ Page Language="C#" MasterPageFile="~/Views/Shared/Site.Master"

                  Inherits="System.Web.Mvc.ViewPage" %>

<%@ Import Namespace="Microsoft.Web.Mvc" %>

<%@ Import Namespace="MvcViewsDemo.Models" %>

               runat="server">

  Домашняя страница

               runat="server">

 

    <%= Html.Encode(ViewData["Message"]) %>

 

 

   

     

       

        

      

   

    <% foreach (

         Customer c in (IEnumerable)ViewData["Customers"])

    { %>

     

       

       

     

    <% } %>

 

          Название компании

        

          Контактное лицо

        

          <%= c.CompanyName %>

       

          <%= c.ContactName %>

       

  <% Html.RenderAction("ExchangeRates", "Gadgets"); %>

В листинге 5.19 отмечено, что для использования метода Html.RenderAction() необходимо подключить пространство имен Microsoft.Web.Mvc. Также из листинга 5.19 видно, что гаджету не передается никаких дополнительных данных, поскольку он полностью независим от страницы, на которой отображается.

Примечание

Для того чтобы не добавлять директиву Import в разметку представления, можно подключить пространство имен Microsoft.Web.Mvc для всех файлов проекта в разделе namespaces файла web.config.

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

Удобство использования гаджетов для независимых блоков на страницах в том, что в процессе развития проекта могут меняться контроллеры, действия и представления, используемые веб-приложением, однако код независимых блоков легко может быть перенесен на другие страницы и модифицирован, просто лишь перестановкой вызова Html.RenderAction(). Кроме того, появляется дополнительная степень свободы в модификации самих гаджетов без необходимости затрагивать код основных контроллеров и представлений. Например, код гаджета может быть доработан так, как показано в листингах 5.20, 5.21, чтобы получить результат, представленный на рис. 5.5.

Листинг 5.20. Доработанное частичное представление ExchangeRates

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl" %>

  <% foreach (var rate in (Dictionary)ViewData["rates"])

  { %>

   

     

     

    

  <% } %>

        1

        <%= rate.Key %>

     

        <%= rate.Value %> RUB

      

Листинг 5.21. Доработанный контроллер Gadgets

using System.Web.Mvc;

using MvcViewsDemo.Services;

using System. Collections.Generic;

namespace MvcViewsDemo.Controllers

{

  public class GadgetsController : Controller

  {

    public ActionResult ExchangeRates()

    {

      Dictionary rates =

        new Dictionary();

      rates.Add("USD", ExchangeRatesService.GetRate("USD"));

      rates.Add("EUR", ExchangeRatesService.GetRate("EUR"));

      ViewData["Rates"] = rates;

      return View();

    }

  }

}

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

Заключение

Материала, представленного в главах 1—5, достаточно для того, чтобы начать создавать базовые веб-приложения с использованием MVC Framework. В следующих главах вы познакомитесь ближе с механизмами маршрутизации и разработкой клиентской части веб-приложений и будете готовы к разработке веб-приложений любой сложности.

ГЛАВА 6

Механизмы маршрутизации


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

Механизм маршрутизации не является составной частью MVC Framework. Представленный в .NET Framework 3.5 SP1, этот механизм является составной частью ASP.NET и может быть использован в любом проекте ASP.NET, основанном как на WebForms, так и на MVC Framework.

И хотя маршрутизация – это не часть MVC Framework, тем не менее в проектах на базе MVC Framework она играет одну из ключевых ролей. Маршрутизация помогает перейти от запросов к файлам ASPX, к запросам на основании набора контроллеров и действий. Такой переход позволяет избавиться от зависимости от строки запроса, которая в классическом ASP.NET во многом определяла структуру приложения. Кроме того, с помощью маршрутизации проекты на базе MVC Framework изначально получают возможность формирования удобочитаемых URL, что имеет большое значение в оптимизации приложения для индексации поисковыми системами.

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

Маршрутизация в ASP.NET

Механизм маршрутизации ASP.NET был представлен в .NET Framework 3.5 SP1 и представляет собой набор классов, объединенных в пространстве имен System.Web.Routing. В состав System.Web.Routing входят следующие основные классы и интерфейсы:

□ класс UrlRoutingModule реализует интерфейс iHttpModule для обработки клиентских запросов и последующего сопоставления данных запроса одному из маршрутов, определенных в приложении;

□ RouteTable представляет собой класс, хранящий таблицу маршрутизации, т. е. все маршруты, используемые в приложении;

□ класс RouteCollection предоставляет организацию и доступ к коллекции маршрутов;

□ класс Route предназначен для определения свойств маршрута и предоставления данных о нем;

□ класс RouteData содержит данные о запрошенном через механизмы RouteCollection маршруте;

□ класс RequestContext содержит информацию о контексте пользовательского запроса, его параметрах и данных, а также информацию о выбранном маршруте. Этот класс является значительным для MVC Framework механизмом, который используется на всех этапах обработки и выполнения запроса;

□ интерфейс IRouteHandler определяет обработчик маршрутов;

□ интерфейс IRouteConstraint определяет условия, налагающие ограничения на параметры маршрута.

Кроме этих классов в пространстве имен System.Web.Routing определены еще некоторые классы и перечисления, которые играют вспомогательную или базовую роль для перечисленных классов и интерфейсов.

Рассмотрим применение классов механизма маршрутизации на примере стандартного проекта MVC Framework. В базовом шаблоне проекта MVC Framework в web.config механизмом, обрабатывающим запросы по умолчанию, назначен механизм маршрутизации, представленный классом UrlRoutingModule. Именно этот модуль определен в секциях httpModules и system.webServer как модуль, обрабатывающий HTTP-запросы.

Когда веб-приложение MVC Framework запускается в первый раз, выполняется метод Application_Start, определенный в global.asax. В проекте по умолчанию MVC Framework определяет в Application_Start инициализацию таблицы маршрутизации, представленную классом RouteTable. RouteTable содержит статическое свойство Routes, которое представляет собой экземпляр коллекции RouteCollection. Routes, с помощью вспомогательного метода RegisterRoutes заполняется маршрутами, которые определяет пользователь. Каждый такой маршрут представляет собой объект типа Route. По умолчанию в проекте MVC Framework создается всего один маршрут, рассмотрим его на следующем фрагменте кода из файла global.asax.cs:

public class MvcApplication : System.Web.HttpApplication

{

  public static void RegisterRoutes(RouteCollection routes)

  {

    routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

    routes.MapRoute(

           "Default",

           "{controller}/{action}/{id}",

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

    );

  }

  protected void Application_Start()

  {

    RegisterRoutes(RouteTable.Routes);

  }

}

Здесь для таблицы маршрутизации RouteTable.Routes выполняются два действия. Во-первых, вызывается метод IgnoreRoute, который определяет в таблице правило игнорирования маршрута для запросов, содержащих ссылки на AXD-файлы. Определяя правило игнорирования, вы исключаете запрос, который должен быть обработан другим обработчиком, из маршрутизации.

Во-вторых, вызывается метод расширения MapRoute, который регистрирует единственный маршрут в таблице маршрутизации. Для этого в данном конкретном примере он принимает три параметра: наименование маршрута, шаблон маршрута и определение значений параметров шаблона по умолчанию. Наименование маршрута, определенное как Default, может быть использовано в дальнейшем для обращения к маршруту и оперирования с ним. Более подробно разберем шаблон маршрута и параметры по умолчанию.

Шаблон маршрута, представленный строкой {controller}/{action}/{id}, описывает правило, которому будут подчинены клиентские запросы относительно веб-сайта. Правило содержит параметры шаблона: controller, action и id. Первые два из них – это стандартные параметры MVC Framework, которые позволяют задавать в шаблоне определение контроллера и действия соответственно. Параметр id – это пользовательский параметр, который будет передан действию. Например, при обращении к сайту sample.domain по следующему адресу http://sample.domain/home/index/5 механизм маршрутизации сопоставит параметру шаблона controller значение home, параметру action – значение index, параметру id – значение 5. На практике это будет означать следующее: механизм маршрутизации передаст механизму MVC Framework информацию о том, что в ответ на клиентский запрос необходимо вызвать действие Index у контроллера HomeController и передать действию 5 в виде значения параметра id.

Значения параметров шаблона маршрута по умолчанию, которые задаются в MapRoute в виде new { controller = "Home", action = "Index", id = "" }, представляют собой значения для параметров маршрута, которые будут использованы в том в случае, когда клиентский запрос их не содержит. Например, если обратиться к ресурсу со следующим запросом http://sample.domain/About/, в котором определен только первый параметр из шаблона {controller}/{action}/{id} , то механизм маршрутизации автоматически определит оставшиеся два на основании значений по умолчанию. То есть параметр controller получит значение About, а параметры action и id значения Index и пустую строку соответственно. Другими словами, на основании значений параметров по умолчанию запрос http://sample.domain/About/ будет интерпретироваться механизмом маршрутизации как запрос http://sample.domain/About/Index/. Что приведет к вызову действия Index у контроллера AboutController.

Здесь мы поверхностно рассмотрели работу механизма маршрутизации и то, как он участвует в работе с MVC Framework. В следующих разделах данной главы мы рассмотрим маршрутизацию более подробно.

Механизмы маршрутизации


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

Маршрут и класс Route

Маршрут в понятии ASP.NET – это строка, которая представляет собой шаблон URL-строки запроса к веб-приложению. Этот шаблон определяет, какие запросы попадают под понятие данного маршрута, а какие нет. Шаблоны маршрутов содержат параметры, имена которых заключены в фигурные скобки. Обычно параметры разделены обратным слэшем (/) как разделяющие сегменты URL-строки. Например, маршрут, определенный следующим образом admin/{user}/{action}, содержит два параметра: user и action. Такому маршруту могут соответствовать следующие строки URL: http://sample.domain/ admin/foo/add/ или http://sample.domain/admin/bee/edit/. Где foo и bee определяются как значения параметра user, а add и edit – параметра action.

Механизм 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. То есть 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, который предназначен для пропуска маршрутов механизмом маршрутизации.

Таблица маршрутизации и класс 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-приложения.


    Ваша оценка произведения:

Популярные книги за неделю