Данное руководство устарело. Актуальное руководство: Руководство по ASP.NET Core
Иногда возникает необходимость, более точно задать совпадение строки запроса для данного маршрута. Например, нам надо задать, чтобы имя контроллера обязательно начиналось с буквы "H". Тогда нам надо определить соответствующее ограничение для имени с помощью регулярных выражений:
routes.MapRoute( name: "Default", url: "{controller}/{action}/{id}", defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }, constraints: new {controller="^H.*" } );
С помощью параметра constraints
устанавливаются ограничения маршрута. И если мы направим приложению запрос Book/Index,
даже если у нас есть контроллер BookController с методом Index, то приложение вернет ошибку, так как имя контроллера попадает под ограничение,
а другого маршрута, которому бы соответствовал запрос Book/Index, у нас не задано.
Подобным образом мы можем задать ограничения и для других параметров.
Например, пусть параметр id
состоит как минимум из двух цифр:
routes.MapRoute( name: "Default", url: "{controller}/{action}/{id}/{*catchall}", defaults: new { controller = "Home", action = "Index" }, constraints: new { controller = "^H.*", id = @"\d{2}" } );
Теперь даже запрос Home/Index/1 у нас не будет сопоставляться с маршрутом, так как параметр id состоит из одной цифры, а не из двух.
Также мы можем задать ограничение по типу метода. Например, мы хотим, чтобы обрабатывались только запросы для методов с типом GET:
routes.MapRoute( name: "Default", url: "{controller}/{action}/{id}/{*catchall}", defaults: new { controller = "Home", action = "Index" }, constraints: new { controller = "^H.*", id = @"\d{2}", httpMethod=new HttpMethodConstraint("GET") } );
Теперь будут обрабатываться только те запросы, которые представляют запросы типа GET.
Чтобы создать собственное ограничение, нужно реализовать интерфейс IRouteConstraint
с одним единственным методом Match
, который имеет следующее
определение:
public interface IRouteConstraint { bool Match(HttpContextBase httpContext, Route route, string parameterName, RouteValueDictionary values, RouteDirection routeDirection); }
Ограничение маршрута применяет этот интерфейс IRouteConstraint. Это вынуждает движок маршрутизации вызвать для ограничения маршрута метод IRouteConstraint.Match, чтобы определить, применяется ли данное ограничение к данному запросу или нет. Например, создадим ограничение, которое не будет пропускать запросу по некоторому url. Итак, добавим в приложение следующий класс:
public class CustomConstraint : IRouteConstraint { private string uri; public CustomConstraint(string uri) { this.uri = uri; } public bool Match(HttpContextBase httpContext, Route route, string parameterName, RouteValueDictionary values, RouteDirection routeDirection) { return !(uri == httpContext.Request.Url.AbsolutePath); } }
Здесь мы говорим, что если запрашиваемый ресурс совпадает со значением свойства httpContext.Request.Url.AbsolutePath
,
то запрос не будет сопоставляться с маршрутом. Тогда определение маршрута может выглядеть следующим образом:
routes.MapRoute( name: "Default", url: "{controller}/{action}/{id}/{*catchall}", defaults: new { controller = "Home", action = "Index" }, constraints: new { id = @"\d{2}", myConstraint = new CustomConstraint("/Home/Index/12") } );
Теперь запрос /Home/Index/12 не будет обрабатываться, даже если он удовлетворяет всем остальным условиям и ограничениям.
По умолчанию в методе RegisterRoutes
класса RouteConfig
определена такая строка routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
.
С помощью данного выражения мы запрещаем доступ к определенному ресурсу, находящемуся на сервере. Так, мы можем переписать предыдущий пример,
где использовали ограничение для маршрута в виде запрета пути /Home/Index/12, следующим образом:
public static void RegisterRoutes(RouteCollection routes) { routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); routes.IgnoreRoute("Home/Index/12"); routes.MapRoute( name: "Default", url: "{controller}/{action}/{id}/{*catchall}", defaults: new { controller = "Home", action = "Index", id=UrlParameter.Optional } ); }
Теперь также запрос Home/Index/12 не будет обрабатываться и сопоставляться с определенным ресурсом на сервере.