2014-04-21 14 views
29

Trong ASP.NET Web API 2, sự khác nhau giữa những điều sau đây là gì?Trả về IHttpActionResult và IEnumerable <Item> và IQueryable <Item>

public async Task<IEnumerable<MyItem>> GetMyItems() 
{ 
    //... code ..., var myItems = await ... 
    return myItems; 
} 

public async Task<IQueryable<MyItem>> GetMyItems() 
{ 
    //... code ..., var myItems = await ... 
    return myItems; 
} 

public async Task<IHttpActionResult> GetMyItems() 
{ 
    //... code ..., var myItems = await ... 
    return Ok(myItems); 
} 

Tôi có nên trở IHttpActionResult hoặc IEnumerable<MyItem>/IQueryable<MyItem>?

+0

Nếu phương pháp hành động của bạn không bao gồm việc sử dụng từ khoá 'await', thì bạn không nên trả lại một 'Tác vụ'.Thay vào đó, bạn chỉ cần trả lại 'IHttpActionResult',' IEnumerable 'hoặc' IQueryable '. Xem câu hỏi [Tác vụ IHttpActionResult vs async ] (https://stackoverflow.com/q/29100732/1497596). Ngoài ra, hãy xem câu hỏi [Sử dụng hiệu quả async/await với ASP.NET Web API] (https://stackoverflow.com/q/31185072/1497596). – DavidRR

Trả lời

24

Bạn nên trả lại IHttpActionResult vì bạn có thể cụ thể hơn cho khách hàng. Bạn có thể tạo nhiều ứng dụng web thân thiện với người dùng hơn. Về cơ bản bạn có thể trả về các thông báo trạng thái HTML khác nhau cho các tình huống khác nhau.

Ví dụ:

public async Task<IHttpActionResult> GetMyItems() 
{ 
    if(!authorized) 
     return Unauthorized(); 
    if(myItems.Count == 0) 
     return NotFound(); 
    //... code ..., var myItems = await ... 
    return Ok(myItems); 
} 

IEnumerableIQueryable chỉ sẽ phân tích dữ liệu của bạn sang định dạng đầu ra và bạn sẽ không phải một cách thích hợp để xử lý các trường hợp ngoại lệ. Đó là sự khác biệt quan trọng nhất.

+0

Khi 'await' không được sử dụng trong' GetMyItems() ', chữ ký của nó chỉ đơn giản là' public IHttpActionResult GetMyItems() '. Từ câu hỏi [IHttpActionResult vs async Task ] (https://stackoverflow.com/q/29100732/1497596), xem [câu trả lời này] (https://stackoverflow.com/a/38699810/1497596) ở trạng thái nào : "Nếu mã tác vụ điều khiển của bạn không sử dụng 'await' thì bạn có thể chuyển về chữ ký đơn giản hơn. Tuy nhiên, kết quả bạn trả lại sẽ vẫn không đồng bộ." – DavidRR

6

Tôi sẽ chọn giữa IEnumerable và IHttpActionResult, bạn có thể thực hiện khá nhiều điều tương tự với cả hai cách này chỉ theo những cách hơi khác nhau. IQueryable thường được sử dụng cho các nhiệm vụ truy cập dữ liệu cấp thấp hơn và thực thi truy vấn sql bị trì hoãn để tôi giữ nó được đóng gói trong các lớp truy cập dữ liệu của bạn và không hiển thị nó với api web.

Dưới đây là một bản tóm tắt từ http://www.asp.net/web-api/overview/web-api-routing-and-actions/action-results:

IHttpActionResult

Giao diện IHttpActionResult được INTRODUCTED trong Web API 2. Về cơ bản, nó định nghĩa một nhà máy HttpResponseMessage. Dưới đây là một số lợi thế của việc sử dụng giao diện IHttpActionResult (trên lớp HttpResponseMessage):

  • đơn giản hoá đơn vị thử nghiệm bộ điều khiển của bạn.
  • Di chuyển logic chung để tạo phản hồi HTTP thành các lớp riêng biệt.
  • Làm cho mục đích của thao tác bộ điều khiển rõ ràng hơn, bằng cách ẩn chi tiết cấp thấp của việc xây dựng phản hồi.

IEnumerable < mục >

Đối với tất cả các loại lợi nhuận khác, Web API sử dụng một định dạng phương tiện truyền thông để serialize giá trị trả về. Web API ghi giá trị được tuần tự hóa vào nội dung phản hồi. Mã trạng thái phản hồi là 200 (OK).

public class ProductsController : ApiController 
{ 
    public IEnumerable<Product> Get() 
    { 
     return GetAllProductsFromDB(); 
    } 
} 

Một nhược điểm của phương pháp này là bạn có thể không trực tiếp trả lại mã lỗi, chẳng hạn như 404. Tuy nhiên, bạn có thể ném một HttpResponseException cho mã lỗi. Để biết thêm thông tin.

+2

-1 "IQueryable thường được sử dụng cho các nhiệm vụ truy cập dữ liệu cấp thấp hơn và thực hiện truy vấn sql bị trì hoãn vì vậy tôi sẽ giữ nó trong các lớp truy cập dữ liệu của bạn và không hiển thị nó với api web". Điều này hoàn toàn sai. Nếu không hiển thị IQueryable, rất khó sử dụng các url truy vấn 'OData'. http://www.asp.net/web-api/overview/odata-support-in-aspnet-web-api/odata-v4/create-an-odata-v4-endpoint – Aron

+1

@Aron Tôi đồng ý điều này không áp dụng cho OData, nhưng rất nhiều người sẽ không đồng ý với bạn về việc phơi bày IQueryable bên ngoài lớp kho lưu trữ: http://codetunnel.com/should-you-return-iqueryablet-from-your-repositories/, http: // lập trình viên .stackexchange.com/questions/192044/should-repositories-return-iqueryable, http://mikehadlow.blogspot.com.au/2009/01/should-my-repository-expose-iqueryable.html. Và một số người thậm chí mô tả OData chính nó như là một mô hình chống https://github.com/ServiceStack/ServiceStack/wiki/Auto-Query#why-not-odata – Jason

+0

Đó là những người cùng tôi sẽ cho rằng nền tảng bên trong là một chống mẫu. – Aron

Các vấn đề liên quan