2014-04-27 42 views
2

我的操作應該返回什麼?ASP.NET WebApi操作返回類型

  1. 類型的對象/類別:CustomerIEnumerable<Order>
  2. HttpResponseMessage
  3. IHttpActionResult

什麼是返回後兩個一個最好的方法是什麼?我應該使用Ok還是Content輔助方法?

回答

2

所有的操作結果將被框架轉換爲HttpResponseMessage,所以三個列出的操作的結果將是相同的。但是,最後一個是將結果返回給客戶端的首選方式,因爲它更簡潔。我們來看看三個選項。

比方說,有一個產品倉庫像這樣的:

public interface IProductRepository 
    { 
     Product FindProductById(int productId); 
    } 

    public class ProductRepository : IProductRepository 
    { 
     private List<Product> products = new List<Product>(); 
     private int _nextId = 1; 

     public ProductRepository() 
     { 
      Add(new Product { Name = "Tomato soup", Category = "Groceries", Price = 1.39M }); 
      Add(new Product { Name = "Yo-yo", Category = "Toys", Price = 3.75M }); 
      Add(new Product { Name = "Hammer", Category = "Hardware", Price = 16.99M }); 
     } 

     public IEnumerable<Product> GetAll() 
     { 
      return products; 
     } 

     public Product FindProductById(int id) 
     { 
      return products.Find(p => p.Id == id); 
     } 

     public Product Add(Product item) 
     { 
      if (item == null) 
      { 
       throw new ArgumentNullException("item"); 
      } 
      item.Id = _nextId++; 
      products.Add(item); 
      return item; 
     } 

    } 

而且產品控制器:

public class ProductsController : ApiController 
    { 
     private IProductRepository _repository; 

     public ProductsController() 
     { 
      _repository = new ProductRepository(); 
     } 

    } 

現在,添加一個get操作,返回對象作爲結果。

 [Route("products/{productId}")] 
     public Product GetReturnsObjects(int productId) 
     { 
      Product product = _repository.FindProductById(productId); 

      if(product ==null) //Throwing the exception skips the entire Http Response pipeline 
       throw new HttpResponseException(HttpStatusCode.NotFound); 

      return product; 
     } 

正如你所看到的,爲了回報什麼,但一個產品,我們不得不拋出一個異常,並適當HttpStatusCode。這樣做會跳過響應管道,除非在HttpConfiguration中有一個異常過濾器。

接下來,讓我們創建GET方法返回HttpResponseMessage或IHttpActionResult

 [Route("messageproducts/{productId}")] 
     public HttpResponseMessage GetReturnResponseMessage(int productId) 
     { 
      Product product = _repository.FindProductById(productId); 

      if(product ==null) 
       return new HttpResponseMessage(HttpStatusCode.NotFound); 

      return Request.CreateResponse(HttpStatusCode.OK, product); 
     } 

     [Route("actionresultproducts/{productId}")] 
     public IHttpActionResult GetReturnsActionResult(int productId) 
     { 
       Product product = _repository.FindProductById(productId); 

      if (product == null) 
       return NotFound(); 


      return Ok(product); //Same as Content(HttpStatusCode.OK, product); 
     } 

顯然,後者是更短,更簡潔。

至於Ok()或Content(),您應該使用Ok()出於同樣的原因。

希望這會有所幫助。

+0

因爲我有同樣的問題而陷入困境。 +1的例子。你碰巧知道微軟(又一次)提供多種方法的原因嗎?根據你的解釋,「返回產品」這樣的東西不應該首先存在,但它似乎是微軟在他們的例子中首選的方式。哦,我喜歡IHttpActionResult,像'return NotFound()'這樣的東西很好地吸引了大多數產品無處不在的語言。 – Acrotygma

+0

@Acrotygma我猜他們只是想讓API方法看起來像普通的.Net方法,所以這就是「返回對象」被設計的原因。另外,您查看的示例可能來自API的版本1,該版本沒有IHttpActionResult。 –