ASP.NET Core MVC(前 MVC 6)Razor 错误未被异常过滤器捕获 [英] ASP.NET Core MVC (former MVC 6) Razor errors not getting caught by exception filter

查看:18
本文介绍了ASP.NET Core MVC(前 MVC 6)Razor 错误未被异常过滤器捕获的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

背景:使用 Dapper 和存储库模式的 ASP.NET 5 (ASP.NET Core 1.0) MVC 6 应用程序

Background: ASP.NET 5 (ASP.NET Core 1.0) MVC 6 application using Dapper and the Repository Pattern

显然,与其他所有网站/应用程序一样,我正在尝试消除我网站中弹出的大多数/所有异常.

Obviously, like with every other website/app, I'm trying to eliminate most/all of the exceptions that popup in my website.

我实现了一个 ExceptionFilter 来捕获所有未处理的异常,如下所示:

I implemented an ExceptionFilter in order to catch all unhandled exceptions like this:

public class UnhandledExceptionFilter : ActionFilterAttribute, IExceptionFilter
{
    private readonly IErrorRepo _errorRepo;

    public UnhandledExceptionFilter(IErrorRepo errorRepo)
    {
        _errorRepo = errorRepo;
    }

    public void OnException(ExceptionContext context)
    {
        try
        {
            _errorRepo.SaveException(context.Exception);
        }
        catch { }
    }
}

当错误来自 C# 代码时,这很有效.但是我故意在我的 razor 视图(cshtml 文件)中添加了错误,而这些错误并没有被这个过滤器捕获.

This works great when the error comes from C# code. But I've purposely put in errors in my razor views (cshtml files) and those are NOT getting caught by this filter.

是否需要继承其他属性/接口才能捕获 razor 异常?

Is there an additional attribute/interface that I need to inherit in order to catch razor exceptions?

更新:

这里是指定过滤器属性的地方,在configureServices方法的startup.cs文件中.

Here's where the filter attribute is specified, in the startup.cs file in the ConfigureServices method.

    services.AddMvc(options =>
    {
        options.Filters.Add(new UnhandledExceptionFilter(new ErrorRepo(Configuration)));
    });

推荐答案

这样做的诀窍不在于属性 - 它是通过添加中间件提供程序.一旦您的中间件在管道中,您将能够捕获任何时候抛出的异常(因此不再需要您的属性).

The trick to doing this is not in the attribute - it's by adding a middleware provider. Once your middleware is in the pipeline, you'll be able to catch exceptions thrown at any point (so your attribute will no longer be needed).

这实际上是要记录错误的东西.我已经复制了我从您的 IErrorRepo 界面中看到的内容,但是您当然可以对其进行修改以包含传递到下面的 Log 方法中的任何附加信息.

This is the thing that's actually going to log errors. I've copied what I've seen from your IErrorRepo interface, but of course you could modify it to include any of the additional information passed into the Log method below.

public class UnhandledExceptionLogger : ILogger
{
    private readonly IErrorRepo _repo;

    public UnhandledExceptionLogger(IErrorRepo repo)
    {
        _repo = repo;
    }
    public IDisposable BeginScopeImpl(object state) =>
        new NoOpDisposable();

    public bool IsEnabled(LogLevel logLevel) =>
        logLevel == LogLevel.Critical || logLevel == LogLevel.Error;

    public void Log(LogLevel logLevel, int eventId, object state, Exception exception, Func<object, Exception, string> formatter)
    {
        if (IsEnabled(logLevel))
        {
            _repo.SaveException(exception);
        }
    }

    private sealed class NoOpDisposable : IDisposable
    {
        public void Dispose()
        {
        }
    }
}

提供者

这是创建记录器的工厂.它只会被实例化一次,并在通过管道时创建所有记录器.

The Provider

This is the factory that will create the logger. It's only going to be instantiated once, and will create all the loggers when it goes through the pipeline.

public class UnhandledExceptionLoggerProvider : ILoggerProvider
{
    private readonly IErrorRepo _repo;

    public UnhandledExceptionLoggerProvider(IErrorRepo repo)
    {
        _repo = repo;
    }

    public ILogger CreateLogger(string categoryName) =>
        new UnhandledExceptionLogger(_repo);

    public void Dispose()
    {
    }
}

注册提供者

一旦添加到 ILoggerFactory,它就会在管道中的每个请求上被调用.通常这是通过自定义扩展方法完成的,但我们已经有了很多新代码,所以我将省略这部分.

Registering the Provider

Once added to the ILoggerFactory, it will be invoked on each request in the pipeline. Often this is done through a custom extension method, but we've already got a lot of new code so I'll omit that part.

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
    loggerFactory.AddProvider(new UnhandledExceptionLoggerProvider(new ErrorRepo()));
    // the rest

这篇关于ASP.NET Core MVC(前 MVC 6)Razor 错误未被异常过滤器捕获的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