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 请求管道。
  • 能够在KestrelIIS 、http.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(OK)。

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

void

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

此选项提供了对响应消息的大量控制。 例如,以下控制器操作设置缓存控制标头。

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

更频繁地使用在 IHttpActionResult 命名空间中定义的 实现。 ApiController类定义返回这些内置操作结果的帮助器方法。

在以下示例中,如果请求与现有产品 ID 不匹配,则控制器将调用ApiController来创建404(未找到)响应。 否则,控制器将调用ApiController,这将创建一个包含该产品的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}]