ASP.NET 在處理和響應錯誤的方式上進行了若干改進。在傳統的 ASP 中,是用"On Error Resume Next"(或在 Jscript 中用 try-catch 塊)處理錯誤的。或者,如果您啟動並執行是 Microsoft Internet Information Services (IIS) 5.0,則使用 ASPError 對象建立自訂的錯誤報表頁。然而,這些方法都有其局限性。
ASP.NET 提供了在運行 ASP.NET 應用程式時可能出現的錯誤的若干處理和響應層級。ASP.NET 提供三種用於在出現錯誤時捕獲和響應錯誤的主要方法:Page_Error 事件、Application_Error 事件以及應用程式設定檔 (Web.config)。
本文示範如何在 ASP.NET 應用程式中使用這些新功能。儘管本文由於與 ASP.NET 直接相關而介紹了如何提供自訂錯誤頁和一般錯誤報表,但是它並不介紹其他錯誤處理方法,如 try-catch-finally 塊和公用語言運行庫 (CLR) 異常系統。
如何使用 Page_Error 事件
Page_Error 事件提供一種捕獲在頁層級出現的錯誤的方法。您可以只是顯示錯誤資訊(正如下面的範例程式碼所示),也可以記錄事件或執行某個其他動作。
備忘:此樣本在瀏覽器中顯示詳細的錯誤資訊,提供此樣本只是為了進行說明。嚮應用程式的終端使用者顯示詳細資料(尤其是該應用程式在 Internet 上運行時)一定要小心。更適當的做法是向使用者顯示一條訊息,告知已發生錯誤,然後將具體的錯誤詳細資料記錄在事件記錄中。
本樣本引發一個強迫錯誤發生在 Page_Load 事件中的空異常。按照以下步驟可建立將測試 Page_Error 事件的初始頁。 1. 按照以下步驟將名為 PageEvent.aspx 的新檔案添加到項目中: a. 開啟 Microsoft Visual Studio .NET。
b. 在"方案總管"中,按右鍵該項目節點,指向添加,然後單擊添加 Web Form。
c. 在名稱文字框中,鍵入 PageEvent.aspx,然後單擊開啟。
2. 將以下代碼添加到 PageEvent.aspx 中:
<script language=C# runat="server">
void Page_Load(object sender, System.EventArgs e)
{
throw(new ArgumentNullException());
}
public void Page_Error(object sender,EventArgs e)
{
Exception objErr = Server.GetLastError().GetBaseException();
string err = "<b>Error Caught in Page_Error event</b><hr><br>" +
"<br><b>Error in:</b>" + Request.Url.ToString() +
"<br><b>Error Message:</b>" + objErr.Message.ToString()+
"<br><b>Stack Trace:</b><br>" +
objErr.StackTrace.ToString();
Response.Write(err.ToString());
Server.ClearError();
}
</script>
3. 從檔案菜單中,單擊儲存 PageEvent.aspx。
4. 按右鍵該頁,然後單擊在瀏覽器中查看以運行該頁。請注意,將按照代碼規範引發和報告錯誤。
備忘:您可能注意到代碼發出對 Server.ClearError 的調用。這將防止錯誤繼續到要被處理的 Application_Error 事件中。
此外,您還應記下 @ Page 指令中的 Inherits 屬性。如果已經設定 Inherits,則必須首先產生項目,然後再瀏覽到該頁。如果不首先產生項目,將看到下面的錯誤資訊: 'Project.PageEvent' is not a valid type
如何使用 Application_Error 事件
與 Page_Error 事件相類似,您可使用 Application_Error 事件捕獲發生在應用程式中的錯誤。由於事件發生在整個應用程式範圍內,因此您可記錄應用程式的錯誤資訊或處理其他可能發生的應用程式層級的錯誤。
下面的樣本基於前面的 Page_Error 事件程式碼範例,如果 Page_Load 事件中的錯誤未在 Page_Error 事件中捕獲,將引發異常。Application_Error 事件在應用程式的 Global.asax 檔案中進行指定。為簡單起見,本節中的步驟建立一個要在其中引發異常的新頁,捕獲 Global.asax 檔案的 Application_Error 事件中的錯誤,並將該錯誤寫入事件記錄中。下面的步驟示範如何使用 Application_Error 事件: 1. 將名為 AppEvent.aspx 的新檔案添加到項目中:
2. 將以下代碼添加到 AppEvent.aspx 中:
<script language=C# runat="server">
void Page_Load(object sender, System.EventArgs e)
{
throw(new ArgumentNullException());
}
</script>
3. 從檔案菜單中,單擊儲存 AppEvent.aspx。
4. 將 Application_Error 事件添加到 Global.asax 檔案中以捕獲在 AppEvent.aspx 頁的 Page_Load 事件中引發的錯誤。注意,您必須為 System.Diagnostics 名稱空間將另一條 using 語句添加到 Global.asax,才能使用事件記錄。
將以下代碼添加到 Global.asax 檔案中:
using System.Diagnostics;
protected void Application_Error(object sender, EventArgs e)
{
Exception objErr = Server.GetLastError().GetBaseException();
string err = "Error Caught in Application_Error event\n" +
"Error in:" + Request.Url.ToString() +
"\nError Message:"+ objErr.Message.ToString() +
"\nStack Trace:"+ objErr.StackTrace.ToString();
EventLog.WriteEntry("Sample_WebApp",err,EventLogEntryType.Error);
Server.ClearError();
//additional actions...
}
5. 儲存 Global.asax 檔案。
6. 在 Visual Studio .NET 中,在產生菜單上,單擊產生。
7. 按右鍵該頁,然後單擊在瀏覽器中查看。在這種情況下該頁將為空白,但是您應該注意到在事件記錄中已添加了一個新項。本樣本在應用程式記錄檔中產生一個項,可從事件檢視器訪問應用程式記錄檔。在記錄錯誤之後,您可能希望將使用者重新導向到另一個更方便使用的錯誤頁或者根據需要執行一些其他動作。
如何使用 Web.config 檔案
如果您不調用 Server.ClearError 或者捕獲 Page_Error 或 Application_Error 事件中的錯誤,則將根據 Web.config 檔案的 <customErrors> 部分中的設定處理錯誤。在 <customErrors> 部分,可將重新導向頁指定為預設的錯誤頁 (defaultRedirect) 或者根據引發的 HTTP 錯誤碼指定特定頁。您可使用此方法自訂使用者收到的錯誤資訊。
如果發生在應用程式以前的任一層級都未捕獲到的錯誤,則顯示這個自訂頁。本節示範如何修改 Global.asax 檔案,以便從不調用 Server.ClearError。因此,錯誤在作為捕獲錯誤的最後一點的 Web.config 檔案中進行處理。 1. 從上一個樣本中開啟 Global.asax 檔案。
2. 將 Server.ClearError 行注釋掉,以便確保錯誤出現在 Web.config 檔案中。
3. 將所作更改儲存到 Global.asax 中。代碼看起來應類似如下形式:
using System.Diagnostics;
protected void Application_Error(object sender, EventArgs e)
{
Exception objErr = Server.GetLastError().GetBaseException();
string err = "Error Caught in Application_Error event\n" +
"Error in:" + Request.Url.ToString() +
"\nError Message:"+ objErr.Message.ToString() +
"\nStack Trace:"+ objErr.StackTrace.ToString();
EventLog.WriteEntry("Sample_WebApp",err,EventLogEntryType.Error);
//Server.ClearError();
//additional actions...
}
4. 將以下代碼添加到 <customErrors> 部分,以便將使用者重新導向到自訂頁:
<customErrors defaultRedirect="http://hostName/applicationName/errorStatus.htm" mode="On">
</customErrors>
備忘:必須修改 defaultRedirect 屬性中的檔案路徑,以便它引用相關的 Web 服務器和應用程式名稱。
5. 因為在此層級捕獲的錯誤會發送到預設的錯誤頁,所以,必須建立一個名為 ErrorStatus.htm 的錯誤頁。請記住,您要使用此方法來控制向使用者呈現的內容,因此本樣本使用 .htm 頁作為錯誤頁。將以下代碼添加到 ErrorStatus.htm 中:
<HTML>
<HEAD>
<TITLE></TITLE>
<META NAME="GENERATOR" Content="Microsoft Visual Studio 7.0">
</HEAD>
<BODY>
<b>Custom Error page!</b>
<br>
You have been redirected here from the <customErrors> section of the
Web.config file.
</BODY>
</HTML>
6. 若要測試該代碼,請儲存這些檔案,產生項目,然後在瀏覽器中查看 AppEvent.aspx。請注意,在引發錯誤時,您將被重新導向到 ErrorStatus.htm 頁。
儘管您可在 <customErrors> 部分中 defaultRedirect 屬性的值中引用預設的錯誤頁,但是您還可根據引發的 HTTP 錯誤碼指定要重新導向到的特定頁。<error> 子項目允許使用此選項。例如:
<customErrors defaultRedirect="http://hostName/applicationName/errorStatus.htm" mode="On">
<error statusCode="404" redirect="filenotfound.htm" />
</customErrors>
備忘:在 <customErrors> 部分的 defaultRedirect 中指定的頁是一個 .htm 檔案。如果您打算在 .aspx 頁中使用 GetLastError (正如 Page_Error 和 Application_Error 樣本那樣),則在進行重新導向之前,必須將異常儲存在會話變數或某個其他方法中。
請注意,<customErrors> 部分包括設定為 On 的 mode 屬性。mode 屬性用於控制錯誤重新導向發生的方式。例如,如果您正開發應用程式,則很可能希望查看實際的 ASP.NET 錯誤資訊,並且不希望被重新導向到更方便使用的錯誤頁。mode 屬性包括以下設定: • On:未被處理的異常將使用者重新導向到指定的 defaultRedirect 頁。此模式主要用於生產。
• Off:使用者收到異常資訊而不是被重新導向到 defaultRedirect 頁。此模式主要用於開發。
• RemoteOnly:只有在本機電腦上訪問該網站的使用者(通過使用 localhost)才能收到異常資訊。所有其他使用者都被重新導向到 defaultRedirect 頁。此模式主要用於調試。