2012-06-12 36 views
74

Tôi đã có những hành động sau đây trên một ApiController:ASP.NET Web Api: Tài nguyên yêu cầu không hỗ trợ http phương pháp 'GET'

public string Something() 
{ 
    return "value"; 
} 

Và tôi đã cấu hình các tuyến đường của tôi như sau:

routes.MapHttpRoute(
    name: "DefaultApi", 
    routeTemplate: "api/{controller}/{action}/{id}", 
    defaults: new { id = RouteParameter.Optional } 
); 

Trong các phiên bản beta, điều này chỉ làm việc tốt, nhưng tôi chỉ cập nhật cho phiên bản Release Candidate mới nhất và bây giờ tôi đang nhìn thấy lỗi trên các cuộc gọi như thế này:

Th e tài nguyên được yêu cầu không hỗ trợ phương thức http 'GET'.

Tại sao tính năng này không hoạt động nữa?

(Tôi cho rằng tôi có thể thoát khỏi {action} và chỉ cần thực hiện một tấn điều khiển, nhưng mà cảm thấy lộn xộn.)

Trả lời

94

Nếu bạn chưa cấu hình bất kỳ HttpMethod về hành động của bạn trong bộ điều khiển, nó được giả định chỉ là HttpPost trong RC. Trong bản Beta, nó được giả định là hỗ trợ tất cả các phương thức - GET, PUT, POST và Delete. Đây là một sự thay đổi nhỏ từ phiên bản beta thành RC. Bạn có thể dễ dàng khai thác nhiều hơn một httpmethod trên hành động của bạn với [AcceptVerbs ("GET", "POST")].

+0

chỉ gặp phải điều này, cảm ơn bạn đã khắc phục, nhưng tò mò, tại sao tôi phải làm điều này với phương pháp tùy chỉnh của mình, nhưng không phải là phương pháp "Nhận" mặc định? Tôi có một phương thức Get được tạo bởi mẫu cho bộ điều khiển, nhưng nó không được trang trí. điều này chỉ là theo quy ước vì tên Get? – SelAromDotNet

+3

@Josh: Vâng! Khi tên của phương thức hành động bắt đầu bằng "Get ...", bạn không phải đánh dấu nó là phương thức GET. Đọc thêm tại đây: http://www.asp.net/web-api/overview/web-api-routing-and-actions/routing-in-aspnet-web-api –

+0

Tôi đã làm như đề xuất trong câu trả lời nhưng bây giờ cả hai các cuộc gọi của tôi, Nhận và Đăng, đang được chuyển hướng đến Nhận hành động. Bất kỳ giúp đỡ xin vui lòng? –

14

Đây chắc chắn là sự thay đổi từ Beta sang RC. Trong ví dụ được cung cấp trong câu hỏi, bây giờ bạn cần phải trang trí hành động của mình với [HttpGet] hoặc [AcceptVerbs ("GET")].

Điều này gây ra sự cố nếu bạn muốn kết hợp hành động dựa trên động từ (ví dụ: "GetSomething", "PostSomething") với hành động không dựa trên động từ. Nếu bạn cố gắng sử dụng các thuộc tính ở trên, nó sẽ gây ra xung đột với bất kỳ hành động dựa trên động từ nào trong bộ điều khiển của bạn. Một cách để có được arount đó sẽ là để xác định các tuyến đường riêng biệt cho mỗi động từ, và thiết lập các hành động mặc định để tên của động từ. Cách tiếp cận này có thể được sử dụng để xác định tài nguyên con trong API của bạn. Ví dụ, mã sau đây hỗ trợ: "/ resource/id/children" trong đó id và con là tùy chọn.

 context.Routes.MapHttpRoute(
      name: "Api_Get", 
      routeTemplate: "{controller}/{id}/{action}", 
      defaults: new { id = RouteParameter.Optional, action = "Get" }, 
      constraints: new { httpMethod = new HttpMethodConstraint("GET") } 
     ); 

     context.Routes.MapHttpRoute(
      name: "Api_Post", 
      routeTemplate: "{controller}/{id}/{action}", 
      defaults: new { id = RouteParameter.Optional, action = "Post" }, 
      constraints: new { httpMethod = new HttpMethodConstraint("POST") } 
     ); 

Hy vọng các phiên bản Web API trong tương lai sẽ hỗ trợ tốt hơn cho trường hợp này. Hiện tại có sự cố đã đăng nhập vào dự án mã hóa aspnetwebstack, http://aspnetwebstack.codeplex.com/workitem/184. Nếu đây là điều bạn muốn xem, hãy bỏ phiếu cho vấn đề này.

51

Mọi thông tin trên đều đúng, tôi cũng muốn chỉ ra rằng chú thích [AcceptVerbs()] tồn tại trong cả hai không gian tên System.Web.Mvc và System.Web.Http.

Bạn muốn sử dụng System.Web.Http nếu đó là bộ điều khiển API Web.

+0

thx @Eric, tôi đã tự hỏi tại sao nó sẽ không hoạt động ... – jbl

+0

@Eric. Tuyệt vời, đây là lý do nó không làm việc cho tôi. Tôi đã có động từ trong hành động của mình nhưng nó đã được tham chiếu qua Web.Mvc nên không hoạt động. – dreza

+0

Tuyệt vời, Bạn đã lưu ngày của tôi –

25

Mặc dù đây không phải là câu trả lời cho OP, tôi đã có lỗi chính xác giống như nguyên nhân gốc rễ hoàn toàn khác; vì vậy trong trường hợp điều này sẽ giúp bất kỳ ai khác ...

Vấn đề đối với tôi là tham số phương thức được đặt tên không chính xác khiến WebAPI định tuyến yêu cầu bất ngờ. Tôi có những phương pháp sau đây trong ProgrammesController tôi:

[HttpGet] 
public Programme GetProgrammeById(int id) 
{ 
    ... 
} 

[HttpDelete] 
public bool DeleteProgramme(int programmeId) 
{ 
    ... 
} 

yêu cầu DELETE để .../api/chương trình/3 đã không nhận được chuyển đến DeleteProgramme như tôi mong đợi, nhưng để GetProgrammeById, vì DeleteProgramme không có một tham số tên của id. GetProgrammeById sau đó dĩ nhiên từ chối DELETE vì nó được đánh dấu là chỉ chấp nhận GET.

Vì vậy, việc sửa chữa rất đơn giản:

[HttpDelete] 
public bool DeleteProgramme(int id) 
{ 
    ... 
} 

Và tất cả là tốt. Sai lầm ngớ ngẩn thực sự nhưng khó gỡ lỗi.

14

Nếu bạn đang trang trí phương pháp của bạn với HttpGet, thêm using sau ở phía trên cùng của bộ điều khiển:

using System.Web.Http; 

Nếu bạn đang sử dụng System.Web.Mvc thì vấn đề này có thể xảy ra.

+1

Điều này đúng, và ridiculously .NET không hiển thị thông báo rõ ràng. –

2

Cùng một vấn đề như trên, nhưng gốc rất khác nhau. Đối với tôi, đó là tôi đã đánh một điểm cuối với quy tắc viết lại https. Đánh nó trên http gây ra lỗi, làm việc như mong đợi với https.

2

Có cùng thiết lập như OP. Một bộ điều khiển có nhiều hành động ... ít "lộn xộn" :-)

Trong trường hợp của tôi, tôi quên "[HttpGet]" khi thêm hành động mới.

[HttpGet] 
public IEnumerable<string> TestApiCall() 
{ 
    return new string[] { "aa", "bb" }; 
} 
Các vấn đề liên quan