Share via


Verarbeiten von Ausnahmefehlern (VB)

von Scott Mitchell

Anzeigen oder Herunterladen von Beispielcode (Vorgehensweise zum Herunterladen)

Wenn ein Laufzeitfehler in einer Webanwendung in der Produktion auftritt, ist es wichtig, einen Entwickler zu benachrichtigen und den Fehler zu protokollieren, damit er zu einem späteren Zeitpunkt diagnostiziert wird. Dieses Tutorial bietet eine Übersicht darüber, wie ASP.NET Laufzeitfehler verarbeitet, und untersucht eine Möglichkeit, benutzerdefinierten Code auszuführen, wenn eine nicht behandelte Ausnahme bis zur ASP.NET Runtime blasen.

Einführung

Wenn eine nicht behandelte Ausnahme in einer ASP.NET Anwendung auftritt, wird sie bis zur ASP.NET Runtime angezeigt, die das Error Ereignis auslöst und die entsprechende Fehlerseite anzeigt. Es gibt drei verschiedene Arten von Fehlerseiten: den Laufzeitfehler Gelber Bildschirm des Todes (YSOD); ausnahmedetails YSOD; und benutzerdefinierte Fehlerseiten. Im vorherigen Tutorial haben wir die Anwendung so konfiguriert, dass sie eine benutzerdefinierte Fehlerseite für Remotebenutzer und den Ausnahmedetails-YSOD für Benutzer verwendet, die lokal besuchen.

Die Verwendung einer benutzerfreundlichen benutzerdefinierten Fehlerseite, die dem Aussehen und Verhalten der Website entspricht, wird dem standardmäßigen Laufzeitfehler-YSOD vorgezogen, aber das Anzeigen einer benutzerdefinierten Fehlerseite ist nur ein Teil einer umfassenden Lösung zur Fehlerbehandlung. Wenn in einer Anwendung in der Produktion ein Fehler auftritt, ist es wichtig, dass die Entwickler über den Fehler benachrichtigt werden, damit sie die Ursache der Ausnahme ermitteln und beheben können. Darüber hinaus sollten die Fehlerdetails protokolliert werden, damit der Fehler zu einem späteren Zeitpunkt untersucht und diagnostiziert werden kann.

In diesem Tutorial wird gezeigt, wie Sie auf die Details einer nicht behandelten Ausnahme zugreifen, damit sie protokolliert und ein Entwickler benachrichtigt werden kann. In den beiden folgenden Tutorials werden Fehlerprotokollierungsbibliotheken untersucht, die Entwickler nach ein wenig Konfiguration automatisch über Laufzeitfehler benachrichtigen und deren Details protokollieren.

Hinweis

Die in diesem Tutorial untersuchten Informationen sind am nützlichsten, wenn Sie nicht behandelte Ausnahmen auf eindeutige oder angepasste Weise verarbeiten müssen. In Fällen, in denen Sie nur die Ausnahme protokollieren und einen Entwickler benachrichtigen müssen, ist die Verwendung einer Fehlerprotokollierungsbibliothek der weg. Die nächsten beiden Tutorials bieten eine Übersicht über zwei solcher Bibliotheken.

Ausführen von Code beim Auslösen desErrorEreignisses

Ereignisse bieten einem Objekt einen Mechanismus zum Signalisieren, dass etwas Interessantes aufgetreten ist, und für ein anderes Objekt, um Code als Antwort auszuführen. Als ASP.NET Entwickler sind Sie es gewohnt, in Bezug auf Ereignisse zu denken. Wenn Sie Code ausführen möchten, wenn der Besucher auf eine bestimmte Schaltfläche klickt, erstellen Sie einen Ereignishandler für das Ereignis dieses Click Button und legen Ihren Code dort ein. Da die ASP.NET Runtime ihr Error Ereignis auslöst, wenn eine nicht behandelte Ausnahme auftritt, folgt daraus, dass der Code zum Protokollieren der Fehlerdetails in einem Ereignishandler ausgeführt wird. Aber wie erstellen Sie einen Ereignishandler für das Error Ereignis?

