ExceptionContext.ExceptionHandled更改为true.处理例外的地方在哪里?

esc*_*ist 8 asp.net-mvc exception-handling custom-error-pages asp.net-mvc-3

我正在使用全局操作过滤器来处理和记录所有异常.

    public static void RegisterGlobalFilters(GlobalFilterCollection filters)
    {
        filters.Add(new ElmahHandleErrorAttribute());
        filters.Add(new HandleErrorAttribute());
    }
Run Code Online (Sandbox Code Playgroud)

这是全局动作过滤器ElmahHandleErrorAttribute的定义方式 - 它会覆盖该OnException方法.

public class ElmahHandleErrorAttribute : System.Web.Mvc.HandleErrorAttribute
{
    public override void OnException(ExceptionContext context)
    {
       //Is the exception handled already? context.ExceptionHandled seems to be true here
        if (!context.IsChildAction && (context.HttpContext.IsCustomErrorEnabled))
        {
            //Do other stuff stuff
            //Log to Elmah               
        }
    }
   ...
 }
Run Code Online (Sandbox Code Playgroud)

我不明白为什么方法执行context.ExceptionHandled时值为true OnException.如何处理此异常?

-EDIT- 我有一customErrorsWeb.Config.我有一个ErrorController班级和行动叫做GeneralHttp404.

<customErrors mode ="On" defaultRedirect="Error/General">
      <error statusCode="404" redirect="Error/Http404"/>
  </customErrors>
Run Code Online (Sandbox Code Playgroud)

我不明白的是,控制器操作General没有执行(断点永远不会被命中),但是ExceptionContext.ExceptionHandled当开始执行的OnException方法时,值设置为true ElmahHandleErrorAttribute.

Ric*_*ett 22

发生异常时,全局过滤器的顺序以相反的顺序执行.这意味着HandleErrorAttribute首先运行.

您可以查看HandleErrorAttribute 此处的代码,但简而言之,它:

  1. 仅在ExceptionHandledfalse为false时执行,并且启用自定义错误.
  2. 设置重定向到错误视图,默认情况下会调用该视图Error.
  3. 设置ExceptionHandled为true.

因为它是第一个过滤器,ExceptionHandled所以在执行时它是假的,导致它将视图设置ExceptionHandled为Error并设置为true.那么,当你自己的过滤器执行时,这就是为什么ExceptionHandled已经设置为true.请注意,如果自定义错误被禁用,那么ExceptionHandled仍然是假的,因为HandleErrorAttribute它不会做它的东西.在这种情况下,ELMAH无论如何都会记录错误,因为它是未处理的(黄色死亡屏幕),因此您班级中的测试是为了防止重复记录错误.

现在,关于乳清General未执行操作的另一个问题,defaultRedirect仅在过滤器本身未设置某些显式重定向时使用,因此当ActionMethod内发生异常并且您HandleErrorAttribute注册了全局过滤器时,它实际上被忽略.但是,如果您输入的URL不存在,则会调用它,即在ActionMethod中不会发生错误.此外,如果您注释掉HandleErrorAttribute在Global.asax.cs中注册的行,那么您将始终General执行控制器操作.