Get Start-如何将Controller的返回值转换成HTTP response消息

一个Web API 控制器方法可以返回以下类型的值

1.void

2.HttpResponseMessage

3.IHttpActionResult

4.其它一些类型

根据action不同的返回类型,Web API 使用不同的处理方法去创建一个http响应信息。

Action返回类型

Web API 如何生成响应消息

void

返回空 204(No Content)

HttpResponseMessage

直接转换成HTTP响应消息

IHttpActionResult

调用ExecuteAsync方法去创建一个HttpResponseMessage 对象,让后将这个对象转换成Http响应消息

其他类型

将序列化的值写到响应消息的内容中,返回200(OK)

下面对每一种返回类型做详细说明

void

如果action返回void类型,Web API返回一个空HTTP响应消息,状态码为:204(No Content)

例如:

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

执行此Action时,响应消息为:

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响应消息,使用HttpResponseMessage对象的属性值去填充响应消息。

返回HttpResponseMessage类型的方式给了我们更多的控制响应消息的能力,例如下面的控制器 action实现了设置响应消息头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

如果你传递一个model 对象(domain model)给CreateResponse方法,Web API将使用媒体格式(media formatter)序列化对象并将序列化后的内容写入到响应主体内容中。

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 API2中引入,本质上,它是一个HttpResponseMessage工厂(比如使用NotFound()可以返回404响应,Ok(products)可以返回一个 200响应并返回内容,这两个方法返回的类型均实现了IHttpActionResult接口)。

使用IHttpActionResult 接口有以下几个优势:

--简化控制器的单元测试

--将创建HTTP响应的主要逻辑分离到不同的类中

--通过隐藏创建响应消息的底层细节,使控制器动作的意图更加清晰。

IHttpActionResult 只包含一个方法,ExecuteAsync,这个方法能够异步的创建一个HttpResponseMessage对象。

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

如果一个控制器方法返回一个IHttpActionResult类型对象,Web API调用ExecuteAsync方法去创建一个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

通常,你应该将IHttpActionResult接口的实现类定义在System.Web.Http.Results命名空间下,The ApiContoller class defines helper methods that return these built-in action results.(APIController 类定义了返回(这些内建的action返回类型)帮助信息的方法。

在下面的例子中:如果找不到请求的id所对应的产品,控制器则调用APIController.NotFound 去创建一个404(Not Found)响应消息,否则控制器调用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
}

其他的返回类型

对应其他的action返回类型,Web API使用媒体格式(media formatter)序列化返回值,Web API将序列化的值写入肖响应消息的主体中,响应状态代码为200(OK)

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

上面Action返回一个列表类型,如果请求消息中没有指定 Accept头部信息(要求响应消息内容的类型),则会将列表对象序列化成json(默认)返回给浏览器。

返回其他类型的方式,一个缺点就是不能直接返回一个响应错误代码,比如404,当然,可以通过抛出一个HttpResponseException异常来返回响应错误代码,更多信息可查看(Exception Handling in ASP.NET Web API.)

Web API 使用请求消息中 Accept 头部值指定的格式来决定响应消息返回的内容格式(即内容协商方式)

比如:使用Chrome的postman插件

指定请求头部 Accept 值 为:application/xml 则返回xml类型数据。

指定请求头部 Accept 值 为:application/json 则返回json类型数据。

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。