Das Error Ereignis ist eines von vielen Ereignissen in der -Klasse, dieHttpApplication während der Lebensdauer einer Anforderung in bestimmten Phasen der HTTP-Pipeline ausgelöst werden. Beispielsweise wird das -Ereignis der HttpApplication -Klasse BeginRequest am Anfang jeder Anforderung ausgelöst. Ihr AuthenticateRequest Ereignis wird ausgelöst, wenn ein Sicherheitsmodul den Anforderer identifiziert hat. Diese HttpApplication Ereignisse geben dem Seitenentwickler die Möglichkeit, benutzerdefinierte Logik an den verschiedenen Punkten der Lebensdauer einer Anforderung auszuführen.

Ereignishandler für die HttpApplication Ereignisse können in einer speziellen Datei mit dem Namen Global.asaxplatziert werden. Um diese Datei auf Ihrer Website zu erstellen, fügen Sie dem Stamm Ihrer Website mithilfe der Global Application Class-Vorlage mit dem Namen Global.asaxein neues Element hinzu.

Screenshot: Hinzufügen eines neuen Elements zum Stamm Ihrer Website mithilfe der Global Application Class-Vorlage mit dem Namen Global.asax, um diese Datei auf Ihrer Website zu erstellen.

Abbildung 1: Hinzufügen Global.asax zu Ihrer Webanwendung
(Klicken Sie hier, um das Bild in voller Größe anzuzeigen)

Der Inhalt und die Struktur der Global.asax von Visual Studio erstellten Datei unterscheiden sich geringfügig, je nachdem, ob Sie ein Webanwendungsprojekt (WAP) oder ein Websiteprojekt (Web Site Project, WSP) verwenden. Bei einem WAP wird das Global.asax als zwei separate Dateien implementiert – Global.asax und Global.asax.vb. Die Global.asax Datei enthält nichts anderes als eine @Application Direktive, die auf die .vb Datei verweist. Die relevanten Ereignishandler sind in der Global.asax.vb Datei definiert. Für WSPs wird nur eine einzelne Datei erstellt, Global.asaxund die Ereignishandler werden in einem <script runat="server"> Block definiert.

Die Global.asax Datei, die in einer WAP von der Global Application Class-Vorlage von Visual Studio erstellt wurde, enthält Ereignishandler mit den Namen Application_BeginRequest, Application_AuthenticateRequestund , und Application_Error, bei denen es sich um Ereignishandler für die HttpApplication Ereignisse BeginRequest, AuthenticateRequestbzw. und Errorhandelt. Es gibt auch Ereignishandler mit den Namen Application_Start, Session_Start, Application_End, und , bei Session_Enddenen es sich um Ereignishandler handelt, die beim Starten der Webanwendung, beim Start einer neuen Sitzung, beim Ende der Anwendung bzw. beim Beenden einer Sitzung ausgelöst werden. Die Global.asax von Visual Studio in einem WSP erstellte Datei enthält nur die Application_ErrorEreignishandler , Application_Start, Session_Start, Application_Endund Session_End .

Hinweis

Beim Bereitstellen der ASP.NET Anwendung müssen Sie die Datei in die Global.asax Produktionsumgebung kopieren. Die Global.asax.vb Datei, die im WAP erstellt wird, muss nicht in die Produktion kopiert werden, da dieser Code in die Assembly des Projekts kompiliert wird.

Die von der Global Application Class-Vorlage von Visual Studio erstellten Ereignishandler sind nicht vollständig. Sie können einen Ereignishandler für jedes HttpApplication Ereignis hinzufügen, indem Sie den -Ereignishandler Application_EventNamebenennen. Beispielsweise können Sie der Datei den folgenden Code hinzufügen, Global.asax um einen Ereignishandler für das AuthorizeRequest Ereignis zu erstellen:

