WebApi2中action几种返回值

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


本文介绍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 =new StringContent("hello",Encoding.Unicode);
        response.
Headers.CacheControl =new CacheControlHeaderValue()
        {
           
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 =new HttpResponseMessage()
        {
           
Content =new StringContent(_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}]


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值