Вопрос по asp.net-mvc-3, exception-handling, custom-error-pages, asp.net-mvc – ExceptionContext.ExceptionHandled изменяется на true. Где обрабатывается исключение?

8

Я использую глобальный фильтр действий для обработки и регистрации всех исключений.

    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 метод выполняется. Как обрабатывается это исключение?

-EDIT- у меня естьcustomErrors раздел вWeb.Config, у меня естьErrorController класс и действия под названиемGeneral а такжеHttp404.

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

What I don't understand is, the controller action General is not executed (breakpoint is never hit), but the value of ExceptionContext.ExceptionHandled is set to true when the OnException method of ElmahHandleErrorAttribute starts executing.

Вы переопределилиOnException метод контроллера? gdoron
@gdoron Я удалил проверку для context.ExceptionHandled. Ранее в заявление было включено:if (!context.IsChildAction && !context.ExceptionHandled && (context.HttpContext.IsCustomErrorEnabled)) escist
@gdoron: нет, я отменяюOnException метод MVCHandleErrorAttribute фильтр. escist
Я не вижуcontext.ExceptionHandled в вашем коде, где это? gdoron

Ваш Ответ

1   ответ
22

в обратном порядке, Это означает, чтоHandleErrorAttribute бежит первым.

Вы можете просмотреть кодHandleErrorAttribute ВотКороче, это:

Only executes if ExceptionHandled is false, and custom errors are enabled. Sets up a redirect to the error view, which by default is called Error. Sets ExceptionHandled to true.

Поскольку это первый фильтр, тоExceptionHandled имеет значение false при выполнении, в результате чего для него устанавливается вид Error и настройкаExceptionHandled к истине. Итак, когда работает ваш собственный фильтр, вот почемуExceptionHandled уже установлен в true. Обратите внимание, что если пользовательские ошибки были отключены, тоExceptionHandled все равно будет ложным, какHandleErrorAttribute не сделал бы свое дело. В этом случае ELMAH все равно зарегистрирует ошибку, поскольку она необработана (желтый экран смерти), поэтому тест в вашем классе должен предотвратить повторное ведение журнала ошибки.

Теперь к вашему другому вопросу о сывороткеGeneral действие не выполнено,defaultRedirect используется только в том случае, если фильтры сами не устанавливают какое-либо явное перенаправление, поэтому оно фактически игнорируется, когда в ActionMethod возникает исключение, и у вас есть глобальный фильтрHandleErrorAttribute зарегистрировано. Однако он вызывается, если вы ввели URL, который не существует, то есть ошибка, которая не возникает из ActionMethod. Кроме того, если вы закомментируете строку для регистрацииHandleErrorAttribute в Global.asax.cs, вы всегда получитеGeneral выполнение действия контроллера.

Я указал заказы при регистрации фильтров. Теперь мой пользовательский фильтрElmahHandleErrorAttribute сначала обрабатывает ошибку По вашему вопросуNot sure why you would want the ELMAH one to run first thoughКак вы думаете, это плохая идея? Я делаю это, потому что хочу отобразить пользовательские страницы ошибок, проверить тип ошибки и отобразить конкретное представление. escist
Спасибо за ваше объяснение. Это действительно помогло мне. Я хочу, чтобы ElmahHandleErrorAttribute был первым фильтром, который выполняется. Будет ли установка порядка этого пользовательского фильтра исправить это? Согласно этому комментарию (stackoverflow.com/a/9163926/1242061) Я должен дать более высокое значение Order фильтру, который я хочу выполнить первым. escist
Я думаю, я должен избавиться отHandleErrorAttribute, ОбычайElmahHandleErrorAttribute будет отображать вид. Так как я определил Application_Error () вglobal.asax для обработки 404 и других необработанных исключений, я не думаю, что будет отображаться YSOD. escist
Да, я подозреваю, что вы можете поэкспериментировать со свойством Order (но не знаете, как это сделать в глобальном фильтре, это можно сделать только при использовании его в качестве атрибута). Простое изменение порядка добавления фильтров в RegisterGlobalFilters должно сработать ... при возникновении ошибки последний, добавленный последним, запускается первым. Не уверен, почему вы хотите, чтобы ELMAH запускал первым, и если вы действительно это делаете, вы не можете проверить ExceptionHandled, так как в этом случае он всегда будет ложным.
При условии, что представление ELMAH всегда будет отображать представление, тогда да, я думаю, что это нормально. Однако, если вы оставите значение по умолчаниюHandleErrorAttribute обработать запасной вариант, еслиit также не устанавливается представление, затем происходит YSOD, и вы потенциально можете получить ELMAH, регистрирующую ошибку дважды (один раз в глобальном фильтре и один раз, когда исключение не помечено как обработанное). Если вы настраиваете представления в своем фильтре ELMAH, то, возможно, вам следует избавиться отHandleErrorAttribute вообще?

Похожие вопросы