Sub Application_AuthorizeRequest(ByVal sender As Object, ByVal e As EventArgs)
    ' Event handler code
End Sub

Ebenso können Sie alle Ereignishandler entfernen, die von der Global Application Class-Vorlage erstellt wurden und nicht benötigt werden. Für dieses Tutorial benötigen wir nur einen Ereignishandler für das Error Ereignis. Sie können die anderen Ereignishandler aus der Global.asax Datei entfernen.

Hinweis

HTTP-Module bieten eine weitere Möglichkeit, Ereignishandler für HttpApplication Ereignisse zu definieren. HTTP-Module werden als Klassendatei erstellt, die direkt im Webanwendungsprojekt platziert oder in eine separate Klassenbibliothek unterteilt werden kann. Da sie in eine Klassenbibliothek unterteilt werden können, bieten HTTP-Module ein flexibleres und wiederverwendbares Modell zum Erstellen von HttpApplication Ereignishandlern. Während die Global.asax Datei spezifisch für die Webanwendung ist, in der sie sich befindet, können HTTP-Module in Assemblys kompiliert werden. Zu diesem Zeitpunkt ist das Hinzufügen des HTTP-Moduls zu einer Website so einfach wie das Löschen der Assembly im Bin Ordner und das Registrieren des Moduls in Web.config. Dieses Tutorial befasst sich nicht mit dem Erstellen und Verwenden von HTTP-Modulen, aber die beiden Fehlerprotokollierungsbibliotheken, die in den folgenden beiden Tutorials verwendet werden, werden als HTTP-Module implementiert. Weitere Informationen zu den Vorteilen von HTTP-Modulen finden Sie unter Verwenden von HTTP-Modulen und -Handlern zum Erstellen von pluggablen ASP.NET-Komponenten.

Abrufen von Informationen zur nicht behandelten Ausnahme

An diesem Punkt verfügen wir über eine Global.asax-Datei mit einem Application_Error Ereignishandler. Wenn dieser Ereignishandler ausgeführt wird, müssen wir einen Entwickler über den Fehler benachrichtigen und seine Details protokollieren. Zum Ausführen dieser Aufgaben müssen wir zunächst die Details der Ausnahme ermitteln, die ausgelöst wurde. Verwenden Sie die -Methode desGetLastError Server-Objekts, um Details der nicht behandelten Ausnahme abzurufen, die das Error Ereignis ausgelöst hat.

Sub Application_Error(ByVal sender As Object, ByVal e As EventArgs)
    ' Get the error details
    Dim lastErrorWrapper As HttpException = _
        CType(Server.GetLastError(), HttpException)
End Sub

Die GetLastError -Methode gibt ein Objekt vom Typ Exceptionzurück, das der Basistyp für alle Ausnahmen im .NET Framework ist. Im obigen Code konvertiert ich jedoch das von zurückgegebene GetLastError Exception-Objekt in ein HttpException -Objekt. Wenn das Error Ereignis ausgelöst wird, weil während der Verarbeitung einer ASP.NET Ressource eine Ausnahme ausgelöst wurde, wird die ausgelöste Ausnahme in einen HttpExceptionumschlossen. Verwenden Sie InnerException die -Eigenschaft, um die tatsächliche Ausnahme abzurufen, die das Error-Ereignis ausgelöst hat. Wenn das Error Ereignis aufgrund einer HTTP-basierten Ausnahme ausgelöst wurde, z. B. eine Anforderung für eine nicht vorhandene Seite, wird ein HttpException ausgelöst, aber es verfügt nicht über eine innere Ausnahme.

