Атрибуты маршрутизации

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

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

Одним из нововведений MVC 5 стала такая функциональность как атрибуты маршрутизации (attribute routing). Данные атрибуты позволяют сопоставить определенный маршрут с методом контроллера. Например, у нас есть такой метод в контроллере HomeController:

public string Test(int id, string name)
{
    return id.ToString() + ". " + name;
}

Ему мог бы соответствовать следующий маршрут, определенный в файле RouteConfig.cs:

public class RouteConfig
{
    public static void RegisterRoutes(RouteCollection routes)
    {
        routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

        routes.MapRoute(
            name: "Default2",
            url: "{id}/{name}",
            defaults: new { controller = "Home", action = "Test"},
            constraints: new { id="\d+"}
        );

        routes.MapRoute(
            name: "Default",
            url: "{controller}/{action}/{id}",
            defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
        );
    }
}

Параметр constraints: new { id="\d+"} ограничивает первый сегмент строки запроса числами, таким образом, у нас не будет конфликта между двумя маршрутами. То есть запрос вида http://localhost:6392/2/volga будет сопоставляться с первым маршрутом, а если вместо числа 2 будет идти строка - то со вторым.

Но атрибуты маршрутизации позволяют не определять дополнительный маршрут, а указать сопоставление прямо в коде контроллера:

[Route("{id:int}/{name}")]
public string Test(int id, string name)
{
    return id.ToString() + ". " + name;
}

Кроме того, нам надо изменить код в файле RouteConfig.cs следующим образом:

public class RouteConfig
{
    public static void RegisterRoutes(RouteCollection routes)
    {
        routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

        routes.MapMvcAttributeRoutes();

        routes.MapRoute(
            name: "Default",
            url: "{controller}/{action}/{id}",
            defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
        );
    }
}

Здесь вместо определения маршрута мы используем метод routes.MapMvcAttributeRoutes();, который подключает в систему маршрутизации приложения функциональность атрибутов маршрутизации.

Мы также можем явно указать имя контроллера или метода или параметра в атрибуте: [Route("Home/{id:int}/{name}")]. Данный маршрут будет соответствовать запросу Home/4/somename

Ограничения маршрутов

В определении сегмента id мы использовали ограничение, чтобы явно указать, что этот сегмент должен представлять целое число: id:int. Кроме int мы можем задать еще ряд ограничений по типу:

  • alpha: соответствует только алфавитным символам латинского алфавита. Например, {id:alpha}

  • bool: соответствует логическлму значению. Например, {id:bool}

  • datetime: соответствует значению DateTime. Например, {id:datetime}

  • decimal: соответствует значению decimal. Например, {id:decimal}

  • double: соответствует значению double. Например, {id:double}

  • float: соответствует значению float. Например, {id:float}

  • length: соответствует строке определенной длины, либо ее длина должна быть в определенном диапазоне. Например, {id:length(5)} или {id:length(5, 15)}

  • long: соответствует значению long. Например, {id:long}

  • max: соответствует значению int, которое не больше значения max. Например, {id:max(99)}. Аналогичным образом действует ограничение min, только оно указывает на минимально допустимое значение сегмента.

  • maxlength: соответствует строке, длина которой не больше определенного значения. Например, {id:maxlength(20)}. Аналогичным образом работает ограничение minlength, указывая на минимально допустимую длину строки

  • range: указывает на диапазон, в пределах которого должно находиться значение сегмента. Например, {id:range(5, 20)}

  • regex: соответствует регулярному выражению. Например, {id:regex(^\d{3}-\d{3}-\d{4}$)}

Значения по умолчанию

Как и при определении маршрута, мы можем задать значения для параметров по умолчанию:

[Route("{id:int}/{name=volga}")]
public string Test(int id, string name)
{
    return id.ToString() + ". " + name;
}

Так, если строка запроса не будет содержать последний параметр, то вместо него будет использоваться строка "volga".

Использование префиксов

Выше приводился пример атрибута маршрутизации с название контроллера в начале: [Route("Home/{id:int}/{name}")]. Но если у нас вдруг есть несколько подобных действий, обращение к которым должно начинаться с "Home", то удобно использовать префиксы:

[RoutePrefix("home")]
public class HomeController : Controller
{
    [Route("{id:int}/{name}")]
    public string Test(int id, string name)
    {
        return id.ToString() + ". " + name;
    }
	[Route("{id:int}")]
    public string Sead(int id)
    {
        return id.ToString();
    }
	[Route("~/lol/twit/{id:int}")]
    public string Twit(int id)
    {
        return id.ToString();
    }
}

Теперь запрос к обоим методам должен начинаться с Home: "Home/5/fds" или "Home/5". При этом префикс не обязательно должен совпадать с именем контроллера, а может иметь любое значение.

Последний маршрут устраняет действие префикса с помощью знака тильды (~) в начале маршрута. И чтобы к этому методу обратиться, надо будет использовать запрос http://localhost:6392/lol/twit/2.

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