ASP.NET Web API 2:Action的返回類型

Web API控制器中的Action方法有以下幾種返回類型:json

  1. void
  2. HttpResponseMessage
  3. IHttpActionResult
  4. 其它類型
基於上面幾種不一樣的返回類型,Web API建立HTTP響應消息的機制也不一樣。
返回類型 Web API建立HTTP響應消息的機制
void 返回HTTP狀態碼204(無內容)
HttpResponseMessage 直接轉換成HTTP響應消息
IHttpActionResult 調用接口的ExecuteAsync方法建立一個HttpResponseMessage對象,而後轉換成HTTP響應消息
其它類型 把序列化後的返回值寫入響應正文,而且返回HTTP狀態碼200(OK)
下面詳細介紹幾種返回類型

voidapi

若是返回類型是void, Web API 會返回一個HTTP狀態碼204(無內容)的空HTTP響應消息
示例代碼:
    public class ReturnValueDemoController : ApiController
    {
          //返回類型爲void        
          public void Get()
        {           
        }
    }
HTTP響應消息:
HTTP/1.1 204 No Content
Cache-Control: no-cache
Pragma: no-cache
Expires: -1
Server: Microsoft-IIS/8.0
X-AspNet-Version: 4.0.30319
X-SourceFiles: =?UTF-8?B?RTpcV29ya1NwYWNlXERvdE5ldFxNdmNEZW1vXE12Y0RlbW8uV2ViVUlcYXBpXFJldHVyblZhbHVlRGVtbw==?=
X-Powered-By: ASP.NET
Date: Wed, 04 Mar 2015 14:34:09 GMT

 

HttpResponseMessageapp

若是返回類型是HttpResponseMessage ,Web API直接把返回值轉換成HTTP響應消息,HttpResponseMessage對象的屬性對應響應消息的屬性。你能夠靈活的設置響應標頭和響應正文,這就給了你對響應消息的更大的控制權。以下例:
    
 public class ReturnValueDemoController : ApiController
    {
        //返回類型爲HttpResponseMessage
        public HttpResponseMessage Get()
        {
            HttpResponseMessage response = Request.CreateResponse(HttpStatusCode .OK, "hello");
            response.Content = new StringContent ( "hello wep api", Encoding .Unicode);
            response.Headers.CacheControl = new CacheControlHeaderValue
            {
                MaxAge = TimeSpan .FromSeconds(600)
            };
            return response;
        }
    } 
響應:
HTTP/1.1 200 OK
Cache-Control: max-age=600
Content-Type: text/plain; charset=utf-16
Vary: Accept-Encoding
Server: Microsoft-IIS/8.0
X-AspNet-Version: 4.0.30319
X-SourceFiles: =?UTF-8?B?RTpcV29ya1NwYWNlXERvdE5ldFxNdmNEZW1vXE12Y0RlbW8uV2ViVUlcYXBpXFJldHVyblZhbHVlRGVtbw==?=
X-Powered-By: ASP.NET
Date: Wed, 04 Mar 2015 15:14:05 GMT
Content-Length: 26
 
hello wep api
若是你給CreateResponse方法傳入了一個領域模型, Web API就會把序列化後的領域模型寫入響應正文。
示例:
    public HttpResponseMessage Get()
        {
            IQueryable <Product > products = repository.GetProducts();
            HttpResponseMessage response = Request.CreateResponse(HttpStatusCode .OK, products);
            return response;
        }
響應:
HTTP/1.1 200 OK
Cache-Control: no-cache
Pragma: no-cache
Content-Type: application/json; charset=utf-8
Expires: -1
Server: Microsoft-IIS/8.0
X-AspNet-Version: 4.0.30319
X-SourceFiles: =?UTF-8?B?RTpcV29ya1NwYWNlXERvdE5ldFxNdmNEZW1vXE12Y0RlbW8uV2ViVUlcYXBpXFJldHVyblZhbHVlRGVtbw==?=
X-Powered-By: ASP.NET
Date: Wed, 04 Mar 2015 15:37:51 GMT
Content-Length: 264
 
[{"ProductId":1,"Name":" 蘋果","Description":null,"Price":1.0,"Category":"水果"},{"ProductId":2,"Name":"鼠標","Description":null,"Price":50.0,"Category":"電腦配件"},{"ProductId":3,"Name":"洗髮水","Description":null,"Price":20.0,"Category":"日用品"}]

IHttpActionResult異步

IHttpActionResult接口是在Web API 2才引入進來的,本質上,它定義了一個HttpResponseMessage工廠類。IHttpActionResult接口只定義了一個ExecuteAsync方法,該方法異步方式建立一個HttpResponseMessage實例。
public interface IHttpActionResult
{
    Task<HttpResponseMessage> ExecuteAsync(CancellationToken cancellationToken);
} 
若是控制器的Action返回類型是IHttpActionResult,Web API就會調用接口的ExecuteAsync方法建立一個HttpResponseMessage對象,而後轉換成HTTP響應消息。如下是一個IHttpActionResult接口的實現,它建立了一個普通文本響應消息。
  
