Создание ограничений для маршрутов

Данное руководство устарело. Актуальное руководство: Руководство по ASP.NET Core

Последнее обновление: 31.10.2015

Иногда возникает необходимость, более точно задать совпадение строки запроса для данного маршрута. Например, нам надо задать, чтобы имя контроллера обязательно начиналось с буквы "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 не будет обрабатываться и сопоставляться с определенным ресурсом на сервере.

Помощь сайту
Юмани:
410011174743222
Перевод на карту
Номер карты:
4048415020898850