在这篇文章中
作者:Mike Wasson
本主题描述ASP.NET Web API如何将控制器操作的返回值转换为HTTP响应消息。
Web API控制器操作可以返回以下任何内容:
- 空虚
- HttpResponseMessage
- IHttpActionResult
- 一些其他类型
取决于返回哪些,Web API使用不同的机制来创建HTTP响应。
返回类型 | Web API如何创建响应 |
---|---|
空虚 | 返回空204(无内容) |
HttpResponseMessage | 直接转换为HTTP响应消息。 |
IHttpActionResult | 调用ExecuteAsync创建一个HttpResponseMessage,然后转换为HTTP响应消息。 |
其他类型 | 将序列化返回值写入响应体; 返回200(OK)。 |
本主题的其余部分更详细地描述每个选项。
空虚
如果返回类型是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对象的属性来填充响应。
此选项可让您对响应消息进行很多控制。例如,以下控制器操作设置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界面中的Web API 2,从本质上讲,它定义了一个介绍HttpResponseMessage工厂。以下是使用IHttpActionResult接口的一些优点:1
- 简化对控制器的单元测试。
- 将用于将HTTP响应创建为单独类的常用逻辑。
- 通过隐藏构建响应的低级细节,使控制器动作的意图更清晰。
IHttpActionResult包含一个单独的方法ExecuteAsync,它异步创建一个HttpResponseMessage实例。
public interface IHttpActionResult
{
Task<HttpResponseMessage> ExecuteAsync(CancellationToken cancellationToken);
}
如果控制器操作返回IHttpActionResult,Web API将调用ExecuteAsync方法来创建HttpResponseMessage。然后将HttpResponseMessage转换为HTTP响应消息。2
这是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类定义辅助方法返回这些内置的动作效果。1
在以下示例中,如果请求与现有产品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
}
其他返回类型
对于所有其他返回类型,Web API使用媒体格式化程序来序列化返回值。Web API将序列化值写入响应体。响应状态码为200(OK)。
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}]