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