Freigeben über


Vollständiges Beispiel für Fehlerhandler

Aktualisiert: November 2007

In diesem Codebeispiel werden sowohl auf Seitenebene als auch auf Anwendungsebene Elemente für die Ausnahmebehandlung eingefügt.

Codebeispieldateien

Folgende Dateien werden in diesem Codebeispiel verwendet:

  • Web.config

  • Global.asax

  • Default.aspx

  • ExceptionUtility (muss in den Ordner App_Code kopiert werden)

  • GenericErrorPage.aspx

  • HttpErrorPage.aspx

Web.config

Im folgenden Beispiel wird die Datei Web.config bereitgestellt. Die ursprüngliche Einstellung customErrors bewirkt, dass alle nicht behandelten Fehler an die Datei HttpErrorPage.aspx geleitet werden.

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

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

  </system.web>
</configuration>

Global.asax

Im folgenden Beispiel wird die Datei Global.asax bereitgestellt. Um den Fehlerhandler in der Datei Global.asax zu aktivieren, müssen Sie die Datei Web.config bearbeiten. Die Konfigurationsdatei hat Vorrang. Daher müssen Sie entweder customErrors auf Off festlegen oder die Einstellung defaultRedirect entfernen. Wenn in der Konfigurationsdatei Web.config customErrors auf Off festgelegt ist, werden alle unbehandelten Fehler vom Application_Error-Ereignishandler in der Datei Global.asax bearbeitet.

Sicherheitshinweis:

Legen Sie für customErrors in der Datei Web.config niemals Off fest, wenn in der Datei Global.asax kein Application_Error-Handler vorhanden ist. Andernfalls können vertrauliche Informationen über Ihre Website von jedem zugänglich werden, der einen Fehler auf Ihrer Site verursachen kann.

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

Im folgenden Beispiel wird die Datei ExceptionUtility bereitgestellt. Fehlerprotokolle können in die Datei ErrorLog des Computers geleitet werden oder, wenn der Computer Teil einer Webfarm ist, in einer global verfügbaren Textdatei oder Datenbank aufgezeichnet werden. In bestimmten Fällen sollten Sie auch die Systemadministratoren direkt über ein Problem benachrichtigen. Das folgende ExceptionUtility verfügt über zwei statische Methoden: eine Methode protokolliert die Ausnahme, die andere sendet eine Benachrichtigung an die Systemadministratoren. Wie Sie diese Methoden in Ihrem Code implementieren, sollte ausgehend von den Anforderungen in Ihrer Organisation entschieden werden. In diesem Beispiel müssen Sie dem NETZWERKDIENST Schreibberechtigungen für den Ordner App_Data gewähren, sodass die Anwendung Meldungen in das Fehlerprotokoll schreiben kann.

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

Im folgenden Beispiel wird die Seite Default.aspx bereitgestellt. In der Datei werden drei Schaltflächen erstellt, von denen jede eine andere Ausnahme auslöst. Der Page_Error-Handler der Seite unterscheidet verschiedene Fehler und behandelt jede dieser Ausnahmen auf andere Weise. Zusätzlich ist ein Link zu einer nicht vorhandenen Datei enthalten. Dieser verursacht einen weiteren Fehler, der nicht auf der Seite behandelt wird.

<%@ 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

Im folgenden Beispiel wird die Seite GenericErrorPage.aspx bereitgestellt. Die Seite erstellt eine sichere Meldung, die Remotebenutzern angezeigt wird. Lokalen Benutzern (Entwickler und Tester der Anwendung) wird ein vollständiger Bericht zur Ausnahme angezeigt.

<%@ 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

Im folgenden Beispiel wird die Seite HttpErrorPage.aspx bereitgestellt. Die Seite erstellt ebenfalls eine sichere Meldung, die vom jeweiligen Fehlercode abhängig ist und den Remotebenutzern angezeigt wird. Lokalen Benutzern wird ein vollständiger Bericht zur Ausnahme angezeigt.

<%@ 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>

Siehe auch

Aufgaben

Gewusst wie: Behandeln von Fehlern auf Seitenebene

Gewusst wie: Behandeln von Fehlern auf Anwendungsebene

Weitere Ressourcen

Fehlerbehandlung in ASP.NET-Seiten und -Anwendungen