Der folgende Code verwendet den GetLastErrormessage , um Informationen über die Ausnahme abzurufen, die das Error Ereignis ausgelöst hat, und speichert das HttpException in einer Variablen mit dem Namen lastErrorWrapper. Anschließend wird der Typ, die Nachricht und die Stapelablaufverfolgung der ursprünglichen Ausnahme in drei Zeichenfolgenvariablen gespeichert, wobei überprüft wird, ob es lastErrorWrapper sich um die tatsächliche Ausnahme handelt, die das Error Ereignis ausgelöst hat (im Fall von HTTP-basierten Ausnahmen) oder ob es sich lediglich um einen Wrapper für eine Ausnahme handelt, die während der Verarbeitung der Anforderung ausgelöst wurde.

Sub Application_Error(ByVal sender As Object, ByVal e As EventArgs)
    ' Get the error details
    Dim lastErrorWrapper As HttpException = _
        CType(Server.GetLastError(), HttpException)

    Dim lastError As Exception = lastErrorWrapper
    If lastErrorWrapper.InnerException IsNot Nothing Then
        lastError = lastErrorWrapper.InnerException
    End If

    Dim lastErrorTypeName As String = lastError.GetType().ToString()
    Dim lastErrorMessage As String = lastError.Message
    Dim lastErrorStackTrace As String = lastError.StackTrace
End Sub

An diesem Punkt verfügen Sie über alle Informationen, die Sie zum Schreiben von Code benötigen, der die Details der Ausnahme in einer Datenbanktabelle protokolliert. Sie können eine Datenbanktabelle mit Spalten für jede der relevanten Fehlerdetails erstellen - den Typ, die Nachricht, die Stapelablaufverfolgung usw. - zusammen mit anderen nützlichen Informationen, z. B. die URL der angeforderten Seite und den Namen des aktuell angemeldeten Benutzers. Application_Error Im Ereignishandler würden Sie dann eine Verbindung mit der Datenbank herstellen und einen Datensatz in die Tabelle einfügen. Ebenso können Sie Code hinzufügen, um einen Entwickler per E-Mail über den Fehler zu benachrichtigen.

Die in den nächsten beiden Tutorials untersuchten Fehlerprotokollierungsbibliotheken bieten diese Funktionalität sofort einsatzbereit, sodass Sie diese Fehlerprotokollierung und -benachrichtigung nicht selbst erstellen müssen. Um jedoch zu veranschaulichen, dass das Error Ereignis ausgelöst wird und dass der Application_Error Ereignishandler verwendet werden kann, um Fehlerdetails zu protokollieren und einen Entwickler zu benachrichtigen, fügen wir Code hinzu, der einen Entwickler benachrichtigt, wenn ein Fehler auftritt.

Benachrichtigen eines Entwicklers, wenn eine nicht behandelte Ausnahme auftritt

Wenn eine nicht behandelte Ausnahme in der Produktionsumgebung auftritt, ist es wichtig, das Entwicklungsteam zu benachrichtigen, damit es den Fehler bewerten und bestimmen kann, welche Aktionen ergriffen werden müssen. Wenn beispielsweise beim Herstellen einer Verbindung mit der Datenbank ein Fehler auftritt, müssen Sie Ihre Verbindungszeichenfolge überprüfen und möglicherweise ein Supportticket mit Ihrem Webhostingunternehmen öffnen. Wenn die Ausnahme aufgrund eines Programmierfehlers aufgetreten ist, muss möglicherweise zusätzlicher Code oder validierungslogik hinzugefügt werden, um solche Fehler in Zukunft zu verhindern.

Die .NET Framework Klassen im Namespace erleichtern das System.Net.Mail Senden einer E-Mail. Die MailMessage -Klasse stellt eine E-Mail-Nachricht dar und verfügt über Eigenschaften wie To, From, Subject, Bodyund Attachments. Wird SmtpClass verwendet, um ein MailMessage Objekt mit einem angegebenen SMTP-Server zu senden. Die SMTP-Servereinstellungen können programmgesteuert oder deklarativ im <system.net> -Element in Web.config fileangegeben werden. Weitere Informationen zum Senden von E-Mail-Nachrichten in einer ASP.NET Anwendung finden Sie in meinem Artikel Senden von Email von einer ASP.NET Web Pages Website und den häufig gestellten Fragen zu System.Net.Mail.

