2015-02-24 22 views
7

Tôi có phương pháp hành động sau trên một bộ điều khiển trong một dự án Web API ASP.NET:ASP.NET Web Api trả về 200 OK khi nó phải trả lại 404

[Route("api/v2/project/{projectId}/stuff"), HttpGet] 
public IHttpActionResult Get(int projectId) 

[Route("api/v2/project/{projectId}/stuff/{id:guid}"), HttpGet] 
public IHttpActionResult Get(int projectId, [FromUri] Guid id) 

[Route("api/v2/project/{projectId}/stuff"), HttpPost] 
public IHttpActionResult Post(int projectId, [Required] Stuff stuff) 

[Route("api/v2/project/{projectId}/stuff/{id:guid}"), HttpPut] 
public IHttpActionResult Put(int projectId, [FromUri] Guid blastId, Stuff stuff) 

[Route("api/v2/project/{projectId}/stuff/{id:guid}"), HttpDelete] 
public IHttpActionResult Delete(int projectId, [FromUri] Guid id) 

Do một lỗi javascript, tôi đã thực hiện một DELETE yêu cầu

api/v2/project/1234/stuff/undefined 

tức là thay vì một GUID cho id, tôi có chuỗi "undefined". Theo như tôi có thể nói, điều này không phù hợp với bất kỳ tuyến đường nào của tôi, nhưng thay vì một số 404 Not found (hoặc thậm chí 405 Method not allowed), tôi nhận được một phản hồi là 200 OK.

Tôi đặt điểm ngắt trong mỗi phương thức hành động này và lặp lại yêu cầu bằng Fiddler, nhưng không có điểm ngắt nào bị trúng. Tôi cũng đã thử cài đặt gói WebApiRouteDebugger từ nuget, nhưng chúng tôi đang sử dụng một nhà máy điều khiển tùy chỉnh móc mọi thứ thông qua vùng chứa DI của chúng tôi, vì vậy tôi không thể làm việc đó được. Tôi thậm chí đã cố gắng ném ngoại lệ sau đây từ một trong các bộ lọc đăng ký trên toàn thế giới của tôi:

throw new Exception(actionContext.ControllerContext.ControllerDescriptor.ControllerName + 
" " + actionContext.ActionDescriptor.ActionName); 

nhưng yêu cầu DELETEvẫn đi qua để 200 OK (không yêu cầu đối với các url hợp lệ dường như để làm điều đó).

Tôi có thể khắc phục sự cố này bằng cách nào khác? Nguyên nhân gốc rễ có thể là gì?

+1

Tôi đã tạo dự án Web APi mới và thêm bộ điều khiển với các phương pháp và định tuyến của bạn để kiểm tra. Thật không may hoạt động tốt. Đối với url 'api/v2/project/{project Id}/stuff/{id: guid}' Tôi gặp lỗi 404. Tôi nghĩ rằng đó là vấn đề với định tuyến không chính xác trong bộ điều khiển khác hoặc url với 'không xác định' phù hợp với tuyến đường khác. –

+0

@BartoszCzerwonka: Cảm ơn bạn đã dành thời gian để làm điều đó. Dự án là lớn, đó là lý do tại sao tôi không bao gồm tất cả các tuyến trong toàn bộ dự án - tuy nhiên, tôi đã kiểm tra cẩn thận và không có tuyến nào trong dự án khớp với 'api/v2/project/{ projectId}/stuff/ 'ngoại trừ trong bộ điều khiển này. –

+0

Ngoài ra, chỉ có duy nhất một trong số chúng chấp nhận yêu cầu 'DELETE' - và đó là yêu cầu không có điểm ngắt. –

Trả lời

3

Trong Global.asax.cs bạn nộp nơi protected void Application_Start(object sender, EventArgs e) của bạn, thêm dòng sau:

protected void Application_BeginRequest(object sender, EventArgs e) 
    { 
    } 

Mọi yêu cầu máy chủ nên đi qua đây.

