2012-05-18 25 views
7

Tôi đang xem hướng dẫn sau đây từ Microsoft. Theo hướng dẫn này,ASP.NET Web.api xử lý hai phương thức với tên bắt đầu bằng GET như thế nào?

Trong ví dụ đầu tiên, "sản phẩm" khớp với bộ điều khiển có tên ProductsController. Yêu cầu là yêu cầu GET, do đó, khung tìm kiếm phương thức trên ProductsController có tên bắt đầu bằng "Nhận ...". Hơn nữa, URI không chứa phân đoạn {id} tùy chọn, do đó khung tìm kiếm một phương thức không có tham số. Các ProductsController :: GetAllProducts phương pháp đáp ứng tất cả các yêu cầu .

Điều gì xảy ra nếu có hai phương pháp như GetAllProducts() và GetSoldProducts()? Cả hai đều không có tham số.

Your First Web API Tutorial

Trả lời

8

Giả sử bạn đang sử dụng các tuyến đường mặc định câu trả lời ngắn gọn là: phương pháp định nghĩa đầu tiên (ở phía trên) của lớp học của bạn sẽ được gọi. phương pháp khác là không thể tiếp cận.

LƯU Ý: phiên bản beta hoạt động như ở trên cho 'khớp nhiều phương thức' - phiên bản RC & Phiên bản phát hành có nhiều OCD hơn một chút. Nó ném một lỗi nếu có nhiều trận đấu tiềm năng. Thay đổi này loại bỏ sự nhầm lẫn của nhiều kết quả không rõ ràng. Đồng thời, nó làm giảm khả năng kết hợp các giao diện kiểu REST và RPC trong cùng một bộ điều khiển, dựa vào thứ tự chồng chéo &.

Trộm cắp tự do từ another post I wrote on the topic:

WebAPI Matching Semantic

Các phù hợp với ngữ nghĩa được sử dụng bởi WebAPI là khá đơn giản.

  1. Nó phù hợp với tên của hành động với động từ (verb = get? Tìm kiếm phương pháp bắt đầu bằng "nhận được")
  2. nếu một tham số được thông qua, các api tìm kiếm một hành động với một tham số

Vì vậy, trong mã của bạn, hãy lấy một yêu cầu GET mà không có tham số khớp với hàm Get*() mà không có tham số. A chứa và ID tìm kiếm một Get***(int id).

Ví dụ

Trong khi ngữ nghĩa phù hợp rất đơn giản, nó tạo ra một số nhầm lẫn cho các nhà phát triển MVC (cũng ít nhất nhà phát triển này). Hãy xem xét một số ví dụ:

Tên vô danh - Phương thức nhận của bạn có thể được đặt tên bất cứ điều gì, miễn là bắt đầu bằng "get". Vì vậy, trong trường hợp của một bộ điều khiển widget, bạn có thể đặt tên cho các hàm của mình GetStrawberry() và nó vẫn sẽ được khớp. Hãy suy nghĩ về kết hợp như một cái gì đó như: methodname.StartsWith("Get")

Nhiều phương pháp đối sánh - Điều gì sẽ xảy ra nếu bạn có hai phương pháp Nhận không có tham số?GetStrawberry()GetOrange(). Tốt nhất tôi có thể nói, hàm được định nghĩa đầu tiên (đầu tệp) trong mã của bạn thắng ... lạ. Điều này có tác dụng phụ của việc làm cho một số phương pháp trong bộ điều khiển của bạn không thể truy cập (ít nhất là với các tuyến đường mặc định) .... người lạ.

CẬP NHẬT

@WinFXGuy - Đây là một chút thời gian để đặt trong một chú thích, nhưng ...

Đừng nhảy đến kết luận! Tôi đã cố trả lời câu hỏi mà bạn đặt ra, nhưng đó chỉ là một nửa câu chuyện. Có rất nhiều điều bạn có thể làm để thay đổi hành vi mặc định.

Đầu tiên, WebAPI hỗ trợ nhiều thông số oData. Nếu bạn bong bóng một IQueryable lên đến bộ điều khiển của bạn, oData paramaters được tự động tích hợp với đối tượng truy vấn. Nó có các tham số như $filter, $top$skip. Vì vậy, bạn trong trường hợp của bạn, bạn có thể viết một phương pháp và vượt qua một cái gì đó như $filter=sale_date neq null.

Ngoài ra, bạn có thể áp dụng thuộc tính [ResultLimit] để ngăn mọi người yêu cầu 15 tỷ bản ghi.

Thứ hai bạn có thể sửa đổi các tuyến đường. Các tuyến mặc định hướng tới một api RESTful, nơi bạn thường có 1 bộ điều khiển cho mỗi thực thể. Bạn có thể thay đổi các tuyến đường và làm cho nó phong cách RPC.

Nếu bạn nhìn vào bài đăng được liên kết của tôi, tôi giải thích cách tôi giữ liên kết tuyến mặc định, thêm 'thư mục phụ' và cũng cho phép gọi phương thức bổ sung cho các tình huống mà tôi cần GetAllProducts()GetSoldProducts().

+0

tôi không thích những gì tôi đang đọc! Đó là loại hạn chế asp.net web api capabilites. – WinFXGuy

+0

@WinFXGuy - quá dài để nhận xét ... xem cập nhật – EBarr

+0

Tôi thấy rằng nó nhìn vào tên tham số để giải quyết tình trạng quá tải. Vì vậy, api/thực phẩm? Name = cam được gọi là GetFoodByName (tên chuỗi) và api/food? Category = fruit có tên GetFoodByCategory (loại chuỗi). –

11

Có hai giải pháp khả thi cho vấn đề cụ thể này:

  1. Alter MapHttpRoute gọi để yêu cầu xác định tên của hành động. (Tôi đang sử dụng cú pháp Tự lưu trữ):

    config.Routes.MapHttpRoute(
          "API Route 1", 
          "api/{controller}/{action}"); 
    
        config.Routes.MapHttpRoute(
          "API Route 2", 
          "api/{action}", 
          new { controller = "products" }); 
    

    Vì vậy, khách hàng của bạn sẽ http gọi:

    api/products/GetAllProducts HOẶC api/GetAllProducts api/products/GetSoldProducts HOẶC api/GetSoldProducts

    Xem: http://www.asp.net/web-api/overview/web-api-routing-and-actions/routing-in-aspnet-web-api

  2. Nơi mỗi phương pháp trong một bộ điều khiển riêng biệt (ProductsController, SoldProductsController). Vì vậy, bạn sẽ gọi số api/productsapi/soldproducts để nhận kết quả của mình.


chủ đề liên quan ... trong tình huống mà bạn có nhiều Get hành động mà có một cuộc tranh luận nguyên thủy duy nhất của cùng loại, ASP.NET Web API sẽ nhìn vào tên của đối số để giải quyết hành động quá tải để gọi.

Ví dụ, nếu bạn có hai hành động:

GetProductByName(string name) 
GetProductByCategory(string category) 

khách hàng http của bạn có thể gọi

api/products?name=hammer 
api/products?category=toys 

và động cơ định tuyến sẽ gọi hành động đúng.

4

Thêm một câu trả lời để phản ánh rằng phiên bản mới nhất của Web API hỗ trợ [Route] thuộc tính natively

[Route("api/products")] 
public IEnumerable<Product> GetAllProducts(){} 

[Route("api/products/sold")] 
public IEnumerable<Product> GetSoldProducts(){} 
+1

Điều này với tôi là giải pháp tốt nhất –

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