Web API 2 的操作结果

请考虑使用 ASP.NET Core Web API。 与 ASP.NET 4.x Web API 的比,它具有以下优势:

  • ASP.NET Core是一个开源的跨平台框架,用于在 Windows、macOS 和 Linux 上构建基于云的新式 Web 应用。
  • ASP.NET Core MVC 控制器和 Web API 控制器是统一的。
  • 针对可测试性进行构建。
  • 能够在 Windows、macOS 和 Linux 上进行开发和运行。
  • 开源和关注社区。
  • 新式客户端框架和开发工作流的集成。
  • 一个云就绪、基于环境的配置系统。
  • 内置依赖项注入。
  • 轻型高性能模块化 HTTP 请求管道。
  • 能够在 KestrelIISHTTP.sysNginxApacheDocker 上托管。
  • 并行版本。
  • 简化新式 Web 开发的工具。

本主题介绍 ASP.NET Web API如何将返回值从控制器操作转换为 HTTP 响应消息。

Web API 控制器操作可以返回以下任一项:

  1. void
  2. HttpResponseMessage
  3. IHttpActionResult
  4. 其他一些类型

根据返回的响应,Web API 使用不同的机制来创建 HTTP 响应。

返回类型 Web API 如何创建响应
void 返回空的 204 (无内容)
HttpResponseMessage 直接转换为 HTTP 响应消息。
IHttpActionResult 调用 ExecuteAsync 以创建 HttpResponseMessage,然后转换为 HTTP 响应消息。
其他类型 将序列化的返回值写入响应正文;返回 200 (正常) 。

本主题的其余部分更详细地介绍了每个选项。

void

如果返回类型为 void,Web API 仅返回状态代码为 204 的空 HTTP 响应 (无内容) 。

示例控制器:

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,Web API 将使用 HttpResponseMessage 对象的属性来填充响应,将返回值直接转换为 HTTP 响应消息。

此选项可让你对响应消息进行大量控制。 例如,以下控制器操作设置 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 方法,Web 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;
}

Web API 使用请求中的 Accept 标头来选择格式化程序。 有关详细信息,请参阅 内容协商

IHttpActionResult

IHttpActionResult 接口是在 Web API 2 中引入的。 本质上,它定义了 一个 HttpResponseMessage 工厂。 下面是使用 IHttpActionResult 接口的一些优点:

  • 简化了控制器 的单元测试
  • 将用于创建 HTTP 响应的常见逻辑移动到单独的类中。
  • 通过隐藏构造响应的低级别详细信息,使控制器操作的意图更加清晰。

IHttpActionResult 包含一个 ExecuteAsync 方法,该方法异步创建 HttpResponseMessage 实例。

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

如果控制器操作返回 IHttpActionResult,Web 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

更常见的情况是使用 System.Web.Http.Results 命名空间中定义的 IHttpActionResult 实现。 ApiController 类定义返回这些内置操作结果的帮助程序方法。

在以下示例中,如果请求与现有产品 ID 不匹配,则控制器调用 ApiController.NotFound 以创建 404 (“找不到”) 响应。 否则,控制器会调用 ApiController.OK,这将创建包含产品的 200 (OK) 响应。

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

其他返回类型

对于所有其他返回类型,Web API 使用 媒体格式化程序 来序列化返回值。 Web API 将序列化的值写入响应正文。 响应状态代码为 200 (正常) 。

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

此方法的缺点是无法直接返回错误代码,例如 404。 但是,对于错误代码,可以引发 HttpResponseException 。 有关详细信息,请参阅 ASP.NET Web API 中的异常处理

Web 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}]