Контроллеры ASP.NET Core Web API. Маршрутизация с использованием атрибутов HTTP-команд

Маршрутизация с использованием атрибута 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 и содержат следующие свойства:

HttpMethods Список поддерживаемых методов 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();
    }
}

В итоге, мы получим четыре маршрута:

  1. /WeatherForecast/Get
  2. /api/WeatherForecast/Get
  3. /WeatherForecast/weather
  4. /api/WeatherForecast/weather

Здесь каждый шаблон маршрута контроллера был объединен с каждым шаблоном маршрута для действия. Аналогичные правила буду действовать также и при использовании только атрибутов Route.

Итого

Помимо атрибута Route, мы также можем организовать систему маршрутизации к действиям контроллеров в приложениях ASP.NET Core Web API и с помощью атрибутов http-команд. Каждый атрибут http-команды может использовать свойство Template для указания шаблона маршрута. Действие этого свойства полностью аналогично одноименному свойству атрибута Route, а именно: шаблоны маршрутов действий не объединяются с шаблонами маршрутов контроллера, если шаблон маршрута действия начинается с символа / или ~/. Объединение маршрутов контроллера и действий осуществляется по принципу «многие-ко-многим», то есть каждый шаблон маршрута контроллера будет объединяться с каждым шаблоном маршрута действия.

Подписаться
Уведомить о
guest
0 Комментарий
Старые
Новые Популярные
Межтекстовые Отзывы
Посмотреть все комментарии