背景:使用 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()
{
}
}
}
这是创建记录器的工厂.它只会被实例化一次,并在通过管道时创建所有记录器.
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
,它就会在管道中的每个请求上被调用.通常这是通过自定义扩展方法完成的,但我们已经有了很多新代码,所以我将省略这部分.
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 错误未被异常过滤器捕获的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!