Маршрутизация с использованием атрибута Route
, которую мы рассмотрели в предыдущей части используется в проектах ASP.NET Core Web API наиболее часто, так как многократное применение этого атрибута к цели (классу или методу) позволяет создавать гибкую систему маршрутизации. Однако, при необходимости, мы можем настраивать маршрутизацию в контроллере также и с помощью атрибутов HTTP-команд.
Атрибуты HTTP-команд
Атрибуты HTTP-команд определяют какие команды HTTP будут обрабатываться тем или иным действие контроллера. На данный момент, в ASP.NET Core Web API определены следующие атрибуты HTTP-команд:
Атрибут | Описание |
[HttpGet] |
Действие контроллера обрабатывает GET-запросы |
[HttpPost] |
Действие контроллера обрабатывает POST-запросы |
[HttpPut] |
Действие контроллера обрабатывает PUT-запросы |
[HttpDelete] |
Действие контроллера обрабатывает DELETE-запросы |
[HttpHead] |
Действие контроллера обрабатывает HEAD-запросы |
[HttpPatch] |
Действие контроллера обрабатывает PATCH-запросы |
[HttpOptions] |
Действие контроллера обрабатывает OPTIONS-запросы |
Все классы этих атрибутов имеют схожее описание, являются наследниками класса HttpMethodAttribute
и содержат следующие свойства:
Http |
Список поддерживаемых методов HTTP. Например, для HttpGet — это будет только GET, для HttpPost — POST и т.д. |
Name |
Имя маршрута. |
Order |
Порядок маршрута. Сначала выполняются маршруты с более низким порядком. |
Template |
Шаблон маршрута. Может иметь значение null . |
В данном случае, для нас наиболее важным свойством является свойство Template
с помощью которого мы можем задавать шаблон маршрута для действия контроллера. Рассмотрим несколько примеров использования атрибутов HTTP-команд для настройки системы маршрутизации в приложениях ASP.NET Core Web API.
Маршрутизация с использованием атрибутов HTTP-команд
Для рассмотрения примеров, воспользуемся шаблоном приложения ASP.NET Core Web API с использованием контроллеров. Изменим контроллер WeatherForecastController
следующим образом:
[ApiController] [Route("[controller]")] public class WeatherForecastController : ControllerBase { private static readonly string[] Summaries = new[] { "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching" }; private readonly ILogger<WeatherForecastController> _logger; public WeatherForecastController(ILogger<WeatherForecastController> logger) { _logger = logger; } [HttpGet("/weather")] //шаблон маршрута public IEnumerable<WeatherForecast> Get() { return Enumerable.Range(1, 5).Select(index => new WeatherForecast { Date = DateOnly.FromDateTime(DateTime.Now.AddDays(index)), TemperatureC = Random.Shared.Next(-20, 55), Summary = Summaries[Random.Shared.Next(Summaries.Length)] }) .ToArray(); } }
здесь мы указали у действия контроллера Get()
атрибут HttpGet
в параметрах которого определили шаблон маршрута /weather
. Также, у класса контроллера определен уже известный нам атрибут Route
. Теперь метод API будет нам доступен по пути /weather
. Всё в соответствии с тем, как ASP.NET Core выводит параметры маршрутов.
Также, как и при использовании атрибута Route
, мы можем использовать зарезервированные имена в шаблонах маршрутов, а также применять атрибуты http-команд многократно к одному и тому же действию контроллера, например,
[HttpGet("[action]")] //шаблон будет объединен с шаблоном маршрута для контроллера [HttpGet("/")] //шаблон НЕ будет объединен с шаблоном маршрута для контроллера public IEnumerable<WeatherForecast> Get() { return Enumerable.Range(1, 5).Select(index => new WeatherForecast { Date = DateOnly.FromDateTime(DateTime.Now.AddDays(index)), TemperatureC = Random.Shared.Next(-20, 55), Summary = Summaries[Random.Shared.Next(Summaries.Length)] }) .ToArray(); }
В первом атрибуте мы использовали зарезервированное имя action
вместо которого в маршрут подставляется имя действия контроллера. Также, следует отметить ещё один момент, касающийся настройки системы маршрутизации с использованием атрибутов:
Изменим наш пример следующим образом:
[ApiController] [Route("[controller]")] //первый шаблон маршрута [Route("api/[controller]")] //второй шаблон маршрута public class WeatherForecastController : ControllerBase { private static readonly string[] Summaries = new[] { "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching" }; private readonly ILogger<WeatherForecastController> _logger; public WeatherForecastController(ILogger<WeatherForecastController> logger) { _logger = logger; } [HttpGet("[action]")] //первый шаблон действия [HttpGet("weather")] //второй шаблон действия public IEnumerable<WeatherForecast> Get() { return Enumerable.Range(1, 5).Select(index => new WeatherForecast { Date = DateOnly.FromDateTime(DateTime.Now.AddDays(index)), TemperatureC = Random.Shared.Next(-20, 55), Summary = Summaries[Random.Shared.Next(Summaries.Length)] }) .ToArray(); } }
В итоге, мы получим четыре маршрута:
- /WeatherForecast/Get
- /api/WeatherForecast/Get
- /WeatherForecast/weather
- /api/WeatherForecast/weather
Здесь каждый шаблон маршрута контроллера был объединен с каждым шаблоном маршрута для действия. Аналогичные правила буду действовать также и при использовании только атрибутов Route
.
Итого
Помимо атрибута Route
, мы также можем организовать систему маршрутизации к действиям контроллеров в приложениях ASP.NET Core Web API и с помощью атрибутов http-команд. Каждый атрибут http-команды может использовать свойство Template для указания шаблона маршрута. Действие этого свойства полностью аналогично одноименному свойству атрибута Route, а именно: шаблоны маршрутов действий не объединяются с шаблонами маршрутов контроллера, если шаблон маршрута действия начинается с символа /
или ~/
. Объединение маршрутов контроллера и действий осуществляется по принципу «многие-ко-многим», то есть каждый шаблон маршрута контроллера будет объединяться с каждым шаблоном маршрута действия.