Упражнение. Добавление контроллера

Завершено

Контроллер — это открытый класс с одним или несколькими открытыми методами, известными как действия. По соглашению контроллер помещается в корневом каталоге проекта в подкаталоге Controllers. Действия предоставляются как конечные точки HTTP в контроллере веб-API.

Создание контроллера

  1. Выберите папку Controllers в Visual Studio Code и добавьте в нее новый файл с именем PizzaController.cs.

    Снимок экрана Visual Studio Code, который демонстрирует добавление нового файла в папку Controllers.

    Будет создан пустой файл класса с именем PizzaController.cs в каталоге Controllers. Имя каталога Controllers — это соглашение. Имя каталога унаследовано от архитектуры "Модель — представление — контроллер", которую использует веб-API.

    Примечание.

    По соглашению в имена классов контроллера добавляется суффикс Controller.

  2. Добавьте следующий код в файл Controllers/PizzaController.cs. Сохранение изменений.

    using ContosoPizza.Models;
    using ContosoPizza.Services;
    using Microsoft.AspNetCore.Mvc;
    
    namespace ContosoPizza.Controllers;
    
    [ApiController]
    [Route("[controller]")]
    public class PizzaController : ControllerBase
    {
        public PizzaController()
        {
        }
    
        // GET all action
    
        // GET by Id action
    
        // POST action
    
        // PUT action
    
        // DELETE action
    }
    

    Как вы узнали ранее, этот класс является производным от ControllerBase, базового класса для работы с HTTP-запросами в ASP.NET Core. Он также включает в себя два стандартных атрибута, о которые вы узнали: [ApiController] и [Route]. Как и ранее, атрибут [Route] определяет сопоставление с токеном [controller]. Этот класс контроллера имеет имя PizzaController, поэтому он обрабатывает запросы на адрес https://localhost:{PORT}/pizza.

Получить все пиццы

Прежде всего мы реализуем команду REST GET, которая позволяет клиенту получить список пицц из API. Встроенный [HttpGet] атрибут можно использовать для определения метода, возвращающего пиццу из нашей службы.

Замените комментарий // GET all action в файле Controllers/PizzaController.cs на следующий код:

[HttpGet]
public ActionResult<List<Pizza>> GetAll() =>
    PizzaService.GetAll();

Предыдущее действие:

  • Это действие реагирует только на HTTP-команду GET, как указывает атрибут [HttpGet].
  • ActionResult Возвращает экземпляр типаList<Pizza>. Тип ActionResult является базовым классом для всех действий, что приводит к ASP.NET Core.
  • Запрашивает из службы полный список пицц и автоматически возвращает данные в ответе, где application/json имеет значение Content-Type.

Извлечение отдельной пиццы

Клиент может также запросить сведения о конкретной пицце вместо получения списка. Вы можете реализовать еще одно действие GET, для которого требуется параметр id. Встроенный [HttpGet("{id}")] атрибут можно использовать для определения метода, возвращающего пиццу из нашей службы. Логика маршрутизации регистрирует [HttpGet] (без id) и [HttpGet("{id}")]id) как два разных маршрута. Вы также можете написать отдельное действие для получения одного элемента.

Замените комментарий // GET by Id action в файле Controllers/PizzaController.cs на следующий код:

[HttpGet("{id}")]
public ActionResult<Pizza> Get(int id)
{
    var pizza = PizzaService.Get(id);

    if(pizza == null)
        return NotFound();

    return pizza;
}

Предыдущее действие:

  • Это действие реагирует только на HTTP-команду GET, как указывает атрибут [HttpGet].
  • Необходимо, чтобы значение параметра id включалось в сегмент URL-адреса после pizza/. Помните, что атрибут [Route] на уровне контроллера определяет шаблон /pizza.
  • Запрашивает из базы данных пиццу, которая соответствует предоставленному параметру id.

Каждый экземпляр ActionResult в предыдущих действиях сопоставляется с кодом состояния HTTP в следующей таблице.

ASP.NET Core
результат действия
Код состояния HTTP Description
Ok подразумевается 200 Продукт, соответствующий указанному параметру id, существует в кэше в памяти.
Продукт включается в текст ответа с типом мультимедиа, заданным согласно определению в заголовке accept HTTP-запроса (по умолчанию это JSON).
NotFound 404 Продукт, соответствующий указанному параметру id, не существует в кэше в памяти.

Сборка и запуск нового контроллера

Соберите и запустите веб-API, выполнив следующую команду:

dotnet run

