共用方式為


錯誤處理常式的完整範例

更新:2007 年 11 月

本程式碼範例包括頁面層級和應用程式層級的例外處理 (Exception Handling)。

程式碼範例檔案

本程式碼範例中的檔案如下:

  • Web.config

  • Global.asax

  • Default.aspx

  • ExceptionUtility (會放置在 App_Code 資料夾)

  • GenericErrorPage.aspx

  • HttpErrorPage.aspx

Web.config

下列範例提供的是 Web.config 檔案。customErrors 的初始設定將造成任何未處理的錯誤指向 HttpErrorPage.aspx 檔案。

<configuration>
  <appSettings/>
  <connectionStrings/>
  <system.web>
    <compilation debug="true" />

    <!-- Turn on Custom Errors -->
    <customErrors 
      mode="RemoteOnly"
      defaultRedirect="HttpErrorPage.aspx">
    </customErrors >

  </system.web>
</configuration>

Global.asax

下列範例提供的是 Global.asax 檔案。為了在 Global.asax 檔案中啟用錯誤事件處理常式,您將需要修改 Web.config 檔案,但組態檔會優先採用,因此必須將 customErrors 設為 Off,或者移除 defaultRedirect 設定。如果 Web.config 組態檔中有設為 Off 的 customErrors,則 Global.asax 中的 Application_Error 事件處理常式將處理所有未處理的錯誤。

安全性注意事項:

如果 Global.asax 檔案中沒有 Application_Error 處理常式,請不要將 Web.config 檔案中的 customErrors 設為 Off,這會使任何可能對網站引發錯誤的使用者接觸到可能洩漏的網站資訊。

void Application_Error(object sender, EventArgs e) 
{ 
    // Code that runs when an unhandled error occurs
    // Give the user some information, but
    // stay on the default page
    Exception exc = Server.GetLastError();
    Response.Write("<h2>Global Page Error</h2>\n");
    Response.Write(
        "<p>" + exc.Message + "</p>\n");
    Response.Write("Return to the <a href='Default.aspx'>" +
        "Default Page</a>\n");

    // Log the exception and notify system operators
    ExceptionUtility.LogException(exc, "DefaultPage");
    ExceptionUtility.NotifySystemOps(exc);

    // Clear the error from the server
    Server.ClearError();
}

ExceptionUtility

下列範例提供的是 ExceptionUtility 檔案。錯誤記錄可能會被指向電腦的 ErrorLog 檔案,或者如果電腦為 Web 伺服陣列的一部分,錯誤記錄則可能會被記錄到全域存取的文字檔,甚至資料庫。您可能需要立即將問題通知給系統管理員。下列 ExceptionUtility 有兩個靜態方法:一個記錄例外狀況,另一個則通知系統管理員。這些方法在程式碼中實作的方式取決於您組織的需求。對於這個範例,您必須授與 NETWORK SERVICE 對 App_Data 資料夾的寫入權限,讓應用程式可以寫入錯誤記錄。

using System;
using System.IO;
using System.Web;

// Create our own utility for exceptions
public sealed class ExceptionUtility
{
    // All methods are static, so this can be private
    private ExceptionUtility()
    { }

    // Log an Exception
    public static void LogException(Exception exc, string source)
    {
        // Include enterprise logic for logging exceptions
        // Get the absolute path to the log file
        string logFile = "App_Data/ErrorLog.txt";
        logFile = HttpContext.Current.Server.MapPath(logFile);

        // Open the log file for append and write the log
        StreamWriter sw = new StreamWriter(logFile, true);
        sw.Write("******************** " + DateTime.Now);
        sw.WriteLine(" ********************");
        if (exc.InnerException != null)
        {
            sw.Write("Inner Exception Type: ");
            sw.WriteLine(exc.InnerException.GetType().ToString());
            sw.Write("Inner Exception: ");
            sw.WriteLine(exc.InnerException.Message);
            sw.Write("Inner Source: ");
            sw.WriteLine(exc.InnerException.Source);
            if (exc.InnerException.StackTrace != null)
                sw.WriteLine("Inner Stack Trace: ");
            sw.WriteLine(exc.InnerException.StackTrace);
        }
        sw.Write("Exception Type: ");
        sw.WriteLine(exc.GetType().ToString());
        sw.WriteLine("Exception: " + exc.Message);
        sw.WriteLine("Source: " + source);
        sw.WriteLine("Stack Trace: ");
        if (exc.StackTrace != null)
            sw.WriteLine(exc.StackTrace);
        sw.WriteLine();
        sw.Close();
    }