Thêm chúng bằng cách sử dụng nếu không ở đó.

using System.Web.Compilation; 
using System.Reflection; 

Sau đó, trong yêu cầu bắt đầu, hãy thêm mã này để liệt kê tất cả các tuyến đang hoạt động.

 string Items = ""; 
     IEnumerable<Assembly> Assemblies = BuildManager.GetReferencedAssemblies().Cast<Assembly>(); 

     foreach (Assembly FoundAssembly in Assemblies) 
     { 
      string AssemblyName = FoundAssembly.FullName; 
      IEnumerable<TypeInfo> Types = FoundAssembly.DefinedTypes.Where(type => type != null && type.IsPublic && type.IsClass && !type.IsAbstract && typeof(ApiController).IsAssignableFrom(type)); 
      foreach (TypeInfo ControllerType in Types) 
      { 
       System.Web.Http.Controllers.ApiControllerActionSelector ApiControllerSelection = new System.Web.Http.Controllers.ApiControllerActionSelector(); 
       System.Web.Http.Controllers.HttpControllerDescriptor ApiDescriptor = new System.Web.Http.Controllers.HttpControllerDescriptor(new System.Web.Http.HttpConfiguration(), ControllerType.Name, ControllerType); 
       ILookup<string, System.Web.Http.Controllers.HttpActionDescriptor> ApiMappings = ApiControllerSelection.GetActionMapping(ApiDescriptor); 

       foreach (var Maps in ApiMappings) 
       { 
        foreach (System.Web.Http.Controllers.HttpActionDescriptor Actions in Maps) 
        { 
         Items += "[ controller=" + ControllerType.Name + " action=" + ((System.Web.Http.Controllers.ReflectedHttpActionDescriptor)(Actions)).MethodInfo + "]"; 
        } 
       } 
      } 
     } 

Điều này sẽ liệt kê tất cả bộ điều khiển và chữ ký của chúng. Nếu URL của bạn không phù hợp với bất kỳ trong số này, bạn có thể phải mở rộng danh sách để bao gồm các tuyến không điều khiển.

+0

Một số thay đổi khác trong dự án của chúng tôi đã khiến tôi không thể tái tạo sự cố kể từ khi nó xảy ra; tuy nhiên, đề xuất khắc phục sự cố này là đủ tốt để tôi chắc chắn sẽ sử dụng nó nếu sự cố xuất hiện lại. Cảm ơn bạn rất nhiều về mẹo - Tôi rất vui khi được trao cho bạn mức tăng 1000% :) –

0

Tôi không chắc chắn của định tuyến của bạn nhưng tôi nghĩ rằng bạn có một định tuyến mà không bao gồm các hành động trong bản đồ:

api/v2/project/1234/stuff/undefined 

Kiểm tra web api cấu hình cho việc này: api/{controller}[/{action}]/{id}. Tôi nghĩ rằng bạn có thể nhấn một hành động tuyến đường khác với hành động của bạn (như GET).

P.S. đăng cấu hình tuyến đường của bạn để cập nhật câu trả lời.

1

Tôi gặp vấn đề tương tự. Trong startup.cs của tôi, tôi đã có phương thức

app.Run(async context => 
     { 
      context.Response.ContentType = "text/plain"; 
      await context.Response.WriteAsync("My Api"); 
     }); 

Điều này đã khiến tất cả các tuyến đường nhận được phản hồi 200 cùng với chuỗi. Tôi chỉ muốn hiển thị phản hồi này khi khởi động. Đây là giải pháp.

app.MapWhen(ctx => ctx.Request.Path.Value == "/", StartupPage); 

Cùng với một phương pháp trong cùng một lớp Startup

private void StartupPage(IAppBuilder app) 
    { 
     app.Run(async (context) => 
     { 
      context.Response.ContentType = "text/plain"; 
      await context.Response.WriteAsync("My Api"); 
     }); 
    } 

Tôi chỉ trả lại thông điệp 200 OK khi một yêu cầu được thực hiện trên cơ sở url.

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