WebApi2中action几种返回值

来源:互联网 发布:android数独游戏源码 编辑:程序博客网 时间:2024/05/29 03:36

本文是本人翻译自官方资料,如果翻译的不好请指正。


本文介绍WebApi2如何将action中的结果返回至Http输出中。

 

一个WebApi Controller可以返回以下任意一种类型:

   1.void

   2.HttpReponseMessage

   3.IHttpActionResult

   4.其他类型

 

依据不同返回类型,WebApi会选择不同的机制来创建Http Reponse

Return type

How Web API creates the response

void

Return empty 204 (No Content) 

返回无内容

HttpResponseMessage

Convert directly to an HTTP response message.

直接转换为一个Http Reponse消息。

IHttpActionResult

Call ExecuteAsync to create an HttpResponseMessage, then convert to an HTTP response message. 

调用ExecuteAsync先创建一个HttpReponseMessage,在转换为Http Reponse输出。

Other type

Write the serialized return value into the response body; return 200 (OK).

序列化后的信息返回到消息体中。

 

例子:

 

 

1.void

WebApi会简单的返回空消息,状态码为204

 

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

 

HTTP返回:

HTTP/1.1 204 NoContent
Server: Microsoft-IIS/8.0
Date: Mon, 27 Jan 2014 02:13:26 GMT

 

2.HttpResponseMessage

WepApi会直接将值写入到Http响应中去。你可以使用一些选项在输出之前对http响应做一些控制,例如,可以控制Cache-Control头。

public class ValuesController :ApiController
{
   
public HttpResponseMessageGet()
    {
       
HttpResponseMessage response =Request.CreateResponse(HttpStatusCode.OK,"value");
        response.
Content =newStringContent("hello",Encoding.Unicode);
        response.
Headers.CacheControl =newCacheControlHeaderValue()
        {
           
MaxAge =TimeSpan.FromMinutes(20)
        };
       
returnresponse;
    }
}

 

Response:

HTTP/1.1200 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

 

如果你将一个领域模型对象传递给CreateReponse方法,WebApi会自动调用media formatter将模型序列化后写入到Http响应中。

public HttpResponseMessage Get()
{
   
// Get a list of products from adatabase.
   
IEnumerable<Product>products =GetProductsFromDB();
         // Writethe list to the response body.
   
HttpResponseMessageresponse =Request.CreateResponse(HttpStatusCode.OK, products);
   
return response;
}

WebApi根据Http请求中的Accept头来选择具体使用哪个序列化器,更多信息参见 Content Negotiation.

 

3.IHttpActionResult

该接口本质上,定义了一个HttpReponseMessage工厂,使用IHttpActionResult有一些优势如下:

  • 简化Controller的单元测试 unit testing 
  • 将创建Http响应的通用逻辑移动到单独的类中(Moves common logic for creating HTTP responses into separate classes)
  • 通过隐藏创建响应的底层代码,使Controller、aciton的变得更清晰。

 

该接口定义了一个方法ExecuteAsync,用来创建HttpReponseMessage实例

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


所以,当Action返回一个IHttpActionResult接口的时候,WebApi会调用ExecuteAsync方法生成HttpReponseMessage实例,然后HttpReponseMessage实例会将信息写入到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 =newHttpResponseMessage()
        {
           
Content =newStringContent(_value),
           
RequestMessage = _request
        };
       
return Task.FromResult(response);
    }
}

Controller:

public class ValuesController :ApiController
{
   
public IHttpActionResultGet()
    {
       
return new TextResult("hello",Request);
    }
}

Response:

HTTP/1.1 200OK
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的IHttpActionResult的实例。否则的话,调用ApiController.OK返回一个包含产品信息的200状态的结果。

public IHttpActionResult Get (int id)
{
   
Productproduct = _repository.Get (id);
   
if(product ==null)
    {
       
return NotFound();// Returns a NotFoundResult
    }
   
return Ok(product); // Returns an OkNegotiatedContentResult
}

 

4.Other Return Types其他返回类型

对于其他返回类型,WepApi会调用media formatter来序列化对象,还记得前面讲的吗,WebApi会根据请求中ACCEPT头来自动选择formatterContent Negotiation)。然后将序列化结果写入到响应信息中。

public class ProductsController :ApiController
{
   
public IEnumerable<Product>Get()
    {
       
return GetAllProductsFromDB();//将会序列化

    }
}


注意:因为返回的是自定义类型,所以你不能直接指定返回错误状态404等,但是你可以通过抛出HttpResponseException 异常来指定错误代码,更多信息请看

 Exception Handling in ASP.NETWeb API.

 

请求信息:

GET http://localhost/api/products HTTP/1.1
User-Agent: Fiddler
Host: localhost:24127
Accept: application/json

 

相应信息:

HTTP/1.1200 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}]


0 0
原创粉丝点击