2013-02-08 2 views
16

Tôi đang gặp sự cố với định tuyến Web.API của mình. Tôi có hai tuyến đường sau:Web.API MapHttpThông số tuyến

config.Routes.MapHttpRoute(
    name: "MethodOne", 
    routeTemplate: "api/{controller}/{action}/{id}/{type}", 
    defaults: new { id = RouteParameter.Optional, type = RouteParameter.Optional } 
); 

config.Routes.MapHttpRoute(
    name: "MethodTwo", 
    routeTemplate: "api/{controller}/{action}/{directory}/{report}", 
    defaults: new { directory = RouteParameter.Optional, report = RouteParameter.Optional } 
); 

Và trong điều khiển của tôi hai phương pháp:

[HttpGet] 
[ActionName("methodone")] 
public string MethodOne(string id, string type) 
{ 
    return string.Empty; 
} 

[HttpGet] 
[ActionName("methodtwo")] 
public string MethodTwo(string directory, string report) 
{ 
    return string.Empty; 
} 

Hai dường như không thể sống cạnh nhau. Nếu tôi nhận xét tuyến đường MethodOne trong WebApiConfig, tuyến đường MethodTwo sẽ hoạt động. Commenting MethodTwo route cho phép MethodOne hoạt động. Để cả hai không được chú ý, MethodOne hoạt động, nhưng không phải là MethodTwo.

Tôi đã hy vọng sử dụng một lộ trình cho cả hai loại này, có vẻ như chúng sẽ phải có cùng tên thông số. Ai viết phương pháp với tên tham số chung? Xấu. Tôi thực sự không muốn các phương thức của tôi có cùng tên tham số (như p1, p2, p3), vì vậy tôi nghĩ rằng tôi có thể tạo một tuyến đường chỉ cho phương thức mới. Nhưng ngay cả điều này dường như không hoạt động.

Tôi thực sự bỏ lỡ số WebGet(UriTemplate="") từ phần còn lại WCF.

Tôi có một bộ điều khiển có nhiều phương pháp, một số có tham số 1, 2, 3 hoặc thậm chí nhiều hơn. Tôi không thể tin rằng tôi không thể sử dụng tên tham số có ý nghĩa với cách tiếp cận MapHttpRoute.

Tôi có thể nhận xét nội dung đó ra hoàn toàn và sử dụng WebGet() ... nhưng trước khi tôi đến đó, tôi muốn xem liệu tôi có thiếu gì đó không.

Trả lời

14

Lý do bạn đang nhìn thấy vấn đề này là vì con đường đầu tiên của bạn sẽ phù hợp với cả hai yêu cầu. Mã thông báo id và loại trong URL sẽ khớp với cả hai yêu cầu bởi vì khi tuyến đường đang chạy, nó sẽ thử phân tích URL và đối sánh từng phân đoạn với URL của bạn.

Vì vậy, tuyến đường đầu tiên của bạn sẽ vui vẻ khớp với cả hai yêu cầu như sau.

~/methodone/1/mytype => action = methodone, id = 1, and type = mytype 
~/methodtwo/directory/report => action = methodtwo, id = directory, and type = report 

Để làm việc xung quanh này, bạn nên sử dụng tuyến đường như

config.Routes.MapHttpRoute(
    name: "MethodOne", 
    routeTemplate: "api/{controller}/methodone/{id}/{type}", 
    defaults: new { id = RouteParameter.Optional, type = RouteParameter.Optional } 
); 

config.Routes.MapHttpRoute(
    name: "MethodTwo", 
    routeTemplate: "api/{controller}/methodtwo/{directory}/{report}", 
    defaults: new { directory = RouteParameter.Optional, report = RouteParameter.Optional } 
); 

Thậm chí nếu bạn sử dụng WebGet, bạn có thể cần phải làm điều gì đó tương tự như disambiguous hai phương pháp tôi tin.

+0

Tôi sẽ cung cấp cho điều này một đi và cho bạn biết nếu nó hoạt động. Các bummer là tôi cần phải làm điều này bây giờ cho mọi phương pháp mà tôi muốn có một cách chính xác đặt tên tham số cho. Nó có thể được dễ dàng hơn để đi tuyến đường Youssef liên kết hoặc WebGet- những người thậm chí còn ít công việc và rõ ràng hơn. – Nicros

+2

Vì vậy, điều này không làm việc, cảm ơn. Tuy nhiên, điều này, IMHO, là crap. Không phải giải pháp của bạn mà là cách tiếp cận toàn bộ tuyến đường. Tôi hoặc phải có một lộ trình cho mọi phương pháp, không tốt đẹp, hoặc sử dụng WebGet cũ hoặc GET mới từ thuộc tính và nhận xét ra tất cả các công cụ định tuyến. Tôi thú nhận tôi không phải là một anh chàng web lớn, vì vậy có lẽ tôi đang làm một cái gì đó không chuẩn, nhưng điều này có vẻ như một cách tiếp cận rất hạn chế so với UriTemplate. – Nicros

+0

Tôi nghe bạn. Định tuyến chúng tôi hỗ trợ cho API Web v1 hoạt động tốt cho định tuyến dựa trên hành động HTTP hoặc hành động dựa trên định tuyến tương ứng. Tuy nhiên, nó không hoạt động tốt, vì chúng tôi đang làm việc để cải thiện câu chuyện, hãy xem http://aspnetwebstack.codeplex.com/workitem/184 –

4

Bạn có thể chọn chuyển các tham số trong chuỗi truy vấn như/MethodTwo? Directory = a & report = b, nhưng nếu bạn muốn chúng hiển thị trong đường dẫn, điều này giống như một ứng cử viên tốt cho thuộc tính định tuyến. Filip có một bài tuyệt vời về nó ở đây:

http://www.strathweb.com/2012/05/attribute-based-routing-in-asp-net-web-api/

+0

Tôi đã cố gắng ... dường như không sao, nó chỉ là một chút bực bội đi từ UriTemplate trong WCF đến một cái gì đó mà không làm việc quá nóng, và sau đó phải sử dụng một gói riêng biệt. : P Tôi cũng có thể sử dụng các công cụ WebGet cũ, nhưng sau đó tôi phải ánh xạ một cách rõ ràng toàn bộ tuyến đường cho mọi phương thức. Tôi đã hy vọng cho hệ thống mới linh hoạt hơn một chút. – Nicros

3

Từ http://www.asp.net/web-api/overview/web-api-routing-and-actions/routing-and-action-selection

Bạn cũng có thể cung cấp hạn chế, trong đó hạn chế như thế nào một đoạn URI có thể phù hợp với một trình giữ chỗ:

chế: mới {id = @ "\ d +"} // Chỉ phù hợp nếu "id" là một hoặc chữ số khác.

Thêm ràng buộc này để "MethodOne" (api/{controller}/{action}/{id}/{kiểu}) sẽ có nghĩa là số nó chỉ phù hợp nếu {id} là số nếu không nó sẽ khớp với "MethodTwo" ("api/{controller}/{action}/{directory}/{report}").