错误处理程序的完整示例

更新:2007 年 11 月

本代码示例包括页级和应用程序级异常处理元素。

代码示例文件

本代码示例中的文件如下:

  • 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 配置文件将 customErrors 设置为 Off,则 Global.asax 中的 Application_Error 事件处理程序将处理所有未处理的错误。

Bb397417.alert_security(zh-cn,VS.90).gif安全说明:

如果 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 文件;如果计算机是网络场的一部分,则错误日志可能会记录在可在全局范围内使用的文本文件乃至数据库中。可能还需要立即将问题通知给系统管理员。下面的 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 runat="server">
    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 runat="server">
    <title>Exception Handler Page</title>
</head>
<body>
    <form id="form1" runat="server">
    <div>

    <h2>Default Page</h2>
        <p>
            Click this button to create a InvalidOperationException.<br />
            <asp:Button ID="Submit1" runat="server" CommandArgument="1" 
                OnClick="Submit_Click" Text="Click 1" />
        </p>
        <p>
            Click this button to create a ArgumentOutOfRangeException.<br />
            <asp:Button ID="Submit2" runat="server" CommandArgument="2" 
                OnClick="Submit_Click" Text="Click 2" />
        </p>
        <p>
            Click this button to create a generic Exception.<br />
            <asp:Button ID="Submit3" runat="server" 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 runat="server">
    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 runat="server">
    <title>Generic Error Page</title>
</head>
<body>
    <form id="form1" runat="server">
    <div>

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

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

HttpErrorPage.aspx

下面的示例提供了 HttpErrorPage.aspx 页。该页也创建了取决于错误代码的值的显示给远程用户的安全消息。对于本地用户,该页显示完整的异常报告。

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

<script runat="server">
    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 runat="server">
    <title>Generic Error Page</title>
</head>
<body>
    <form id="form1" runat="server">
    <div>

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

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

请参见

任务

如何:处理页级别错误

如何:处理应用程序级别的错误

其他资源

ASP.NET 页和应用程序中的错误处理