在ASP.NET MVC中,通過應(yīng)用程序生命周期中的Application_Error事件可以捕獲到網(wǎng)站引發(fā)的所有未處理異常,。本文作為學(xué)習(xí)筆記,,記錄了使用Global.asax文件的Application_Error事件處理和捕獲全局異常的詳細步驟,。 文章演示項目是使用vs2013編譯器編寫的,下載地址:GlobalExceptionHandle-By-Application_Error.zip,。 在VS2013中新建一個MVC項目,,這里要先關(guān)閉自定義錯誤,將Web.config配置文件中customErrors節(jié)點的mode設(shè)置為Off,,注意大小寫:
在GlobalFilter全局過濾器中取消HandleErrorAttribute的注冊:
打開Global.asax文件并添加Application_Error事件代碼:
從上面的演示代碼可以看出,,在Application_Error事件中可以通過Server.GetLastError()獲取Exception對象,并依據(jù)Exception對象獲取相關(guān)異常信息,,包括HTTP錯誤碼,、詳細的錯誤信息等等。在事件中可以根據(jù)需求編寫自己的業(yè)務(wù)代碼,,比如記錄日志,、跳轉(zhuǎn)到自定義的錯誤頁面等。 編寫Application_Error事件的代碼需要注意的地方1,、一定要取消GlobalFilter全局過濾器中HandleErrorAttribute的注冊,,也要注意檢查項目中是否有其他全局過濾器對異常進行處理的,防止HTTP 500類型的服務(wù)器錯誤不會觸發(fā)Application_Error事件(其他類型錯誤依然可觸發(fā)),。 此外也可以關(guān)閉Web.config配置文件的自定義錯誤:<customErrors mode="Off"></customErrors>,。因為一般情況下都是在Application_Error事件中處理要跳轉(zhuǎn)的自定義錯誤頁,這樣有利于設(shè)置HTTP錯誤代碼,。 2、無論最終處理的流程如何,,在流程結(jié)束或者響應(yīng)輸出的地方,,一定要調(diào)用Server.ClearError()方法清空異常,否則異常錯誤依然處于未被處理的狀態(tài),,如果customErrors mode="On",,那么異常會被自定義錯誤模塊處理,除非本意就是要使用這種方式跳轉(zhuǎn)到錯誤頁,。 如果已經(jīng)關(guān)閉了自定義錯誤但又沒有調(diào)用ClearError方法,,將會引發(fā)ASP.NET的詳細錯誤頁面(俗稱黃頁)。 3,、如果要跳轉(zhuǎn)到靜態(tài)的自定義錯誤頁面中,,請使用Response.WriteFile(string filename)方法,最后設(shè)置下HTTP狀態(tài)碼,,比如下面的代碼:
4,、如果想要使用Server.Transfer(string path)方法跳轉(zhuǎn)到自定義的錯誤頁面,這里有兩點需要注意: 第一點,、一定不能設(shè)置HTTP狀態(tài)碼(Response.StatusCode),,否則會引發(fā)IIS錯誤,無論是跳轉(zhuǎn)到靜態(tài)還是動態(tài)頁面中,。例如下列代碼:
第二點,、Server.Transfer方法對路由地址不兼容,會引發(fā)錯誤,,下面代碼使用路由會引發(fā)另一個異常:
使用應(yīng)用程序全局錯誤的一些優(yōu)勢:第一點就是兼容性好,,Web Form和MVC中都可以通用,如果舊的Web Form項目中是使用Application_Error處理全局異常,,那么在新的MVC項目就可以很容易移植過來,!此外靈活性也比較高,相比ASP.NET自帶的自定義錯誤以及MVC的HandleError特性,,可以更加自由的編寫靈活的業(yè)務(wù)代碼,。 另外可以根據(jù)需求設(shè)定HTTP錯誤碼,這方面也是考慮到一個SEO的問題,,畢竟ASP.NET的自定義錯誤機智是使用302重寫跳轉(zhuǎn),,并不有利于SEO。雖然customErrors節(jié)點的redirectMode屬性可以設(shè)置為"ResponseRewrite"(重寫),,但是如果在跳轉(zhuǎn)的頁面上不設(shè)置HTTP錯誤碼,,則HTTP狀態(tài)碼為200。 Application_Error處理網(wǎng)站異常的局限性Application_Error事件無法處理已經(jīng)被處理的異常,,比如在try-catch捕捉的異常,。此外由于是應(yīng)用程序級別的事件,所以無法處理操作方法或者控制器級別的異常,暫時我也只想到這些局限,,一般來說只要項目沒有什么特殊要求都可以使用此事件處理自定義異常,。
出處:http:///post/635813858052755170 歡迎轉(zhuǎn)載本文,本文版權(quán)歸作者所有,,轉(zhuǎn)載請聲明出處或保留此段聲明,。^_^請尊重他人勞動成果,共建美好的網(wǎng)絡(luò)環(huán)境。 |
|