    // Notify System Operators about an exception
    public static void NotifySystemOps(Exception exc)
    {
        // Include code for notifying IT system operators
    }
}

Default.aspx

下列範例提供的是 Default.aspx 頁面。這個檔案提供了三個按鈕,各自會引發不同的例外狀況。在頁面上的 Page_Error 處理常式會針對特定的錯誤進行篩選,並以不同的方式處理這三個例外狀況。這個檔案還提供了指向不存在之檔案的連結,提供四種未在頁面上處理的錯誤。

<%@ Page Language="C#" %>

<script >
    protected void Submit_Click(object sender, EventArgs e)
    {
        string arg = ((Button)sender).CommandArgument;

        if (arg.Equals("1"))
        {
            // Exception handled on the Generic Error Page
            throw new InvalidOperationException("Invalid click operation?!");
        }
        else if (arg.Equals("2"))
        {
            // Exception handled on the current page
            throw new ArgumentOutOfRangeException("click?!");
        }
        else
        {
            // Exception handled on the Http Error Page (per Web.Config)
            throw new Exception("Generic click problem?!");
        }
    }
    private void Page_Error(object sender, EventArgs e)
    {
        // Get last error from the server
        Exception exc = Server.GetLastError();

        // Filter for a specific kind of exception
        if (exc is ArgumentOutOfRangeException)
        {
            // Give the user some information, but
            // stay on the default page
            Response.Write("<h2>Default Page Error</h2>\n");
            Response.Write( 
                "<p>ArgumentOutOfRange: Your click must have " +
                "been out of range?!</p>\n");
            Response.Write("Return to the <a href='Default.aspx'>" +
                "Default Page</a>\n");

            // Log the exception and notify system operators
            ExceptionUtility.LogException(exc, "DefaultPage");
            ExceptionUtility.NotifySystemOps(exc);

            // Clear the error from the server
            Server.ClearError();

        }
        // Filter for other kinds of exceptions
        else if (exc is InvalidOperationException)
        {
            // Pass the error on to the Generic Error page
            Server.Transfer("GenericErrorPage.aspx", true);
        }
        else
        {
            // Pass the error on to the default global handler
        }
    }
</script>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" >
<head >
    <title>Exception Handler Page</title>
</head>
<body>
    <form id="form1" >
    <div>

    <h2>Default Page</h2>
        <p>
            Click this button to create a InvalidOperationException.<br />
            <asp:Button ID="Submit1"  CommandArgument="1" 
                OnClick="Submit_Click" Text="Click 1" />
        </p>
        <p>
            Click this button to create a ArgumentOutOfRangeException.<br />
            <asp:Button ID="Submit2"  CommandArgument="2" 
                OnClick="Submit_Click" Text="Click 2" />
        </p>
        <p>
            Click this button to create a generic Exception.<br />
            <asp:Button ID="Submit3"  CommandArgument="3" 
                OnClick="Submit_Click" Text="Click 3" />
        </p>

        <p>Click this link to attempt to access a non-existent page:<br />
        <a href="NoPage.aspx">NoPage.aspx</a>
    </p>

    </div>
    </form>
</body>
</html>

GenericErrorPage.aspx

下列範例提供的是 GenericErrorPage.aspx 檔案。這個頁面會建立安全訊息並顯示給遠端使用者,而對本機使用者 (應用程式的開發人員和測試人員) 則顯示完整的例外狀況報告。

<%@ Page Language="C#" %>