Hinweis

Das <system.net> Element enthält die SMTP-Servereinstellungen, die von der SmtpClient Klasse beim Senden einer E-Mail verwendet werden. Ihr Webhostingunternehmen verfügt wahrscheinlich über einen SMTP-Server, den Sie zum Senden von E-Mails aus Ihrer Anwendung verwenden können. Informationen zu den SMTP-Servereinstellungen, die Sie in Ihrer Webanwendung verwenden sollten, finden Sie im Abschnitt Support Ihres Webhosts.

Fügen Sie dem Ereignishandler den Application_Error folgenden Code hinzu, um einem Entwickler eine E-Mail zu senden, wenn ein Fehler auftritt:

Sub Application_Error(ByVal sender As Object, ByVal e As EventArgs)
    ' Get the error details
    Dim lastErrorWrapper As HttpException = _
        CType(Server.GetLastError(), HttpException)
    
    Dim lastError As Exception = lastErrorWrapper
    If lastErrorWrapper.InnerException IsNot Nothing Then
        lastError = lastErrorWrapper.InnerException
    End If

    Dim lastErrorTypeName As String = lastError.GetType().ToString()
    Dim lastErrorMessage As String = lastError.Message
    Dim lastErrorStackTrace As String = lastError.StackTrace

    Const ToAddress As String = "support@example.com"
    Const FromAddress As String = "support@example.com"
    Const Subject As String = "An Error Has Occurred!"

    ' Create the MailMessage object
    Dim mm As New MailMessage(FromAddress, ToAddress)
    mm.Subject = Subject
    mm.IsBodyHtml = True
    mm.Priority = MailPriority.High
  mm.Body = string.Format( _
"<html>" & vbCrLf & _
"  <body>" & vbCrLf & _
"  <h1>An Error Has Occurred!</h1>" & vbCrLf & _
"  <table cellpadding=""5"" cellspacing=""0"" border=""1"">" & vbCrLf & _
"  <tr>" & vbCrLf & _
"  <tdtext-align: right;font-weight: bold"">URL:</td>" & vbCrLf & _
"  <td>{0}</td>" & vbCrLf & _
"  </tr>" & vbCrLf & _
"  <tr>" & vbCrLf & _
"  <tdtext-align: right;font-weight: bold"">User:</td>" & vbCrLf & _
"  <td>{1}</td>" & vbCrLf & _
"  </tr>" & vbCrLf & _
"  <tr>" & vbCrLf & _
"  <tdtext-align: right;font-weight: bold"">Exception Type:</td>" & vbCrLf & _
"  <td>{2}</td>" & vbCrLf & _
"  </tr>" & vbCrLf & _
"  <tr>" & vbCrLf & _
"  <tdtext-align: right;font-weight: bold"">Message:</td>" & vbCrLf & _
"  <td>{3}</td>" & vbCrLf & _
"  </tr>" & vbCrLf & _
"  <tr>" & vbCrLf & _
"  <tdtext-align: right;font-weight: bold"">Stack Trace:</td>" & vbCrLf & _
"  <td>{4}</td>" & vbCrLf & _
"  </tr> " & vbCrLf & _
"  </table>" & vbCrLf & _
"  </body>" & vbCrLf & _
"</html>", _
  Request.RawUrl, _
  User.Identity.Name, _
  lastErrorTypeName, _
  lastErrorMessage, _
  lastErrorStackTrace.Replace(Environment.NewLine, "<br />"))

    'Attach the Yellow Screen of Death for this error
    Dim YSODmarkup As String = lastErrorWrapper.GetHtmlErrorMessage()
    If Not String.IsNullOrEmpty(YSODmarkup) Then
        Dim YSOD As Attachment = _
            Attachment.CreateAttachmentFromString(YSODmarkup, "YSOD.htm")
        mm.Attachments.Add(YSOD)
    End If

    ' Send the email
    Dim smtp As New SmtpClient()
    smtp.Send(mm)
