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

时间:2012-05-15 09:06:35

标签: asp.net-mvc asp.net-mvc-3 exception-handling custom-error-pages

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

    public static void RegisterGlobalFilters(GlobalFilterCollection filters)
    {
        filters.Add(new ElmahHandleErrorAttribute());
        filters.Add(new HandleErrorAttribute());
    }

这是全局操作过滤器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               
        }
    }
   ...
 }

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

- 编辑 - 我在customErrors中有一个Web.Config部分。我有一个ErrorController类,以及名为GeneralHttp404的操作。

<customErrors mode ="On" defaultRedirect="Error/General">
      <error statusCode="404" redirect="Error/Http404"/>
  </customErrors>

我不明白的是,控制器操作General未执行(断点永远不会被命中),但ExceptionContext.ExceptionHandled的值设置为真{{1 OnException的方法开始执行。

1 个答案:

答案 0 :(得分:22)

发生异常时,全局过滤器的顺序将执行in reverse order。这意味着HandleErrorAttribute首先运行。

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

  1. 仅在ExceptionHandled为false且已启用自定义错误时执行。
  2. 设置重定向到错误视图,默认情况下称为Error
  3. ExceptionHandled设置为true。
  4. 由于它是第一个过滤器,因此ExceptionHandled在执行时为false,导致它将视图设置为Error并将ExceptionHandled设置为true。那么,当您自己的过滤器执行时,这就是ExceptionHandled已经设置为true的原因。请注意,如果自定义错误被禁用,则ExceptionHandled仍然是假的,因为HandleErrorAttribute不会完成其中的任务。在这种情况下,ELMAH无论如何都会记录错误,因为它是未处理的(黄色死亡屏幕),因此您班级中的测试是为了防止重复记录错误。

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