在一个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/

10-13 07:08