End Sub

Während der obige Code ziemlich lang ist, erstellt der Großteil davon den HTML-Code, der in der E-Mail angezeigt wird, die an den Entwickler gesendet wurde. Der Code verweist zunächst auf das von der HttpExceptionGetLastError -Methode zurückgegebene (lastErrorWrapper). Die tatsächliche Ausnahme, die von der Anforderung ausgelöst wurde, wird über lastErrorWrapper.InnerException abgerufen und der Variablen lastErrorzugewiesen. Die Typ-, Nachrichten- und Stapelablaufverfolgungsinformationen werden von lastError abgerufen und in drei Zeichenfolgenvariablen gespeichert.

Als Nächstes wird ein MailMessage Objekt mit dem Namen mm erstellt. Der E-Mail-Text ist HTML-formatiert und zeigt die URL der angeforderten Seite, den Namen des aktuell angemeldeten Benutzers sowie Informationen zur Ausnahme (Typ, Nachricht und Stapelablaufverfolgung) an. Eine der coolen Dinge an der HttpException -Klasse ist, dass Sie den HTML-Code generieren können, der zum Erstellen der Ausnahmedetails gelber Bildschirm des Todes (YSOD) verwendet wird, indem Sie die GetHtmlErrorMessage-Methode aufrufen. Diese Methode wird hier verwendet, um das YSOD-Markup "Ausnahmedetails" abzurufen und der E-Mail als Anlage hinzuzufügen. Ein Wort der Vorsicht: Wenn die Ausnahme, die das Error Ereignis ausgelöst hat, eine HTTP-basierte Ausnahme war (z. B. eine Anforderung für eine nicht vorhandene Seite), gibt die GetHtmlErrorMessage -Methode zurück null.

Der letzte Schritt besteht darin, das MailMessagezu senden. Dazu erstellen Sie eine neue SmtpClient Methode und rufen ihre Send Methode auf.

Hinweis

Bevor Sie diesen Code in Ihrer Webanwendung verwenden, sollten Sie die Werte in den ToAddress Konstanten und FromAddress von support@example.com in die E-Mail-Adresse ändern, an die die Fehlerbenachrichtigungs-E-Mail gesendet werden soll und von der sie stammt. Sie müssen auch SMTP-Servereinstellungen im <system.net> Abschnitt in Web.configangeben. Wenden Sie sich an Ihren Webhostanbieter, um die zu verwendenden SMTP-Servereinstellungen zu ermitteln.

Wenn dieser Code bei jedem Fehler vorhanden ist, erhält der Entwickler eine E-Mail-Nachricht, die den Fehler zusammenfasst und YSOD enthält. Im vorherigen Tutorial haben wir einen Laufzeitfehler veranschaulicht, indem wir Genre.aspx aufrufen und einen ungültigen ID Wert über die Abfragezeichenfolge übergeben, z. B Genre.aspx?ID=foo. . Der Besuch der Seite mit der Global.asax Datei erzeugt die gleiche Benutzererfahrung wie im vorherigen Tutorial. In der Entwicklungsumgebung wird weiterhin der gelbe Bildschirm mit den Ausnahmedetails des Todes angezeigt, während in der Produktionsumgebung die benutzerdefinierte Fehlerseite angezeigt wird. Zusätzlich zu diesem vorhandenen Verhalten erhält der Entwickler eine E-Mail.

Abbildung 2 zeigt die E-Mail, die beim Besuch Genre.aspx?ID=fooempfangen wurde. Der E-Mail-Text fasst die Ausnahmeinformationen zusammen, während die YSOD.htm Anlage den Inhalt anzeigt, der im Ausnahmedetails-YSOD angezeigt wird (siehe Abbildung 3).

Screenshot der empfangenen E-Mail mit den Ausnahmeinformationen.

