エラー ハンドラの完全なコード例

更新 : 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 構成ファイルに、Off に設定された customErrors がある場合、Global.asax の Application_Error イベント ハンドラがすべての未処理エラーを処理します。

Bb397417.alert_security(ja-jp,VS.90).gifセキュリティに関するメモ :

Global.asax ファイルに Application_Error ハンドラがない場合、Web.config ファイルの customErrors を Off に設定しないでください。Web サイトに関する情報が、サイトにエラーを発生させるようなユーザーに公開される危険性があります。

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 には静的メソッドが 2 つあります。1 つは例外をログに記録するメソッドで、もう 1 つはシステム管理者に通知するメソッドです。これらのメソッドをコードに実装する方法は、組織の要件によって変わります。たとえば、アプリケーションがエラー ログを出力できるようにするには、App_Data フォルダに NETWORK SERVICE の書き込みアクセス許可を付与する必要があります。

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 ページの例を次に示します。このファイルには 3 つのボタンがあり、それぞれ異なる例外を発生させます。このページの Page_Error ハンドラは特定のエラーをフィルタ処理し、3 つの個別の方法で 3 つの例外を処理します。また、存在しないファイルへのリンクもあります。これは、ページで処理されない 4 種類目のエラーです。

<%@ 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 のページとアプリケーションにおけるエラー処理