ASP.NET Web API应用程序为启用了TransferRequestHandler的非存在路由返回HTTP 500

时间:2015-12-01 10:58:36

标签: c# asp.net iis asp.net-web-api

我创建了一个简单的Web API应用程序(启用了Web API的Visual Studio中的空模板),添加了一个控制器:

[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" });
    }
}

现在我们需要在file.pdf变量中支持文件扩展名(例如path),所以我修改了web.config:

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

现在的问题是HTTP状态代码是不一致的,具体取决于前缀/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)

500错误页面以HTML格式显示,应用程序日志中没有记录任何内容,不会抛出任何异常。我正在使用VS 2015,使用.NET framework 4.5.1。

1 个答案:

答案 0 :(得分:4)

我也看到了这一点 - 我看到了我的global.asax.cs&#34; BeginRequest&#34;和#34; EndRequest&#34;对于这样的请求,大约会被调用10次。看起来像是一个ASP.NET / WebApi错误。

我找到的解决方案是注册一个&#34;赶上所有&#34;使用始终返回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();
    }
}