Abbildung 2: Der Entwickler erhält eine Email Benachrichtigung, wenn eine ausnahme nicht behandelt wird
(Klicken Sie hier, um das Bild in voller Größe anzuzeigen)

Screenshot der E-Mail-Benachrichtigung, die vom Entwickler empfangen wird, wenn eine nicht behandelte Ausnahme vorliegt.

Abbildung 3: Die Email-Benachrichtigung enthält die Ausnahmedetails YSOD als Anlage.
(Klicken Sie hier, um das Bild in voller Größe anzuzeigen)

Was ist mit der Verwendung der benutzerdefinierten Fehlerseite?

In diesem Tutorial wurde gezeigt, wie Sie und den Application_Error Ereignishandler verwendenGlobal.asax, um Code auszuführen, wenn eine nicht behandelte Ausnahme auftritt. Insbesondere haben wir diesen Ereignishandler verwendet, um einen Entwickler über einen Fehler zu benachrichtigen. wir könnten sie erweitern, um auch die Fehlerdetails in einer Datenbank zu protokollieren. Das Vorhandensein des Application_Error Ereignishandlers wirkt sich nicht auf die Benutzererfahrung des Endbenutzers aus. Sie sehen weiterhin die konfigurierte Fehlerseite, sei es die Fehlerdetails YSOD, die Laufzeitfehler-YSOD oder die benutzerdefinierte Fehlerseite.

Es ist natürlich, sich zu fragen, ob die Datei und Application_Error das Global.asax Ereignis erforderlich sind, wenn eine benutzerdefinierte Fehlerseite verwendet wird. Wenn ein Fehler auftritt, wird dem Benutzer die benutzerdefinierte Fehlerseite angezeigt. Warum können wir den Code nicht einfügen, um den Entwickler zu benachrichtigen und die Fehlerdetails in der CodeBehind-Klasse der benutzerdefinierten Fehlerseite zu protokollieren? Sie können zwar Code zur CodeBehind-Klasse der benutzerdefinierten Fehlerseite hinzufügen, aber Sie haben keinen Zugriff auf die Details der Ausnahme, die das Error Ereignis ausgelöst hat, wenn Sie die technik verwenden, die wir im vorherigen Tutorial untersucht haben. Durch Aufrufen der GetLastError -Methode von der benutzerdefinierten Fehlerseite wird zurückgegeben Nothing.

Der Grund für dieses Verhalten ist, dass die benutzerdefinierte Fehlerseite über eine Umleitung erreicht wird. Wenn eine nicht behandelte Ausnahme die ASP.NET Runtime erreicht, löst die ASP.NET-Engine das Error -Ereignis aus (das den Application_Error Ereignishandler ausführt) und leitet den Benutzer dann zur benutzerdefinierten Fehlerseite um, indem ein Response.Redirect(customErrorPageUrl)ausgegeben wird. Die Response.Redirect -Methode sendet eine Antwort mit einem HTTP 302-status Code an den Client und weist den Browser an, eine neue URL anzufordern, nämlich die benutzerdefinierte Fehlerseite. Der Browser fordert diese neue Seite dann automatisch an. Sie können feststellen, dass die benutzerdefinierte Fehlerseite getrennt von der Seite angefordert wurde, auf der der Fehler aufgetreten ist, da die Adressleiste des Browsers in die URL der benutzerdefinierten Fehlerseite geändert wird (siehe Abbildung 4).

Screenshot des Browsers, der zur Benutzerdefinierten Fehlerseite umgeleitet wird, wenn ein Fehler auftritt.

Abbildung 4: Wenn ein Fehler auftritt, wird der Browser zur URL der benutzerdefinierten Fehlerseite umgeleitet.
(Klicken Sie hier, um das Bild in voller Größe anzuzeigen)

