對Web應用程式來說,發生不可預知的錯誤和異常在所難免,我們必須為Web程式提供錯誤處理機制。當錯誤發生時,我們必須做好兩件事情:一是將錯誤資訊記錄日誌,發郵件通知網站維護人員,方便技術人員對錯誤進行跟蹤處理;二是以友好的方式提示終端使用者頁面發生了錯誤,而不能將未處理的錯誤資訊顯示給使用者。
讓我們想想,ASP.NET為我們提供了幾種錯誤處理機制?如果同時使用他們是不是有一定的優先順序?.NET提供了四種錯誤處理機制,它們有一定的優先順序順序:Page_Error事件 > ErrorPage屬性 > Application_Error事件 > <customErrors>配置項。下面分別介紹這四種錯誤處理機制的用法。
1.Page_Error事件
Page_Error 事件提供一種捕獲在頁層級出現的錯誤的方法。您可以只是顯示錯誤資訊(正如下面的範例程式碼所示),也可以記錄事件或執行某個其他動作。 private void Page_Load(object sender, System.EventArgs e)
{
// Put user code to initialize the page here
throw new Exception("Page Error!");
}
protected void Page_Error(object sender, EventArgs e)
{
Exception objErr = Server.GetLastError().GetBaseException();
Response.Write("Error:" + objErr.Message);
Server.ClearError(); //同樣要注意這句代碼的使用
}
備忘:此樣本在瀏覽器中顯示詳細的錯誤資訊,提供此樣本只是為了進行說明。嚮應用程式的終端使用者顯示詳細資料一定要小心。更適當的做法是向使用者顯示一條訊息,告知已發生錯誤,然後將具體的錯誤詳細資料記錄在日誌中。
2.ErrorPage屬性
你幾乎可以在頁面任何時候設定ErrorPage屬性,從而確定頁面發生錯誤的時候會重新導向至哪個頁面。要讓ErrorPage屬效能夠發揮作用,<customErrors>配置項中的mode屬性必須設為"On"。
this.ErrorPage = "~/ErrorHandling/PageError.html";
如果Page_Error和ErrorPage都存在,當拋出Exception時,頁面執行順序是怎樣的呢?頁面會先執行Page_Error事件處理函數,如果Page_Error()事件中調用函數Server.ClearError()清除異常資訊,則不會跳轉到ErrorPage屬性指定頁面;如果沒有調用Server.ClearError(),Exception資訊會繼續向上拋,頁面會跳轉到ErrorPage指定頁面。這也就證明了優先順序順序:Page_Error事件 > ErrorPage屬性。
3.Application_Error事件
與Page_Error 事件相類似,您可使用Application_Error事件捕獲發生在應用程式中的錯誤。由於事件發生在整個應用程式範圍內,因此您可記錄應用程式的錯誤資訊或處理其他可能發生的應用程式層級的錯誤。在Global.asax檔案中添加如下代碼就OK了。protected void Application_Error(object sender, EventArgs e)
{
Exception ex = Server.GetLastError().GetBaseException();
//實際應用中這裡可以將Exception資訊記Log或是儲存到資料庫中
//還可以將錯誤發郵件給網站維護人員
Response.Write("Error:" + ex.Message);
//清除Exception,避免繼續傳遞給上一級處理
//這裡上級就是<CustomerErrors>配置節了
Server.ClearError();
}
4.<customErrors>配置項
設定檔web.config中的<customErrors> 配置節,可將重新導向頁指定為預設的錯誤頁defaultRedirect或者根據引發的 HTTP 錯誤碼指定特定頁。如果發生在應用程式以前的任一層級都未捕獲到的錯誤,則顯示這個自訂頁。<customErrors mode="On" defaultRedirect="~/ErrorHandling/ApplicationError.html">
<error statusCode="404" redirect="~/ErrorHandling/404.html" />
</customErrors>
同樣,如果Application_Error和<customerErrors>同時存在,也存在執行順序的問題。因為優先順序Application_Error事件 > <customErrors>配置項,所以發生應用程式級錯誤時,優先執行Application_Error事件中的代碼,如果Application_Error事件中調用了Server.ClearError()函數,<customerErrors>配置節中的defaultRedirect不起作用,因為Exception已經被清除;如果Application_Error事件中沒用調用了Server.ClearError()函數,錯誤頁會重新置放到defaultRedict指定的URL頁面,為使用者顯示友好出錯資訊。
通過對.NET提供的以上四種錯誤處理機制的分析,我們可以把它們從不同的角度分類,便於我們理解和使用。
1.從功能上分類:用於異常處理(Handling exceptions)是Page_Error事件和Application_Error事件;使用者錯誤頁面重新導向(Redirecting the user to an error page)的是 ErrorPage屬性 和 <customErrors>配置項。
2.從錯誤處理的範圍分類:用於頁面級(Page level)錯誤處理的是Page_Error事件 和 ErrorPage屬性;用於應用程式級(Application level)錯誤處理的是Application_Error事件 和 <customErrors>配置項。
參考資料:ASP.NET的錯誤處理機制,在 ASP.NET 中建立自訂的錯誤報表頁,Error Handling in ASP.NET
原始碼: 點擊下載完整樣本程式 (樣本路徑:/ErrorHandling 目錄)