ASP.NET Core Web API:捕获路由错误

时间:2016-09-26 10:36:52

标签: asp.net-web-api asp.net-core asp.net-core-mvc asp.net-core-webapi

我正在尝试捕获ASP.NET Core Web API项目中的路由错误。

具体来说,路由错误,我的意思是: 在控制器中我只有:

// GET api/values/5
[HttpGet("{id}")]
public string Get(int id)
{
    return "value";
}

但请求是:

api/values/5/6

自动返回404,但我希望能够在代码中处理此问题(即调用某种异常处理例程)。

我尝试了三种不同的方法但没有成功:

在ConfigureServices(IServiceCollection服务)中,我添加了:

services.AddMvc(config =>
{
    config.Filters.Add(typeof(CustomExceptionFilter));
});

这捕获了控制器内发生的错误(例如,如果我在上面的Get(id)方法中放置了throw()),但没有路由错误。我假设这是因为没有找到匹配的控制器方法,因此错误传播到中间件管道。

为了在管道中进一步处理错误,我试过......

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
    loggerFactory.AddConsole(Configuration.GetSection("Logging"));
    loggerFactory.AddDebug();

    app.UseExceptionHandler(
        options =>
        {
            options.Run(
            async context =>
            {
                var ex = context.Features.Get<IExceptionHandlerFeature>();
                // handle exception here
            });
        });

    app.UseApplicationInsightsRequestTelemetry();
    app.UseApplicationInsightsExceptionTelemetry();
    app.UseMvc();
}

我也尝试过:

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
    loggerFactory.AddConsole(Configuration.GetSection("Logging"));
    loggerFactory.AddDebug();

    app.Use(async (ctx, next) =>
        {
            try
            {
                await next();
            }
            catch (Exception ex)
            {
                // handle exception here
            }
        });

    app.UseApplicationInsightsRequestTelemetry();
    app.UseApplicationInsightsExceptionTelemetry();
    app.UseMvc();
}

发生路由错误时,似乎都没有调用上述任何一项。我采取了错误的做法吗?或者其中一种方法是否真的有效?

任何建议都会非常感激。

由于

克里斯

PS。我是ASP.NET Web API的新手,所以请原谅我可能会使用错误的术语。

1 个答案:

答案 0 :(得分:4)

您可以使用UseStatusCodePages扩展方法:

 app.UseStatusCodePages(new StatusCodePagesOptions()
 {
     HandleAsync = (ctx) =>
     {
          if (ctx.HttpContext.Response.StatusCode == 404)
          {
               //handle
          }

          return Task.FromResult(0);
     }
 });

修改

 app.UseExceptionHandler(options =>
 {
       options.Run( async context =>
       {
             var ex = context.Features.Get<IExceptionHandlerFeature>();
             // handle
             await Task.FromResult(0);
       });
 });
 app.UseStatusCodePages(new StatusCodePagesOptions()
 {
     HandleAsync = (ctx) =>
     {
          if (ctx.HttpContext.Response.StatusCode == 404)
          {
               // throw new YourException("<message>");
          }

          return Task.FromResult(0);
     }
 });