Web API 2 中 Action的返回值
原文更新日期:2014.02.03
导航页面
http://blog.csdn.net/wf824284257/article/details/79475115
上一步
ASP.NET Web API 2 入门教学:
http://blog.csdn.net/wf824284257/article/details/79417272
开始
这篇教程描述了 ASP.NET Web API 是怎样将controller的Action返回值转变为HTTP响应值的。
一个 Web API controller 的 action 可以返回以下任何一种类型
1.void
2.HttpResponseMessage
3.IHttpActionResult
4.一些其他的类型
Web API 会根据返回类型的不同来使用不同的机制来创建HTTP响应。
返回类型 Web API 响应
void 返回 HTTP 204(No Content)
HttpResponseMessage 直接转换为HTTP response message.
IHttpActionResult 调用ExecuteAsync来创建一个HttpResponseMessage,然后将它转换为一个HTTP response message.
其他类型 将序列化后的返回值写入响应的response body;返回HTTP 200(OK)
void
如果返回值是void,Web API 将会直接返回一个空的HTTP响应,状态码是204(No Content).
示例controller:
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
如果Action返回的是一个 HttpResponseMessage ,Web API 将会将返回值直接转化为一个HTTP response message, 并使用 HttpResponseMessage 类的属性来填充响应结果。
这种返回类型可以让你更好的控制response message。举个例子,下面的这个controller 的 action 设置了 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
如果你将一个域模型做为参数传递给 CreateResponse 方法,Web API会使用media formatter(https://docs.microsoft.com/en-us/aspnet/web-api/overview/formats-and-model-binding/media-formatters)
来将序列化后的model写入响应的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 来选择formatter。更多信息可以看
https://docs.microsoft.com/en-us/aspnet/web-api/overview/formats-and-model-binding/content-negotiation
IHttpActionResult
IHttpActionResult 接口是 Web API 2新加的。从本质上说,它定义了一个HttpResponseMessage 的工厂。使用该接口有以下好处:
- 简化controller的单元测试
- 为 创建不同的HTTP响应 添加相同的逻辑
- 通过隐藏构造响应时的低级的详细信息来使 controller action 的目的更清晰。
IHttpActionResult 仅包含了1个方法:ExecuteAsync。它能异步的创建一个 HttpResponseMessage 实例。
public interface IHttpActionResult
{
Task<HttpResponseMessage> ExecuteAsync(CancellationToken cancellationToken);
}
如果一个controller的action返回类型是IHttpActionResult, Web API 会调用ExecuteAsync 来创建一个 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);
}
}
响应为:
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 类定义了一些返回这些内置类型的方法。
在下面的例子中,如果请求中不含有一个已知的 Product ID,对应 controller 将会调用 ApiController.NotFound来创建一个HTTP404(Not Found)响应;否则,controller会调用 ApiController.OK 来返回一个HTTP200(OK),并将指定的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
}
其他返回类型
对于所有的其他的返回类型, Web API 使用 media formatter 将返回值序列化。Web API 会将序列化后的值写入响应body,响应的状态码为200(OK)。
public class ProductsController : ApiController
{
public IEnumerable<Product> Get()
{
return GetAllProductsFromDB();
}
}
这种返回值的缺点之一就是不能直接返回一个error 状态码,比如404.然而,你可以通过抛出HttpResponseException 来返回错误码.更多信息请看:https://docs.microsoft.com/en-us/aspnet/web-api/overview/error-handling/exception-handling
Web API 在请求中使用 Accept 来选择formatter。更多信息可以看
https://docs.microsoft.com/en-us/aspnet/web-api/overview/formats-and-model-binding/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}]
下一步
在WebForm项目中使用Web API:
http://blog.csdn.net/wf824284257/article/details/79449844
结束
本文为微软官方文档的个人译文。本译文的非商用转载请注明地址及作者,感谢。禁止商用转载。若经发现,将依法追究责任。
英文原文地址:https://docs.microsoft.com/en-us/aspnet/web-api/overview/getting-started-with-aspnet-web-api/action-results
原文作者: MikeWasson and Other 5 Contributors
主作者链接:https://github.com/MikeWasson
作者尊重微软公司的知识产权,若贵公司认为该博客有损贵公司利益,请联系作者删除
译者:大吴凡 http://www.dawufan.cn/