public class PlainTextResult : IHttpActionResult
    {
        private string text;
        private HttpRequestMessage request;
 
        public PlainTextResult(string text, HttpRequestMessage request)
        {
            this .text = text;
            this .request = request;
        }
        public Task < HttpResponseMessage> ExecuteAsync(CancellationToken cancellationToken)
        {
            HttpResponseMessage response=new HttpResponseMessage
            {
                Content = new StringContent (text, Encoding.Unicode),
                RequestMessage = request
            };
            return Task .FromResult(response);
        }
    }
控制器Action代碼:
//返回類型是IHttpActionResult
        public IHttpActionResult Get()
        {
            return new PlainTextResult( "plain text result" ,Request);
        }
響應:
HTTP/1.1 200 OK
Cache-Control: no-cache
Pragma: no-cache
Content-Type: text/plain; charset=utf-16
Expires: -1
Vary: Accept-Encoding
Server: Microsoft-IIS/8.0
X-AspNet-Version: 4.0.30319
X-SourceFiles: =?UTF-8?B?RTpcV29ya1NwYWNlXERvdE5ldFxNdmNEZW1vXE12Y0RlbW8uV2ViVUlcYXBpXFJldHVyblZhbHVlRGVtbw==?=
X-Powered-By: ASP.NET
Date: Wed, 04 Mar 2015 16:17:30 GMT
Content-Length: 34
 
plain text result
一般狀況下,你無須本身去實現IHttpActionResult接口, 在System.Web.Http.Results命名空間下已經包含了不少實現該接口的Action返回類型。ApiContoller類也定義了不少方法獲取這些內置的Action返回類型。
在下面的例子裏,若是沒有找到某個產品,控制器調用ApiController.NotFound方法建立一個404 (Not Found)的響應消息。
HTTP/1.1 404 Not Found
Cache-Control: no-cache
Pragma: no-cache
Expires: -1
Server: Microsoft-IIS/8.0
X-AspNet-Version: 4.0.30319
X-SourceFiles: =?UTF-8?B?RTpcV29ya1NwYWNlXERvdE5ldFxNdmNEZW1vXE12Y0RlbW8uV2ViVUlcYXBpXFJldHVyblZhbHVlRGVtb1w1?=
X-Powered-By: ASP.NET
Date: Wed, 04 Mar 2015 16:54:21 GMT
Content-Length: 0
若是找到了,控制器調用ApiController.OK方法建立一個HTTP狀態碼200(OK)響應正文是產品信息的響應消息。
HTTP/1.1 200 OK
Cache-Control: no-cache
Pragma: no-cache
Content-Type: application/json; charset=utf-8
Expires: -1
Server: Microsoft-IIS/8.0
X-AspNet-Version: 4.0.30319
X-SourceFiles: =?UTF-8?B?RTpcV29ya1NwYWNlXERvdE5ldFxNdmNEZW1vXE12Y0RlbW8uV2ViVUlcYXBpXFJldHVyblZhbHVlRGVtb1wx?=
X-Powered-By: ASP.NET
Date: Wed, 04 Mar 2015 16:53:16 GMT
Content-Length: 82
 
{"ProductId":1,"Name":" 蘋果","Description":null,"Price":1.0,"Category":"水果"}

其它返回類型this

對於其它的返回類型,Web API會對返回值序列化,而後把序列化後的返回值寫入到響應正文裏,而且響應狀態碼是200(OK)。    
public IQueryable < Product> GetpProducts()
        {
            return repository.GetProducts();
        } 
響應:
HTTP/1.1 200 OK
Cache-Control: no-cache
Pragma: no-cache
Content-Type: application/json; charset=utf-8
Expires: -1
Server: Microsoft-IIS/8.0
X-AspNet-Version: 4.0.30319
X-SourceFiles: =?UTF-8?B?RTpcV29ya1NwYWNlXERvdE5ldFxNdmNEZW1vXE12Y0RlbW8uV2ViVUlcYXBpXFJldHVyblZhbHVlRGVtb1w=?=
X-Powered-By: ASP.NET
Date: Wed, 04 Mar 2015 17:03:13 GMT
Content-Length: 264
 
[{"ProductId":1,"Name":" 蘋果","Description":null,"Price":1.0,"Category":"水果"},{"ProductId":2,"Name":"鼠標","Description":null,"Price":50.0,"Category":"電腦配件"},{"ProductId":3,"Name":"洗髮水","Description":null,"Price":20.0,"Category":"日用品"}]
使用這種返回類型的一個缺點就是你不能直接返回一個錯誤代碼,例如404。不過,你能夠經過拋出HttpResponseException異常來解決這個問題。
public Product GetProductById( int id)
        {
            Product product = repository.GetProductById(id);
            if (product==null )
                throw new HttpResponseException ( HttpStatusCode.NotFound);
 
            return product;
        }
相關文章
相關標籤/搜索