Web API-如何將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插件

clipboard

指定請求頭部 Accept 值 為:application/xml 則返回xml類型數據。

clip_image002

指定請求頭部 Accept 值 為:application/json 則返回json類型數據。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM