Web API 2中的Action Result
2017-01-11 21:32
344 查看
[译]Action Results in Web API 2
单击此处查看原文
本文阐述了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 Content Server: Microsoft-IIS/8.0 Date: 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 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
如果你通过使用一个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 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的实现写在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.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}]
相关文章推荐
- ASP.NET Web API 配置返回的json字段的格式以及Action返回HttpResponseMessage类型和IHttpActionResult类型
- HTTP Status 404 - No result defined for action
- Strut2中的Action Result类型解析
- struts2注解总结----@Action和@Result
- struts2 跳转类型 result type=chain、dispatcher、redirect(redirect-action)
- MVC之ActionResult
- 了解ASP.NET MVC几种ActionResult的本质:FileResult
- 【Struts2学习笔记(2)】Action默认值和配置Action于result各种转发类型
- struts2 action result 的配置
- No result defined for action and result input
- No result defined for action and result的解决方案
- Play framework Action、Controller和Result
- No result defined for action ....Action and result input
- No result defined for action
- SSH 报错信息No result defined for action
- Struts2报错:No result defined for action xxx and result input
- No result defined for action com.weiyi.bbs.action.LoginAction and result success总结
- HTTP Status 404 - No result defined for action EmployeeAction and result input - action类似异常解决及原因剖析
- struts2 跳转类型、 result type=chain、dispatcher、redirect(redirect-action)
- 关于struts错误:No result defined for action