Der Nettoeffekt ist, dass die Anforderung, bei der die nicht behandelte Ausnahme aufgetreten ist, endet, wenn der Server mit der HTTP 302-Umleitung antwortet. Die nachfolgende Anforderung an die benutzerdefinierte Fehlerseite ist eine brandneue Anforderung. Zu diesem Zeitpunkt hat die ASP.NET-Engine die Fehlerinformationen verworfen und hat außerdem keine Möglichkeit, die nicht behandelte Ausnahme in der vorherigen Anforderung der neuen Anforderung für die benutzerdefinierte Fehlerseite zuzuordnen. Aus diesem Grund GetLastError wird zurückgegeben null , wenn von der benutzerdefinierten Fehlerseite aufgerufen wird.

Es ist jedoch möglich, die benutzerdefinierte Fehlerseite während derselben Anforderung auszuführen, die den Fehler verursacht hat. Die Server.Transfer(url) -Methode überträgt die Ausführung an die angegebene URL und verarbeitet sie innerhalb derselben Anforderung. Sie können den Code im Ereignishandler in Application_Error die CodeBehind-Klasse der benutzerdefinierten Fehlerseite verschieben und ihn in Global.asax durch den folgenden Code ersetzen:

Sub Application_Error(ByVal sender As Object, ByVal e As EventArgs)
    ' Get the error details
    Dim lastErrorWrapper As HttpException = _
        CType(Server.GetLastError(), HttpException)

    If lastErrorWrapper.GetHttpCode() = 404 Then
        Server.Transfer("~/ErrorPages/404.aspx")
    Else
        Server.Transfer("~/ErrorPages/Oops.aspx")
    End If
End Sub

Wenn nun eine nicht behandelte Ausnahme auftritt, überträgt der Application_Error Ereignishandler das Steuerelement auf der Grundlage des HTTP-status-Codes an die entsprechende benutzerdefinierte Fehlerseite. Da die Steuerung übertragen wurde, hat die benutzerdefinierte Fehlerseite Zugriff auf die nicht behandelten Ausnahmeinformationen über Server.GetLastError und kann einen Entwickler über den Fehler benachrichtigen und seine Details protokollieren. Der Server.Transfer Aufruf verhindert, dass die ASP.NET-Engine den Benutzer zur benutzerdefinierten Fehlerseite umleitet. Stattdessen wird der Inhalt der benutzerdefinierten Fehlerseite als Antwort an die Seite zurückgegeben, die den Fehler generiert hat.

Zusammenfassung

Wenn eine nicht behandelte Ausnahme in einer ASP.NET Webanwendung auftritt, löst die ASP.NET Runtime das Error Ereignis aus und zeigt die konfigurierte Fehlerseite an. Wir können den Entwickler über den Fehler benachrichtigen, seine Details protokollieren oder auf andere Weise verarbeiten, indem wir einen Ereignishandler für das Error-Ereignis erstellen. Es gibt zwei Möglichkeiten, einen Ereignishandler für HttpApplication Ereignisse wie Errorzu erstellen: in der Global.asax Datei oder aus einem HTTP-Modul. In diesem Tutorial wurde gezeigt, wie Sie einen Error Ereignishandler in der Global.asax Datei erstellen, der Entwickler über eine E-Mail-Nachricht über einen Fehler benachrichtigt.

Das Erstellen eines Error Ereignishandlers ist nützlich, wenn Sie nicht behandelte Ausnahmen auf eindeutige oder angepasste Weise verarbeiten müssen. Das Erstellen eines eigenen Error Ereignishandlers zum Protokollieren der Ausnahme oder zur Benachrichtigung eines Entwicklers ist jedoch nicht die effizienteste Nutzung Ihrer Zeit, da bereits kostenlose und einfach zu verwendende Fehlerprotokollierungsbibliotheken vorhanden sind, die innerhalb weniger Minuten eingerichtet werden können. In den nächsten beiden Tutorials werden zwei solche Bibliotheken untersucht.

Viel Spaß beim Programmieren!

Weitere Informationen

Weitere Informationen zu den in diesem Tutorial behandelten Themen finden Sie in den folgenden Ressourcen: