Web API 2中的Action Results

2017-01-12 07:46:13来源:cnblogs.com作者:JoiT人点击

[译]Action Results in Web API 2

单击此处查看原文

也可以去我的csdn阅读

本文阐述了ASP.NET Web API是如何将controller action的返回值转换为HTTP response message的。

一个Web API controller action可以有以下几种返回值:

  1. void
  2. HttpResponseMessage
  3. IHttpActionResult
  4. Some other type(其他)

根据以上四种返回类型的不同,Web API会使用不同的机制创建HTTP response。

返回类型创建方式
void无内容
HttpResponseMessage直接转换为Http response message
IHttpActionResult调用ExecuteAsync来创建一个HttpResponseMessage,然后转换为Http response message
Other Type将序列化的返回值写入response body;返回 状态码200(OK)

本文的其余部分将阐述以上四种情况的详细内容。

void

如果返回类型是void,Web API会直接返回一个空的HTTP response,状态码:200,表示无内容。

示例controller:

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

HTTP response:

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

HttpResponseMessage

如果action返回了一个HttpResponseMessage,Web API会将该返回值转换为一个HTTP response message,使用HttpResponseMessage对象的属性来填充这个HTTP response message。

下面的示例代码中对一个response message 进行了大量的控制。比如:它设置了Cache-Control header。

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 OKCache-Control: max-age=1200Content-Length: 10Content-Type: text/plain; charset=utf-16Server: Microsoft-IIS/8.0Date: Mon, 27 Jan 2014 08:53:35 GMThello

如果你通过使用一个domain model(领域模型)来使用CreateResponse方法,Web API使用media formatter来将序列化的模型写入response body。

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 header来选择formatter。更多详情,参见Content Negotiation。

IHttpActionResult

IHttpActionResult接口在Web API 2中有过相关介绍。它主要定义了一个HttpResponseMessage factory。使用此接口有以下的几点优势:

  • 简化了你对controllers进行的unit test
  • 将创建Http responses的通用逻辑分离到独立的类中
  • 通过隐藏构建response的底层实现细节,使得controller action的功能简介明了

IHttpActionResult声明了一个方法:ExecuteAsync,用于异步创建HttpResponseMessage实例。

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

如果一个controller action返回一个IHttpActionResult,Web API 将调用ExecuteAsync方法来创建一个HttpResponseMessage。然后它再将HttpResponseMessage转换为一个HTTP response message。
以下是一个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);    }}

controller action:

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

response:

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

通常你需要将IHttpActionResult的实现写在System.Web.Http.Results命名空间下。因为ApiController定义的helper method会返回这些内置的action results。

下面的示例中,如果一个请求没有匹配到现有的product ID,这个controller将调用ApiController.NotFound来创建一个404(Not Found) response。否则,controller将调用ApiController.OK,来创建一个200(OK) response,它包含了product信息。

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

Other Return Type

如果返回类型是其他任何的一种形式,Web API使用了一个media formatter来序列化这些返回值,然后将这些序列化的值写入response body。这个response status code是200(ok)。

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

使用这种方法的缺点是,你无法直接返回一个error code,比如404。不过你可以抛出一个HttpResponseException异常来替代error code。更多详情,参见Exception Handling in ASP.NET Web API。

Web API在请求中使用Accept header来选择formatter。更多详情,参见Content Negotiation。

示例请求:

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

示例响应:

HTTP/1.1 200 OKContent-Type: application/json; charset=utf-8Server: Microsoft-IIS/8.0Date: Mon, 27 Jan 2014 08:53:35 GMTContent-Length: 56[{"Id":1,"Name":"Yo-yo","Category":"Toys","Price":6.95}]



最新文章

123

最新摄影

微信扫一扫

第七城市微信公众平台