8

我正在使用全局操作篩選器來處理和記錄所有異常。ExceptionContext.ExceptionHandled更改爲true。在哪裏處理異常?

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值爲true的OnException方法執行時。 這個異常是如何處理的?

CNC中 我在Web.Config一個customErrors部分。我有一個ErrorController課程,以及名爲GeneralHttp404的操作。

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

我不明白的是,不執行控制器動作General(斷點從不打),但ExceptionContext.ExceptionHandled值時的ElmahHandleErrorAttribute開始的OnException方法執行設置爲true。

+0

我在代碼中看不到'context.ExceptionHandled',它在哪裏? – gdoron

+0

@gdoron我刪除了關於context.ExceptionHandled的檢查。它早先包含在聲明中:'if(!context.IsChildAction &&!context.ExceptionHandled &&(context.HttpContext.IsCustomErrorEnabled))' – escist

+0

您是否覆蓋了控制器的'OnException'方法? – gdoron

回答

19

當發生異常時,全局過濾器的順序執行in reverse order。這意味着HandleErrorAttribute首先運行。

您可以查看HandleErrorAttributehere的代碼,但在短期,它:

  1. 只有ExceptionHandled是假的,並啓用自定義錯誤執行。
  2. 設置重定向到錯誤視圖,該視圖默認爲Error
  3. ExceptionHandled設置爲true。

,因爲它是第一個過濾器,然後ExceptionHandled是假的,當它執行,導致它設置爲Error視圖,設置ExceptionHandled爲true。那麼,當您自己的過濾器執行時,這就是爲什麼ExceptionHandled已被設置爲true。請注意,如果自定義錯誤被禁用,那麼ExceptionHandled仍然是錯誤的,因爲HandleErrorAttribute不會完成它的工作。在這種情況下,ELMAH將記錄錯誤,因爲它未被處理(死亡的黃色屏幕),所以您班級的測試是爲了防止重複記錄錯誤。現在

,對您關於乳清等問題,不執行General動作,defaultRedirect僅使用,如果過濾器沒有設置一些明確的重定向自己,所以當發生異常的ActionMethod和內部發生這實際上忽略您已註冊全球過濾器HandleErrorAttribute。然而,如果你輸入了一個不存在的URL,也就是在ActionMethod中沒有發生的錯誤,它會被調用。另外,如果您註釋掉在Global.asax.cs中註冊HandleErrorAttribute的行,那麼您將始終執行General控制器操作。

+0

謝謝你的解釋。它真的幫助了我。我想讓ElmahHandleErrorAttribute成爲第一個執行的過濾器。將設置這個自定義過濾器的順序解決這個問題?根據此評論(http://stackoverflow.com/a/9163926/1242061),我應該給予我想要先執行的過濾器更高的Order值。 – escist

+1

是的,我懷疑你可以玩弄Order屬性(但不知道在全局過濾器上該如何做,只有在將它用作屬性時才這樣做)。 簡單地顛倒您在RegisterGlobalFilters中添加過濾器的順序應該可行......當發生錯誤時,最後添加的那個將首先運行。 不知道爲什麼你會希望ELMAH先運行,如果你真的這麼做,你不能檢查ExceptionHandled,因爲在這種情況下它總是會是錯誤的。 –

+0

我在註冊過濾器時指定了訂單。現在我的自定義過濾器ElmahHandleErrorAttribute正在處理錯誤。關於你的問題_不確定你爲什麼希望ELMAH之一先運行_,你認爲這是一個壞主意嗎?我這樣做是因爲我想顯示自定義錯誤頁面並檢查錯誤類型並顯示特定視圖。 – escist