Тестирование контроллера с помощью HTTP-файла

  1. Открытие ContosoPizza.http

  2. Добавьте новый GET для вызова конечной Pizza точки под ### разделителем:

    GET {{ContosoPizza_HostAddress}}/pizza/
    Accept: application/json
    
    ###
    
  3. Выберите команду "Отправить запрос" над этим новым вызовом GET.

    Предыдущая команда возвращает список всех пицц в ФОРМАТЕ JSON:

    HTTP/1.1 200 OK
    Connection: close
    Content-Type: application/json; charset=utf-8
    Date: Wed, 17 Jan 2024 16:57:09 GMT
    Server: Kestrel
    Transfer-Encoding: chunked
    
    [
        {
            "id": 1,
            "name": "Classic Italian",
            "isGlutenFree": false
        },
        {
            "id": 2,
            "name": "Veggie",
            "isGlutenFree": true
        }
    ]   
    
  4. Чтобы запросить одну пиццу, можно выполнить другой запрос GET и передать в нем параметр id, выполнив следующую команду:

    GET {{ContosoPizza_HostAddress}}/pizza/1
    Accept: application/json
    
    ###
    

    Предыдущая команда возвращает Classic Italian с такими выходными данными:

    HTTP/1.1 200 OK
    Content-Type: application/json; charset=utf-8
    Date: Fri, 02 Apr 2021 21:57:57 GMT
    Server: Kestrel
    Transfer-Encoding: chunked
    
    {
        "id": 1,
        "name": "Classic Italian",
        "isGlutenFree": false
    }
    
  5. Наш API также правильно обрабатывает отсутствие элемента. Снова вызовите API, передав ему недопустимый параметр пиццы id, выполнив следующую команду.

    GET {{ContosoPizza_HostAddress}}/pizza/5
    Accept: application/json
    
    ###
    

    Предыдущая команда возвращает ошибку 404 Not Found со следующими выходными данными:

    HTTP/1.1 404 Not Found
    Content-Type: application/problem+json; charset=utf-8
    Date: Fri, 02 Apr 2021 22:03:06 GMT
    Server: Kestrel
    Transfer-Encoding: chunked
    
    {
        "type": "https://tools.ietf.org/html/rfc7231#section-6.5.4",
        "title": "Not Found",
        "status": 404,
        "traceId": "00-ec263e401ec554b6a2f3e216a1d1fac5-4b40b8023d56762c-00"
    }
    

Теперь, когда вы завершили реализацию GET команд. В следующем уроке вы можете добавить дополнительные действия PizzaController для поддержки операций CRUD по данным о пиццах.

Необязательный вариант. Проверка контроллера с помощью цикла чтения http-Eval-Print (REPL)

  1. Откройте существующий терминал httprepl или откройте новый встроенный терминал из Visual Studio Code, выбрав в главном меню пункт Терминал>Новый терминал.

  2. Чтобы подключиться к веб-API, выполните следующую команду:

    httprepl https://localhost:{PORT}
    

    Также можно выполнить следующую команду в любое время, пока выполняется HttpRepl:

    connect https://localhost:{PORT}
    
  3. Чтобы открыть новую конечную точку Pizza, выполните следующую команду:

    ls
    

    Предыдущая команда обнаружит все интерфейсы API, доступные в подключенной конечной точке. Должен отобразиться следующий код:

     https://localhost:{PORT}/> ls
     .                 []
     Pizza             [GET]
     WeatherForecast   [GET]
    
  4. Перейдите к конечной точке Pizza, выполнив следующую команду:

    cd Pizza
    

    Предыдущая команда отображает выходные данные со списком доступных API для конечной точки Pizza:

    https://localhost:{PORT}/> cd Pizza
    /Pizza    [GET]
    
  5. Выполните запрос GET в HttpRepl с помощью следующей команды:

    get
    

    Предыдущая команда возвращает список всех пицц в ФОРМАТЕ JSON:

      HTTP/1.1 200 OK
      Content-Type: application/json; charset=utf-8
      Date: Fri, 02 Apr 2021 21:55:53 GMT
      Server: Kestrel
      Transfer-Encoding: chunked
    
      [
          {
              "id": 1,
              "name": "Classic Italian",
              "isGlutenFree": false
          },
          {
              "id": 2,
              "name": "Veggie",
              "isGlutenFree": true
          }
      ]
    
  6. Чтобы запросить одну пиццу, можно выполнить другой запрос GET и передать в нем параметр id, выполнив следующую команду:

    get 1
    

    Предыдущая команда возвращает Classic Italian с такими выходными данными:

    HTTP/1.1 200 OK
    Content-Type: application/json; charset=utf-8
    Date: Fri, 02 Apr 2021 21:57:57 GMT
    Server: Kestrel
    Transfer-Encoding: chunked
    
    {
        "id": 1,
        "name": "Classic Italian",
        "isGlutenFree": false
    }
    
  7. Наш API также правильно обрабатывает отсутствие элемента. Снова вызовите API, передав ему недопустимый параметр пиццы id, выполнив следующую команду.

    get 5
    

    Предыдущая команда возвращает ошибку 404 Not Found со следующими выходными данными:

    HTTP/1.1 404 Not Found
    Content-Type: application/problem+json; charset=utf-8
    Date: Fri, 02 Apr 2021 22:03:06 GMT
    Server: Kestrel
    Transfer-Encoding: chunked
    
    {
        "type": "https://tools.ietf.org/html/rfc7231#section-6.5.4",
        "title": "Not Found",
        "status": 404,
        "traceId": "00-ec263e401ec554b6a2f3e216a1d1fac5-4b40b8023d56762c-00"
    }
    
  8. Вернитесь к терминалу dotnet в раскрывающемся списке в Visual Studio Code и завершите работу веб-API с помощью комбинации клавиш CTRL+C на клавиатуре.

Теперь, когда вы завершили реализацию GET команд. В следующем уроке вы можете добавить дополнительные действия PizzaController для поддержки операций CRUD по данным о пиццах.