ASP.NET Web Api returns 200 OK when it should return 404

I have the following action methods on a controller in an ASP.NET Web API project:

[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)

Due to a javascript error, I made a DELETE request to

api/v2/project/1234/stuff/undefined

ie instead of a GUID for the id, I got the string "undefined" . As far as I can tell, this shouldn't match any of my routes, but instead of a 404 Not found (or even 405 Method not allowed ), I got a 200 OK as response.

I set a breakpoint in each of these action methods and repeated the request using Fiddler, but none of the breakpoints was hit. I also tried installing the WebApiRouteDebugger package from nuget, but we're using a custom controller factory which hooks things up through our DI container, so I couldn't get it to work at all. I even tried throwing the following exception from one of my globally registered filters:

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

but the DELETE request still goes through to 200 OK (no requests to valid urls seem to do that).

How else can I troubleshoot this? What could be the root cause?


In your Global.asax.cs file where your protected void Application_Start(object sender, EventArgs e) is, add the following:

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

All server requests should come through here.

Add these using if not there.

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

Then in the begin request call add this code to list out all of the active routes.

        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 + "]";
                    }
                }
            }
        }

This will list all controllers and their signatures. If your URL does not fit into any of these you may have to expand the list to include non controller routes.


I had the same issue. In my startup.cs I had the method

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

This was causing all routes to receive a 200 response along with the string. I only wanted to show this response on startup. This was the solution.

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

Along with a method in the same Startup class

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

I only return the 200 OK message when a request is made on the base url.


I'm am not sure of your routing but I think you have a routing that does not include actions in mapping:

api/v2/project/1234/stuff/undefined 

Check web api config for this: api/{controller}[/{action}]/{id} . I think you might hit another route action with your action(like a GET).

PS post your route config to update answer.

链接地址: http://www.djcxy.com/p/83862.html

上一篇: Pydoop从HDFS文件读取readline

下一篇: ASP.NET Web Api在返回404时返回200 OK