ASP.NET Web API returns HTTP 500 for non-existent routes with TransferRequestHandler enabled

I created a simple web API application (an empty template from Visual Studio with the web interface turned on), a controller was added:

[RoutePrefix("api/test")]
public class TestController : ApiController
{
    [HttpGet]
    [Route(@"resource/{*path?}")]
    public async Task<HttpResponseMessage> GetFolder(string path = "")
    {
        return this.Request.CreateResponse(HttpStatusCode.OK, new { Status = "OK" });
    }
}

Now we need to support file name extensions (for example file.pdf) in the variable path, so I changed the web.config file:

<system.webServer>
  <handlers>
    <remove name="ExtensionlessUrlHandler-Integrated-4.0" />
    <remove name="OPTIONSVerbHandler" />
    <remove name="TRACEVerbHandler" />
    <add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />

    <!-- API must handle all file names -->
    <add name="ApiUrlHandler" path="/api/test/*" verb="GET,POST,PUT,DELETE,OPTIONS" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />

  </handlers>
</system.webServer>

Now the problem is that the HTTP status codes are inconsistent, depending on the URL segments provided after the prefix /api/test/:

GET /api/test/resource => HTTP 200 (as expected)
GET /api/test/resource/foo => HTTP 200 (as expected)
GET /api/test/foo => HTTP 404 (as expected)
GET /api/test/foo/bar => HTTP 500 (expected: 404)

The 500 error page is displayed in HTML and nothing is logged in the application logs, with no exception being thrown. I am using VS 2015, with the .NET framework 4.5.1.

+4
1

- , global.asax.cs "BeginRequest" "EndRequest" 10 . ASP.NET/WebApi.

, , " " , 404.

        config.Routes.MapHttpRoute(
            name: "CatchAllRoute",
            routeTemplate: "{*catchall}",
            defaults: new { controller = "UnrecognizedRoute", action = ApiConstants.UnrecognizedRouteAction });

...

public class UnrecognizedRouteController : ApiController
{
    /// <summary>
    /// This method is called for every single API request that comes to the API and is not routed
    /// </summary>
    [ActionName(ApiConstants.UnrecognizedRouteAction)]
    [HttpDelete, HttpGet, HttpHead, HttpOptions, HttpPost, HttpPatch, HttpPut]
    public IHttpActionResult ProcessUnrecognizedRoute()
    {
        return NotFound();
    }
}
+3

Source: https://habr.com/ru/post/1618098/


All Articles