ASP.NET Core Web API. Контроллеры

Любой проект ASP.NET Core Web API на основе контроллеров состоит из одного или нескольких классов — контроллеров, выполняющих определенные действия. Контроллер — это тот компонент, который обеспечивает взаимосвязь между пользователем и приложением. Он обрабатывает входящие запросы и, либо, сразу генерирует данные для ответа, либо использует модель для манипуляции с данными и, затем, генерирует данные для ответа. В проектах ASP.NET Core Web API используются соглашения, в соответствии с которыми, обычные классы C# могут считаться контроллерами.

Что является контроллером в ASP.NET Core Web API?

С точки зрения ASP.NET Core, контроллер – это класс C#, соответствующий одному или нескольким соглашениям, который выполняет определенные действия, то есть, в терминах C# – содержит методы, которые обрабатывают запросы пользователей.

Действие контроллера — это метод, определенный в классе контроллера и содержащий специальный атрибут, указывающий какие запросы поддерживает действие. Например, в шаблонном приложении ASP.NET Core Web API создается контроллер:

[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]
    public IEnumerable<WeatherForecast> Get()
    {
        _logger.LogError("Сообщение из WeatherForecastController с уровнем Error");
        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();
    }
}

По соглашению, в проектах ASP.NET Core Web API контроллерами являются классы, обладающие одним или несколькими признаками:

  1. Класс содержит в названии суффикс Controller
  2. Для класса определен атрибут [ApiController]
  3. Класс унаследован от класса ControllerBase или, реже, от Controller

Например, посмотрим на объявление контроллера, представленного выше

[ApiController]
[Route("[controller]")]
public class WeatherForecastController : ControllerBase

здесь присутствуют все три признака — суффикс Controller, атрибут [ApiController], а сам класс — наследник ControllerBase. У этого контроллера определено одно действие:

[HttpGet]
public IEnumerable<WeatherForecast> Get()
{
    //код действия
}

Так как у метода Get() определен специальный атрибут [HttpGet], то этот метод считается действие контроллера, которое обрабатывает входящие GET-запросы. Теперь рассмотрим какие возможности и приемущества дают те или иные признаки контроллера.

Атрибут [ApiController]

Атрибут [ApiController] включает сразу несколько специализированных схем поведения API, а именно:

  • Обязательная маршрутизация на основе атрибутов
  • Автоматические отклики HTTP 400
  • Вывод параметров источника привязки
  • Сведения о проблемах для кодов состояния ошибки

Кратко разберемся с этими схемами, а далее — рассмотрим некоторые из них более подробно в следующих частях этого руководства.

Обязательная маршрутизация на основе атрибутов

В общем случае, маршрутизация в ASP.NET Core — это механизм сопоставления входящих HTTP-запросов с конкретными обработчиками (конечными точками, endpoints) в приложении. Применительно к ASP.NET Core Web API, маршрутизация — это механизм сопоставления входящего HTTP-запроса с действием контроллера.

В ASP.NET Core могут использоваться различные механизмы маршрутизации — у ASP.NET Core MVC может быть свой механизм маршрутизации, у Minimal API — свой, мы можем комбинировать эти механизмы, если это потребуется, однако, если мы определяем в нашем приложении контроллер с атрибутом [ApiController], то мы обязаны использовать механизм маршрутизации к действиям контроллера только с использованием атрибутов. Что это означает? Это означает, что для контроллера в целом или для отдельных его действий должны определяться специальные атрибуты, в которых мы должны указывать путь к действию. Например, вернемся к стандартному контроллеру:

[ApiController]
[Route("[controller]")]
public class WeatherForecastController : ControllerBase

здесь мы видим атрибут

[Route("[controller]")]

в котором используется специальный маркер [controller], который указывает на то, что вместо этого маркера в URL должно подставляться имя контроллера без суффикса. Обратите внимание на то, как выглядит запрос в http-файле проекта:

GET {{WebApplication3_HostAddress}}/weatherforecast/
Accept: application/json

Атрибут Route — это один из атрибутов маршрутизации. С другими атрибутами мы обязательно познакомимся более детально в следующих частях.

Автоматические отклики HTTP 400

Еще одна схема, которая включается при использовании атрибута [ApiController]. Включение этой схемы означает, что в случае, если запрос пользователя будет составлен некорректно, то ASP.NET Core самостоятельно сгенерирует ответ (по умолчанию в формате JSON) с кодом HTTP 400 и описанием возникшей проблемы и этот ответ будет соответствовать спецификации RFC 7807. Об этом отклике мы также обязательно поговорим, когда будем разбираться с моделями в ASP.NET Core Web API.

Вывод параметров источника привязки

Большинство API не только отдает ответ пользователю, но и может принимать от него какие-либо данные, например, данные для создания учетных записей, параметры фильтрации и поиска данных и так далее. Все эти данные в ASP.NET Core могут передаваться различными способами — через параметры запроса, в теле запроса и так далее, которые называются источниками привязки. Использование атрибута [ApiController] применяет специальные правила привязки к источникам, позволяя избежать лишней рутинной работы и, при необходимости, изменять приоритет тех или иных источников привязки, используя специальные атрибуты.

Сведения о проблемах для кодов состояния ошибки

Если в результате выполнения запроса к API происходит ошибка, то при использовании атрибута [ApiController], ASP.NET Core сгенерирует ответ, соответствующий спецификации RFC 7807. Этот пример можно продемонстрировать уже сейчас, не вдаваясь особо в подробности его реализации. Измените код действия Get() в контроллере WeatherForecastController шаблонного приложения ASP.NET Core следующим образом:

public ActionResult<IEnumerable<WeatherForecast>> Get()
{
    return NotFound();
    _logger.LogError("Сообщение из WeatherForecastController с уровнем Error");
    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();
}

Естественно, что код находящийся после return не будет выполняться, но нам это и не нужно. Здесь мы просто возвращаем пользователю на его запрос ответ с кодом 404 Not Found. Без использования атрибута [ApiController] мы бы увидели следующий ответ сервера:

Если же мы применяем атрибут, то ответ сервера будет таким:

Как было сказано ранее, со всеми этими схемами поведения мы разберемся детально в следующих частях руководства. А пока, перейдем к следующему признаку контроллера.

Классы ControllerBase и Controller

Класс ControllerBase предоставляет методы и свойства для обработки HTTP-запросов, например, такие методы, как NotFound() для возврата пользователю кода состояния 404 или Ok() и т.д. Например, мы можем определить следующий контроллер:

[Route("[controller]")]
public class First: ControllerBase
{
    [HttpGet]
    public OkResult SayOk()
    {
        return Ok(); //метод ControllerBase.Ok()
    }

    [HttpDelete]
    public BadRequestResult SayBadRequest() 
    {
        return BadRequest();//метод ControllerBase.BadRequest()
    }
}

Наиболее часто, именно этот класс является базовым для контроллеров в проектах Web API.

Что касается класса Controller, то этот класс является наследником ControllerBase и добавляет функциональность работы с представлениями. Поэтому, класс Controller оправдано использовать только в том случае, если подразумевается, что ваш проект будет предоставлять и какой-либо визуальный интерфейс пользователям, например, с использованием MVC и, одновременно с этим, давать пользователям доступ к API вашего проекта.

Итого

Контроллером в проектах ASP.NET Core Web API считается класс, который содержит один или несколько признаков: содержит в названии суффикс Controller, для класса определен атрибут [ApiController], наследуется от класса ControllerBase или, реже, от Controller. Атрибут [ApiController] включает несколько специальных схем поведения, облегчающих нашу работу по созданию контроллеров API и обработке ошибок запросов.

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