文章編號: 306355 - 上次校閱: 2006年12月27日 - 版次: 3.1

HOW TO:使用 Visual C# .NET 在 ASP.NET 中建立自訂錯誤報告網頁

系統提示本文適用於您使用的作業系統之外的作業系統。與您不相關的文章內容已停用。
本文曾發行於 CHT306355

在此頁中

全部展開 | 全部摺疊

結論

本文將告訴您,如何使用 Visual C# .NET 程式碼來截取並回應發生在 ASP.NET 中的錯誤。ASP.NET 已經改進了傳統的 Microsoft Active Server Pages (ASP) 的錯誤處理選項。在 ASP.NET 中,您可以在應用程式的數個不同層級中處理錯誤。

ASP.NET 中的新功能

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 區塊以及 Common Language Runtime (CLR) 例外狀況系統。

如何使用 Page_Error 事件

Page_Error 事件提供了可在網頁層級截取錯誤的方法。您可以只是顯示錯誤資訊 (如下面的程式碼範例一樣),也可以記錄該事件或執行其他動作。

注意 :本範例是為了示範目的所以才在瀏覽器中顯示詳細的錯誤資訊。您在顯示詳細的錯誤資訊給應用程式的使用者知道時應該要謹慎小心,特別是當應用程式是在 Internet 上執行時。比較恰當的作法應該是向使用者顯示訊息以通知錯誤的發生,然後才在事件日誌中實際記錄此特定錯誤的詳細資訊。

本範例會擲回一個 Null 例外狀況,迫使 Page_Load 事件發生錯誤。請遵循下列步驟來建立可測試 Page_Error 事件的初始網頁。
  1. 請遵循下列步驟在專案中加入一個稱為 PageEvent.aspx 的新檔案:
    1. 開啟 Microsoft Visual Studio .NET。
    2. 在 [方案總管] 中,以右鍵按一下專案節點,指向 [加入] ,然後按一下 [加入 Web Form]
    3. [名稱] 文字方塊中,輸入 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 (Project.PageEvent 不是有效的型別)

如何使用 Application_Error 事件

類似 Page_Error 事件,您可以使用 Application_Error 事件來截取發生在應用程式中的錯誤。由於此事件是屬於整個應用程式範圍的事件,所以您可以記錄應用程式錯誤資訊或是處理可能會發生的其他應用程式層級的錯誤。

下面的範例是以上面的 Page_Error 事件程式碼範例為基礎,如果 Page_Error 事件沒有截取 Page_Load 事件中的錯誤,就會引發此程式碼。 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. 在 Global.asax 檔中加入 Application_Error 事件以截取您在 AppEvent.aspx 網頁的 Page_Load 事件中擲回的錯誤。請注意,您必須在 Global.asax 中替 System.Diagnostics 命名空間加入另一個 using 陳述式,才能使用事件日誌。

    在 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 &lt;customErrors&gt; 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 網頁。此模式主要是用於偵錯。

疑難排解

當 ASP.NET 是以預設值安裝在 Windows 2000 與 Windows XP 上時,ASP.NET 會在背景工作處理序中執行 Web 應用程式的程式碼。此處理序的識別的預設值是一個未授權的本機帳戶,稱為 ASPNET 帳戶。在 ASP.NET 的測試版中,此處理序的識別是 System,這是一個有權力的系統管理帳戶,擁有電腦上的許多權限。

如需此項變更與它會如何影響您執行本文中程式碼的詳細資訊,以及可能需要額外存取權的其他程式碼的資訊,請檢視下列連結。
Version 1 Security Changes for the Microsoft .NET Framework (http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnnetsec/html/V1securitychanges.asp)
Process and Request Identity in ASP.NET (http://www.gotdotnet.com/team/upgrade/v1/aspnet_account_readme.doc)

?考

如需詳細資訊,請參考下列 Microsoft 網站:
Exception Management in .NET
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnbda/html/exceptdotnet.asp (http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnbda/html/exceptdotnet.asp)

Handling Errors in the .NET Framework Using Exceptions (Dr. GUI.NET #5)
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpguide/html/cpconHandlingThrowingExceptions.asp (http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpguide/html/cpconHandlingThrowingExceptions.asp)

HttpServerUtility.ClearError Method
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/html/frlrfSystemWebHttpServerUtilityClassClearErrorTopic.asp (http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/html/frlrfSystemWebHttpServerUtilityClassClearErrorTopic.asp)

MSDN .NET Development Center
http://msdn2.microsoft.com/en-us/netframework/default.aspx (http://msdn2.microsoft.com/en-us/netframework/default.aspx)

Microsoft .NET Home Page
http://www.microsoft.com/net/ (http://www.microsoft.com/net/)


本文件是根據 Microsoft Knowledge Base 文件編號 Q306355 翻譯的。若要參考原始英文文件內容,請至以下網址:

http://support.microsoft.com/support/kb/articles/Q306/3/55.asp (http://support.microsoft.com/kb/306355/en-us?ln=en-us&sd=gn&fr=0)

這篇文章中的資訊適用於:
  • Microsoft ASP .NET (包含於 .NET Framework)
  • Microsoft Visual C# .NET 2002 Standard Edition
關鍵字:?
kbhowto kbhowtomaster kbgrpdsasp kbaspnet kberror KB306355
Microsoft及(或)其供應商不就任何在本伺服器上發表的文字資料及其相關圖表資訊的恰當性作任何承諾。所有文字資料及其相關圖表均以「現狀」供應,不負任何擔保責任。Microsoft及(或)其供應商謹此聲明,不負任何對與此資訊有關之擔保責任,包括關於適售性、適用於某一特定用途、權利或不侵權的明示或默示擔保責任。Microsoft及(或)其供應商無論如何不對因或與使用本伺服器上資訊或與資訊的實行有關而引起的契約、過失或其他侵權行為之訴訟中的特別的、間接的、衍生性的損害或任何因使用而喪失所導致的之損害、資料或利潤負任何責任。