Результаты действий в веб-API 2

Рассмотрите возможность использования ASP.NET Core веб-API. Он имеет следующие преимущества по сравнению с веб-API ASP.NET 4.x:

  • ASP.NET Core — это кроссплатформенная платформа с открытым кодом для создания современных облачных веб-приложений в Windows, macOS и Linux.
  • Контроллеры ASP.NET Core MVC и контроллеры веб-API унифицированы.
  • Разработано для тестируемости.
  • Возможность разработки и запуска в ОС Windows, macOS и Linux.
  • Открытый исходный код и ориентация на сообщество.
  • Интеграция современных клиентских платформ и рабочих процессов разработки.
  • Облачная система конфигурации на основе среды.
  • Встроенное введение зависимостей.
  • Упрощенный, высокопроизводительный и модульный конвейер HTTP-запросов.
  • Возможность размещения в Kestrel, IIS,HTTP.sys, Nginx, Apache и Docker.
  • Управление параллельными версиями.
  • Инструментарий, упрощающий процесс современной веб-разработки.

В этом разделе описывается, как веб-API ASP.NET преобразует возвращаемое значение из действия контроллера в ответное сообщение HTTP.

Действие контроллера веб-API может возвращать любое из следующих элементов:

  1. void
  2. HttpResponseMessage
  3. IHttpActionResult
  4. Другой тип

В зависимости от того, какой из них возвращается, веб-API использует другой механизм для создания HTTP-ответа.

Возвращаемый тип Как веб-API создает ответ
void Возврат пустого 204 (без содержимого)
HttpResponseMessage Преобразуйте непосредственно в ответное сообщение HTTP.
IHttpActionResult Вызовите ExecuteAsync , чтобы создать httpResponseMessage, а затем преобразовать его в ответное сообщение HTTP.
Другой тип Запишите сериализованное возвращаемое значение в текст ответа; return 200 (OK).

В остальной части этой статьи каждый вариант описывается более подробно.

void

Если тип возвращаемого значения — void, веб-API просто возвращает пустой HTTP-ответ с кодом состояния 204 (без содержимого).

Пример контроллера:

public class ValuesController : ApiController
{
    public void Post()
    {
    }
}

HTTP-ответ:

HTTP/1.1 204 No Content
Server: Microsoft-IIS/8.0
Date: Mon, 27 Jan 2014 02:13:26 GMT

HttpResponseMessage

Если действие возвращает httpResponseMessage, веб-API преобразует возвращаемое значение непосредственно в ответное сообщение HTTP, используя свойства объекта HttpResponseMessage для заполнения ответа.

Этот параметр обеспечивает широкий контроль над ответным сообщением. Например, следующее действие контроллера задает заголовок Cache-Control.

public class ValuesController : ApiController
{
    public HttpResponseMessage Get()
    {
        HttpResponseMessage response = Request.CreateResponse(HttpStatusCode.OK, "value");
        response.Content = new StringContent("hello", Encoding.Unicode);
        response.Headers.CacheControl = new CacheControlHeaderValue()
        {
            MaxAge = TimeSpan.FromMinutes(20)
        };
        return response;
    } 
}

Ответ:

HTTP/1.1 200 OK
Cache-Control: max-age=1200
Content-Length: 10
Content-Type: text/plain; charset=utf-16
Server: Microsoft-IIS/8.0
Date: Mon, 27 Jan 2014 08:53:35 GMT

hello

Если вы передаете модель предметной области в метод CreateResponse , веб-API использует форматировщик мультимедиа для записи сериализованной модели в текст ответа.

public HttpResponseMessage Get()
{
    // Get a list of products from a database.
    IEnumerable<Product> products = GetProductsFromDB();

    // Write the list to the response body.
    HttpResponseMessage response = Request.CreateResponse(HttpStatusCode.OK, products);
    return response;
}

Веб-API использует заголовок Accept в запросе для выбора модуля форматирования. Дополнительные сведения см. в разделе Согласование содержимого.

IHttpActionResult

Интерфейс IHttpActionResult появился в веб-API 2. По сути, он определяет фабрику HttpResponseMessage . Ниже приведены некоторые преимущества использования интерфейса IHttpActionResult .

  • Упрощает модульное тестирование контроллеров.
  • Перемещает общую логику для создания HTTP-ответов в отдельные классы.
  • Делает намерение действия контроллера более понятным, скрывая низкоуровневые сведения о создании ответа.

IHttpActionResult содержит один метод ExecuteAsync, который асинхронно создает экземпляр HttpResponseMessage .

public interface IHttpActionResult
{
    Task<HttpResponseMessage> ExecuteAsync(CancellationToken cancellationToken);
}

Если действие контроллера возвращает IHttpActionResult, веб-API вызывает метод ExecuteAsync для создания HttpResponseMessage. Затем httpResponseMessage преобразуется в ответное сообщение HTTP.

Ниже приведена простая реализация IHttpActionResult , которая создает ответ в виде обычного текста:

public class TextResult : IHttpActionResult
{
    string _value;
    HttpRequestMessage _request;

    public TextResult(string value, HttpRequestMessage request)
    {
        _value = value;
        _request = request;
    }
    public Task<HttpResponseMessage> ExecuteAsync(CancellationToken cancellationToken)
    {
        var response = new HttpResponseMessage()
        {
            Content = new StringContent(_value),
            RequestMessage = _request
        };
        return Task.FromResult(response);
    }
}

Пример действия контроллера:

public class ValuesController : ApiController
{
    public IHttpActionResult Get()
    {
        return new TextResult("hello", Request);
    }
}

Ответ:

HTTP/1.1 200 OK
Content-Length: 5
Content-Type: text/plain; charset=utf-8
Server: Microsoft-IIS/8.0
Date: Mon, 27 Jan 2014 08:53:35 GMT

hello

Чаще используются реализации IHttpActionResult , определенные в пространстве имен System.Web.Http.Results . Класс ApiController определяет вспомогательные методы, возвращающие эти встроенные результаты действий.

В следующем примере, если запрос не соответствует существующему идентификатору продукта, контроллер вызывает ApiController.NotFound , чтобы создать ответ 404 (Не найдено). В противном случае контроллер вызывает ApiController.OK, который создает ответ 200 (ОК), содержащий продукт.

public IHttpActionResult Get (int id)
{
    Product product = _repository.Get (id);
    if (product == null)
    {
        return NotFound(); // Returns a NotFoundResult
    }
    return Ok(product);  // Returns an OkNegotiatedContentResult
}

Другие типы возвращаемых значений

Для всех остальных типов возвращаемых значений веб-API использует форматировщик мультимедиа для сериализации возвращаемого значения. Веб-API записывает сериализованное значение в текст ответа. Код состояния ответа — 200 (ОК).

public class ProductsController : ApiController
{
    public IEnumerable<Product> Get()
    {
        return GetAllProductsFromDB();
    }
}

Недостаток этого подхода заключается в том, что вы не можете напрямую вернуть код ошибки, например 404. Однако можно вызвать исключение HttpResponseException для кодов ошибок. Дополнительные сведения см. в разделе Обработка исключений в веб-API ASP.NET.

Веб-API использует заголовок Accept в запросе для выбора модуля форматирования. Дополнительные сведения см. в разделе Согласование содержимого.

Пример запроса

GET http://localhost/api/products HTTP/1.1
User-Agent: Fiddler
Host: localhost:24127
Accept: application/json

Пример ответа

HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
Server: Microsoft-IIS/8.0
Date: Mon, 27 Jan 2014 08:53:35 GMT
Content-Length: 56

[{"Id":1,"Name":"Yo-yo","Category":"Toys","Price":6.95}]