在一个MVC3 Web应用程序中,我正在使用
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
filters.Add(new HandleErrorAttribute());
}
如果发生未处理的异常,则在向用户显示“错误” View 的地方应用全局错误处理。
对于一个特定的 View ,如果通过用
[HandleError(View = "SpecialError")]
装饰方法而发生未处理的异常,我还希望显示不同的错误 View 。这很好。然后,我想添加未处理异常的全局日志记录。我用日志代码创建了一个自定义的HandleError属性:
public class MyHandleErrorAttribute : HandleErrorAttribute
{
public override void OnException(ExceptionContext context)
{
// Write to log code
base.OnException(context);
}
}
并更新了RegisterGlobalFilters和方法修饰以改为使用此属性名称。这通常可以正常工作,但是当在用
MyHandleError(View = "SpecialError")]
装饰的方法中发生异常时,OnException方法将被调用两次。我最初以为用此属性装饰方法取代了全局处理程序,但似乎只是将它添加到了(这更有意义,但这不是我想要的)。通过两次调用OnException,相同的异常将被记录两次,这一定不会发生。我不认为OnException被调用两次是因为它是一个自定义属性-我相信这也发生在标准HandleError属性中,在我创建它的记录时它现在就可见了。最终,我想记录所有未处理的异常(一次),同时保留[HandleError]提供的功能,特别是为特定的方法异常设置不同的 View 。有没有一种干净的方法可以做到这一点?
最佳答案
我相信我自己找到了一个干净的解决方案。扩展HandleError似乎是一个好主意,但现在我认为这是朝错误方向迈出的一步。我不想以不同的方式处理任何错误,只需编写异常以在HandleError拾取它们之前记录一次即可。因此,默认的HandleError可以保持原样。尽管可以多次调用OnException,但在HandleErrorAttribute的标准实现中,它似乎完全是良性的。
相反,我创建了一个异常日志记录过滤器:
public class LoggedExceptionFilter : IExceptionFilter
{
public void OnException(ExceptionContext filterContext)
{
// logging code
}
}
它不需要从
FilterAttribute
继承,因为它只是在HandleErrorAttribute旁边的RegisterGlobalFilters中注册了一次。 public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
filters.Add(new LoggedExceptionFilter());
filters.Add(new HandleErrorAttribute());
}
这样就可以在不更改标准
[HandleError]
功能的情况下将异常整齐地记录下来关于asp.net - 使用全局日志记录时,MVC [HandleError] HandleErrorAttribute调用了两次,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/11449895/