<script >
    protected Exception ex = null;

    protected void Page_Load(object sender, EventArgs e)
    {
        // Get the last error from the server
        Exception ex = Server.GetLastError();

        // Create a safe message
        string safeMsg = "A problem has occurred in the web site. ";

        // Show Inner Exception fields for local access
        if (ex.InnerException != null)
        {
            innerTrace.Text = ex.InnerException.StackTrace;
            InnerErrorPanel.Visible = Request.IsLocal;
            innerMessage.Text = ex.InnerException.Message;
        }
        // Show Trace for local access
        if (Request.IsLocal)
            exTrace.Visible = true;
        else
            ex = new Exception(safeMsg, ex);

        // Fill the page fields
        exMessage.Text = ex.Message;
        exTrace.Text = ex.StackTrace;

        // Log the exception and notify system operators
        ExceptionUtility.LogException(ex, "Generic Error Page");
        ExceptionUtility.NotifySystemOps(ex);

        // Clear the error from the server
        Server.ClearError();
    }
</script>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" >
<head >
    <title>Generic Error Page</title>
</head>
<body>
    <form id="form1" >
    <div>

    <h2>Generic Error Page</h2>
    <asp:Panel ID="InnerErrorPanel"  Visible="false">
        <p>
            Inner Error Message:<br />
            <asp:Label ID="innerMessage"  
                Font-Bold="true" Font-Size="Large" /><br />
        </p>
        <pre>
<asp:Label ID="innerTrace"  />
        </pre>
    </asp:Panel>
    <p>
        Error Message:<br />
        <asp:Label ID="exMessage"  
            Font-Bold="true" Font-Size="Large" />
    </p>
    <pre>
<asp:Label ID="exTrace"  visible="false" />
    </pre>

    </div>
    </form>
</body>
</html>

HttpErrorPage.aspx

下列範例提供的是 HttpErrorPage.aspx 檔案。這個頁面也會建立根據錯誤碼值的安全訊息並顯示給遠端使用者,而對本機使用者則顯示完整的例外狀況報告。

<%@ Page Language="C#" %>

<script >
    protected HttpException ex = null;

    protected void Page_Load(object sender, EventArgs e)
    {
        ex = (HttpException)Server.GetLastError();
        string safeMsg = String.Empty;

        // Filter for Error Codes and set text
        if (ex.ErrorCode >= 400 && ex.ErrorCode < 500)
        {
            ex = new HttpException
                (ex.ErrorCode, 
                    "Your file could not be found or " +
                    "there was an access problem.", ex);
        }
        else if (ex.ErrorCode > 499)
            ex = new HttpException
                (ex.ErrorCode, 
                    "There was an error on the server.", ex);
        else
            ex = new HttpException
                (ex.ErrorCode, 
                "There was a problem " +
                    "with the web site.", ex);

        // Log the exception and notify system operators
        ExceptionUtility.LogException(ex, "HttpErrorPage");
        ExceptionUtility.NotifySystemOps(ex);

        // Fill the page fields
        exMessage.Text = ex.Message;
        exTrace.Text = ex.StackTrace;

        // Show Inner Exception fields for local access
        if (ex.InnerException != null)
        {
            innerTrace.Text = ex.InnerException.StackTrace;
            InnerErrorPanel.Visible = Request.IsLocal;
            innerMessage.Text = ex.InnerException.Message;
        }
        // Show Trace for local access
        exTrace.Visible = Request.IsLocal;

        // Clear the error from the server
        Server.ClearError();
    }
</script>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" >
<head >
    <title>Generic Error Page</title>
</head>
<body>
    <form id="form1" >
    <div>

    <h2>Http Error Page</h2>    
    <asp:Panel ID="InnerErrorPanel"  Visible="false">
        <asp:Label ID="innerMessage"  
            Font-Bold="true" Font-Size="Large" /><br />
        <pre>
<asp:Label ID="innerTrace"  />
        </pre>
    </asp:Panel>
    Error Message:<br />
    <asp:Label ID="exMessage"  
        Font-Bold="true" Font-Size="Large" />
    <pre>
<asp:Label ID="exTrace"  visible="false" />
    </pre>

    </div>
    </form>
</body>
</html>

請參閱

工作

HOW TO:處理頁面層級的錯誤

HOW TO:處理應用程式層級的錯誤

其他資源

ASP.NET Web 網頁和應用程式中的錯誤處理