ASP.NET中對Exception的統一集中處理常見的有兩種方式:
1、通過配置Web.config的customErrors節點,配置defaultRedirect屬性來實現所有“未處理的異常”均跳轉向同一頁面
2、通過Global.asax中的Application_Error寫代碼實現自己想要的操作
但在實際使用當中,往往會出現一些問題,比如Application_Error中的代碼未被執行,若使用customErrors那麼如何傳遞錯誤資訊給目標頁面等等。
通過我的摸索,總結出一些經驗,記錄如下:
1、不想通過配置Web.config中customErrors的方法進行頁面跳轉,而是希望在Application_Error中寫代碼進行一些處理然後用Response.Redirect方法跳轉到指定頁面,這種理論上很不錯的方法實際上行不通!Application_Error中寫Response.Redirect來跳轉頁面不會執行!
2、很多人不想使用配置Web.config實現出錯自動跳轉的原因無非是:跳轉到了一個“死”連結,無法傳遞當前的錯誤資訊過去,也就沒辦法進行相應的處理!其實這是一個誤解,任何一個aspx網頁都可以使用Server.GetLastError()獲得最後一個異常,也可以使用this.Context.AllErrors獲得全部的未處理異常,你配置的頁面當然也可以,只要他是一個aspx頁面就行。
//獲得最近一個ExceptionException ex = this.Context.Server.GetLastError();//獲得所有未處理的Exception集Exception[] errors = this.Context.AllErrors;//然後你可以對他們進行處理了
3、網上有人推薦使用Web.config和Application_Error結合的方式來處理異常可以嗎?當然可以!但個人感覺這不是個好主意,因為沒啥必要。
我們看一下他們會怎麼幹:
Web.config
<customErrors mode="On" defaultRedirect="Error.aspx">
Global.asax
protected void Application_Error(object sender, EventArgs e) { //獲得最後一個Exception Exception ex = this.Context.Server.GetLastError(); //然後進行一系列處理,寫檔案日誌,寫資料庫都行 //清除掉Exception,OK啦 this.Context.Server.ClearError(); }
Error.aspx
protected void Page_Load(object sender, EventArgs e){ //輸出期望的錯誤頁面}
這樣看起來沒問題吧,其實問題大了!你會發現它根本就不往Error.aspx頁面跳轉!為什嗎?因為Application_Error的處理優先順序高於Web.config裡面配置的自訂錯誤處理頁面,你在Application_Error裡面已經把所有該做的都做了,然後還把Error給Clear掉了,此時已經不會再觸發Web.config裡面配置的自動跳轉了!
有人會說了,那我在Application_Error裡面處理完之後不執行那個ClearError(),他不就跳轉過去了嗎?沒錯!這樣一定是可以跳轉的,而且你甚至可以在Error.aspx裡面把這個錯誤再取出來一次,然後根據錯誤類型給使用者一個“友好的”錯誤提示,最後別忘了再執行ClearError。這樣是可以達到目的的,可是我真的覺得沒必要,為什麼沒必要,看下面。
4、之所以有人採取3中的做法,無非是考慮到既想進行相應的錯誤捕捉處理,又想給使用者一個“友好的”自訂介面。要達到這樣的效果並不一定非得把兩個結合起來,使用任意一種方法都能做到:
A、先看使用Web.config配置的方法:
Web.config
<customErrors mode="On" defaultRedirect="Error.aspx">
Error.aspx
protected void Page_Load(object sender, EventArgs e){
//獲得最近一個ExceptionException ex = this.Context.Server.GetLastError();//然後你可以對他們進行處理了
}
B、使用Application_Error處理
Global.asax
protected void Application_Error(object sender, EventArgs e) { //擷取Exception Exception ex = this.Context.Server.GetLastError(); //處理Exception //清除當前的輸出 this.Context.Response.Clear(); //轉向執行你希望展示給使用者看的錯誤提示頁面樣子(此時網址依然是出錯的那個頁面,但是展示的內容就完全是你自己指定的頁面了) this.Context.Server.Transfer("/Error.aspx");
//如果非要跳轉到目標頁面(即地址欄也改變成Error.aspx的話)也不是不行,可以變通處理
this.Context.Response.Write("<script>top.location.href='/Error.aspx';</script>"); }