how ASP.NET Web API converts the return value from a controller action into an HTTP response message.
ASP.NET Web API如何将返回值从控制器操作转换为HTTP响应消息。
Web API控制器操作可以返回以下任何内容:
- void
- HttpResponseMessage
- IHttpActionResult
- 其他一些类型
根据返回的内容,Web API使用不同的机制来创建HTTP响应。
返回类型 Web API如何创建响应
void 返回空204(无内容)
HttpResponseMessage 直接转换为HTTP响应消息。
IHttpActionResult 调用ExecuteAsync以创建HttpResponseMessage,然后转换为HTTP响应消息。
其他类型 将序列化的返回值写入响应主体; 返回200(OK)。
HttpResponseMessage
如果操作返回HttpResponseMessage,则Web 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方法,则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包含一个方法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 }