ASP.NET MVC中註冊Global.asax的Application_Error事件處理全局異常

在ASP.NET MVC中,經過應用程序生命週期中的Application_Error事件能夠捕獲到網站引起的全部未處理異常。本文做爲學習筆記,記錄了使用Global.asax文件的Application_Error事件處理和捕獲全局異常的詳細步驟。html

文章演示項目是使用vs2013編譯器編寫的,下載地址:GlobalExceptionHandle-By-Application_Error.zipweb

ASP.NET MVC全局異常範例項目結構

在VS2013中新建一個MVC項目,這裏要先關閉自定義錯誤,將Web.config配置文件中customErrors節點的mode設置爲Off,注意大小寫:服務器

<system.web> <customErrors mode="Off"></customErrors> <compilation debug="true" targetFramework="4.5"/> <httpRuntime targetFramework="4.5"/> </system.web>

GlobalFilter全局過濾器中取消HandleErrorAttribute的註冊:網絡

public class FilterConfig { public static void RegisterGlobalFilters(GlobalFilterCollection filters) { //filters.Add(new HandleErrorAttribute()); } }

打開Global.asax文件並添加Application_Error事件代碼:mvc

protected void Application_Error(Object sender, EventArgs e) { Exception lastError = Server.GetLastError(); if (lastError != null) { //異常信息 string strExceptionMessage = string.Empty; //對HTTP 404作額外處理,其餘錯誤所有當成500服務器錯誤 HttpException httpError = lastError as HttpException; if (httpError != null) { //獲取錯誤代碼 int httpCode = httpError.GetHttpCode(); strExceptionMessage = httpError.Message; if (httpCode == 400 || httpCode == 404) { Response.StatusCode = 404; //跳轉到指定的靜態404信息頁面,根據需求本身更改URL Response.WriteFile("~/HttpError/404.html"); Server.ClearError(); return; } } strExceptionMessage = lastError.Message; /*----------------------------------------------------- * 此處代碼可根據需求進行日誌記錄,或者處理其餘業務流程 * ---------------------------------------------------*/ /* * 跳轉到指定的http 500錯誤信息頁面 * 跳轉到靜態頁面必定要用Response.WriteFile方法 */ Response.StatusCode = 500; Response.WriteFile("~/HttpError/500.html"); //必定要調用Server.ClearError()不然會觸發錯誤詳情頁(就是黃頁) Server.ClearError(); Server.Transfer("~/HttpError/500.aspx"); } }

從上面的演示代碼能夠看出,在Application_Error事件中能夠經過Server.GetLastError()獲取Exception對象,並依據Exception對象獲取相關異常信息,包括HTTP錯誤碼、詳細的錯誤信息等等。在事件中能夠根據需求編寫本身的業務代碼,好比記錄日誌、跳轉到自定義的錯誤頁面等。app

編寫Application_Error事件的代碼須要注意的地方

一、必定要取消GlobalFilter全局過濾器中HandleErrorAttribute的註冊,也要注意檢查項目中是否有其餘全局過濾器對異常進行處理的,防止HTTP 500類型的服務器錯誤不會觸發Application_Error事件(其餘類型錯誤依然可觸發)。post

此外也能夠關閉Web.config配置文件的自定義錯誤:<customErrors mode="Off"></customErrors>。由於通常狀況下都是在Application_Error事件中處理要跳轉的自定義錯誤頁,這樣有利於設置HTTP錯誤代碼。學習


二、不管最終處理的流程如何,在流程結束或者響應輸出的地方,必定要調用Server.ClearError()方法清空異常,不然異常錯誤依然處於未被處理的狀態,若是customErrors mode="On",那麼異常會被自定義錯誤模塊處理,除非本意就是要使用這種方式跳轉到錯誤頁。網站

若是已經關閉了自定義錯誤但又沒有調用ClearError方法,將會引起ASP.NET的詳細錯誤頁面(俗稱黃頁)。spa


三、若是要跳轉到靜態的自定義錯誤頁面中,請使用Response.WriteFile(string filename)方法,最後設置下HTTP狀態碼,好比下面的代碼:

//跳轉到指定的靜態404信息頁面,根據需求本身更改URL Response.WriteFile("~/HttpError/404.html"); Server.ClearError(); 

四、若是想要使用Server.Transfer(string path)方法跳轉到自定義的錯誤頁面,這裏有兩點須要注意:

第一點、必定不能設置HTTP狀態碼(Response.StatusCode),不然會引起IIS錯誤,不管是跳轉到靜態仍是動態頁面中。例以下列代碼:

//Response.StatusCode = 500; //Server.Transfer("~/HttpError/500.html"); //Server.Transfer("~/HttpError/500.aspx");

第二點、Server.Transfer方法對路由地址不兼容,會引起錯誤,下面代碼使用路由會引起另外一個異常:

Server.Transfer("~/Home/Index");

使用應用程序全局錯誤的一些優點:

第一點就是兼容性好,Web Form和MVC中均可以通用,若是舊的Web Form項目中是使用Application_Error處理全局異常,那麼在新的MVC項目就能夠很容易移植過來!此外靈活性也比較高,相比ASP.NET自帶的自定義錯誤以及MVC的HandleError特性,能夠更加自由的編寫靈活的業務代碼。

另外能夠根據需求設定HTTP錯誤碼,這方面也是考慮到一個SEO的問題,畢竟ASP.NET的自定義錯誤機智是使用302重寫跳轉,並不有利於SEO。雖然customErrors節點的redirectMode屬性能夠設置爲"ResponseRewrite"(重寫),可是若是在跳轉的頁面上不設置HTTP錯誤碼,則HTTP狀態碼爲200。

Application_Error處理網站異常的侷限性

Application_Error事件沒法處理已經被處理的異常,好比在try-catch捕捉的異常。此外因爲是應用程序級別的事件,因此沒法處理操做方法或者控制器級別的異常,暫時我也只想到這些侷限,通常來講只要項目沒有什麼特殊要求均可以使用此事件處理自定義異常。


 

出處:http://shiyousan.com/post/635813858052755170

歡迎轉載本文,本文版權歸做者全部,轉載請聲明出處或保留此段聲明。^_^請尊重他人勞動成果,共建美好的網絡環境。

相關文章
相關標籤/搜索