Web API 2 的操作结果

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

  • ASP.NET Core 是一个开源的跨平台框架,用于在 Windows、macOS 和 Linux 上构建基于云的新式 Web 应用。
  • ASP.NET 核心 MVC 控制器和 Web API 控制器是统一的。
  • 针对可测试性进行构建。
  • 能够在 Windows、macOS 和 Linux 上进行开发和运行。
  • 开放源代码和以社区为中心。
  • 集成新式客户端框架和开发工作流。
  • 基于环境的云就绪配置系统。
  • 内置依赖项注入。
  • 轻型的高性能模块化 HTTP 请求管道。
  • 能够在 Kestrel、IISHTTP.sys、NginxApacheDocker 上托管。
  • 并行版本控制。
  • 简化新式 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

Web API 2 中引入了 IHttpActionResult 接口。 本质上,它定义 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}]