【问题标题】:Global exception handling in ASP.NET 5ASP.NET 5 中的全局异常处理
【发布时间】:2015-02-07 18:38:35
【问题描述】:

如何将我自己的日志记录逻辑附加到 ASP.NET 5 应用程序以处理业务逻辑和较低层中引发的每个异常?

我在 Startup.cs 中尝试了自己的 ILoggerProvider 实现和 loggerfactory.AddProvider(new LoggerProvider(Configuration))。但它似乎拦截了内部 ASP.NET 的东西,而不是我在较低层抛出的异常。

【问题讨论】:

  • 您是否希望捕获完全任意的异常?还是最终导致请求失败的异常?如果它试图捕获 all 异常,那实际上是不可能的,因为大多数异常都被系统的某些部分捕获和处理(然后馈送到记录器)。如果您发现某些异常没有被记录,请在github.com/aspnet(例如 MVC 或 XRE)上的相应 repo 中记录错误。
  • 是的,这就是为什么它不起作用的原因,因为我在较低层捕获它们,但是当我临时评论捕获时,只有过滤器方法允许我捕获抛出的异常,我没有在 ILogger 中得到它,这是正常行为吗?如果没有,我可以再试一次(因为我目前已经实现了全局过滤器方法),如果是这样,我可以在 github 上写一下。
  • 是的,如果你捕捉到异常,其他人不会看到它,所以没有什么要记录的。但是您很可能是正确的,还有一些其他组件,例如错误处理中间件,它没有记录异常。可能适用于github.com/aspnet/Diagnostics repo。

标签: asp.net asp.net-core


【解决方案1】:

通过使用两个选项解决了这个问题:

1) ILoggerProvider 从命名空间 Microsoft.Framework.Logging 中实现自己的 ILoggerProvider 和 ILogger 然后将其附加到 MVC 框架中 Startup.cs 添加以下代码:

 public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerfactory)
 {
        loggerfactory.AddProvider(new YourCustomProvider());
 }

但是上面的这个选项,似乎只在 MVC 特定事件、路由相关等上调用 ILogger 的 Write 函数,当我在较低层抛出异常时没有调用它,所以第二个选项解决了:

2) 全局过滤器 在 Startup.cs 中注册自己的 ActionFilterAttribute 实现:

public void ConfigureServices(IServiceCollection services)
{
    services.AddMvc().Configure<MvcOptions>(options =>
    {
        options.Filters.Add(new YourCustomFilter());
    });
}

重要的是,自定义过滤器类实现了 IExceptionFilter 接口:

  public class YourCustomFilter : ActionFilterAttribute, IExceptionFilter
  {
             public void OnException(ExceptionContext context)
             {
              ///logic...
             }
 }

(编辑:) 然后在 Startup 类中添加过滤器:

    public void ConfigureServices(IServiceCollection services)
    {
         services.AddMvc(options =>
            {
                options.Filters.Add(new YourCustomFilter());
            });
    }

【讨论】:

  • 是否可以通过OnException 方法更新响应内容?我可以更新状态码,但我也想更新响应正文,但我不知道如何
  • 是的,可以通过设置提供给 OnException 方法的 ExceptionContext 来实现。例如 context.Result = new RedirectResult... 或 context.Result = new JsonResult....
  • @alekkowalczyk 您好,我按照您的示例进行操作,在第二步中对我有用的语法有点不同。这是我的版本,也许可以帮助别人, services.AddMvc((options => { options.Filters.Add(new CustomFilerForExceptionHandling()); }));
  • 顺便说一句,这段代码没有捕捉到在 Startup.Configure() 期间发生的异常
  • 也许是个愚蠢的问题,但是如何将记录器传递给 YourCustomFilter?
【解决方案2】:

如果您想要一个真正的全局异常陷阱框架,而不仅仅是在控制器级别,请查看我的一个开源项目。我计划在假期后不久将其制成 Nuget 包。我还计划更新我的博客,说明我开发它的原因。

开源项目在github上: https://github.com/aspnet-plus/AspNet.Plus.Infrastructure 看看使用示例。

【讨论】:

    猜你喜欢
    • 2018-10-09
    • 1970-01-01
    • 2016-11-03
    • 1970-01-01
    • 1970-01-01
    • 2019-07-18
    • 2017-02-24
    • 2011-05-20
    • 1970-01-01
    相关资源
    最近更新 更多