【问题标题】:ASP.NET Core Web API: Catching Routing ErrorsASP.NET Core Web API:捕获路由错误
【发布时间】:2017-02-03 15:58:24
【问题描述】:

我正在尝试捕获 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) 中,我添加了:

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 比较陌生,所以请原谅我可能使用了稍微错误的术语。

【问题讨论】:

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


    【解决方案1】:

    你可以使用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);
         }
     });
    

    【讨论】:

    • 谢谢,但如果可能的话,我更愿意捕获异常 - 这可能吗?这里的方法似乎更像是在事件发生后捕获后果,而不是在问题发生时捕获异常。
    • 为什么 404 结果需要例外?
    • 谢谢。就 app.UseExceptionHandler() 方法而言,我尝试了这个(参见原始问题),但它似乎没有被调用。路由错误会调用错误处理程序吗? (开始怀疑路由错误是否会导致异常)。
    • 没有异常就不会被调用,因为 404 没有异常。要使用它,您应该手动抛出异常。查看我的更新。
    • 非常感谢,这就是我正在努力解决的问题。我曾假设路由错误(导致 404)会在请求处理的某个时刻产生异常。所以,基本上,我试图捕捉一个从未存在的异常。再次感谢。
    猜你喜欢
    • 2018-08-28
    • 2018-08-25
    • 2012-04-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-12-19
    • 2014-07-01
    • 2013-12-04
    相关资源
    最近更新 更多