2010-08-18 6 views
9

Ich verwende eine generische Fehlerseite mit ASP.NET <customErrors> Direktive.Wie wird der Statuscode "500" für die generische Fehlerseite in IIS gesendet?

<customErrors mode="On" defaultRedirect="500.html" redirectMode="ResponseRewrite"> 
</customErrors> 

Problem - wenn ein Fehler auftritt, gibt diese Seite nicht den HTTP-Status "500" zurück. Es kommt als 200. So sehen Link Checker und Spider nicht, dass es ein Problem gibt.

Wie kann ich den 500 HTTP-Status zusammen mit der statischen 500.html-Seite senden?

Anforderungen:

  • muss ich redirectMode = "ResponseRewrite"
  • kann ich nicht verwenden, um eine dynamische Seite, nur statische HTML verwenden.

Antwort

7

Die MSDN-Dokumentation für das Element customErrors gibt an, dass es von System.Web.Configuration.CustomErrorsSection implementiert wird. Wenn wir den .NET Reflector von Red Gate zur Analyse dieser Klasse verwenden, können wir sehen, wo diese Einstellung im Framework verwendet wird.

Es wird von System.Web.UI.Page.HandleError und System.Web.HttpResponse.ReportRuntimeError verwendet.

Beide rufen System.Web.HttpResponse.RedirectToErrorPage auf.(Der Name dieser Methode ist verwirrend: Es ist wichtig zu beachten, dass RedirectToErrorPage die redirectMode-Einstellung als Parameter verwendet, also auch wenn Sie ResponseRewrite verwenden und tatsächlich keine Umleitung stattfindet.)

Der relevante Teil der RedirectToErrorPage Methode ist:

if (redirectMode == CustomErrorsRedirectMode.ResponseRewrite) 
    { 
     this.Context.Server.Execute(url); 
    } 

es gibt keinen Weg zu sein scheint den Antwortcode in der Fehlerbehandlung zu setzen: am Ende des Tages ist es nur eine Ebene Server.Execute. Es scheint daher unvermeidlich, dass Sie Code schreiben müssten, um die gewünschte HTTP-Antwort zu erreichen.

Können Sie überprüfen, warum Sie eine einfache HTML-Datei verwenden möchten? Dies scheint eine sinnvolle Wahl für die Fehlerbehandlung zu sein, da Sie nicht den gesamten Overhead einer ASPX-Seite durchgehen müssen, wenn dies zu einem anderen Fehler führen könnte.

Aber vielleicht gibt es einen Mittelweg, der genauso robust ist wie eine .html-Datei?

Sie könnten beispielsweise einen vorkompilierten HttpHandler erstellen, ihn in der URL /500.error registrieren und dann 500.error Ihre defaultRedirect-Seite machen. (Dies wäre ähnlich wie ScriptResource.axd funktioniert.) Wenn Sie Ihr Modul in eine DLL vorkompilieren (im Gegensatz zu On-The-Fly-Kompilierung aus einer einfachen alten .axd-Datei), finden Sie möglicherweise, dass es in der gleichen Weise robust ist Gesicht der Fehlerbedingungen. Wenn ein Fehler auftritt, bei dem nicht einmal das funktioniert, funktioniert wahrscheinlich auch eine statische .html-Datei nicht. Beachten Sie, dass die customErrors-Direktive immer noch auf .NET unter der Haube basiert und weiterhin StaticFileHandler verwendet Ihre .html-Datei.

Alternativ könnten Sie auch einen Reverse Proxy vor Ihrer IIS-Anwendung in Erwägung ziehen, der selbst bei einem katastrophalen Ausfall des Anwendungspools eine freundliche 500-Seite liefert. Dies wäre mehr Arbeit zum Einrichten, wäre aber noch robuster als customErrors, z. Wenn Ihre web.config beschädigt wird, funktionieren selbst customErrors nicht.

+1

Sie zeigen, dass von ASP.NET abhängig ist. Ich habe 500.html verwendet, um die Abhängigkeit von ASP.NET zu umgehen, aber es ist müßig, wenn ASP.NET nicht reagiert. Ich denke, meine beste Wette ist es, einen 500.aspx in zu verwenden, und eine Sicherungskopie der 500.html-Fehlerseite auf der IIS-Ebene zu konfigurieren, falls ASP.NET nicht verfügbar ist. – frankadelic

1

Versuchen Sie benutzerdefinierte Fehler Abschnitt wie folgt konfigurieren:

<customErrors mode="On" redirectMode="ResponseRewrite"> 
    <error statusCode="500" redirect="500.aspx"> 
</customErrors> 

In Ihrer 500.aspx Datei, den Response-Code in der page_load ändern;

Response.StatusCode = 500; 
Response.StatusDescription = "Internal Server Error"; 
+0

Ich brauche redirectMode = "ResponseRewrite", also ist dies keine Option für mich. – frankadelic

+0

Außerdem sendet Ihre Lösung keinen 500 HTTP-Status ... Wie beschrieben, führt sie eine 302-Weiterleitung zu 500.html durch. 500.html selbst hat einen 200 HTTP-Status. Überprüfen Sie es in Firebug. – frankadelic

+0

modifizierte Antwort auf Frage. –

4

In Ihrer gllobal.asax Datei fügen Sie den folgenden Code

protected void Application_EndRequest(object sender, EventArgs e) 
    { 
     if (Request.Url.AbsolutePath.EndsWith("500.html")) 
      Response.StatusCode = 500; 
    } 
+0

Benötigt dies IIS7 + Integrierte Pipeline? Anfragen für .html würde sonst Application_EndRequest nicht auslösen. – frankadelic

+0

Entschuldigung, ich habe nicht beachtet, dass die Fehlerseitenerweiterung HTML ist, gibt es irgendein Problem damit, es eine aspx Seite zu sein. Sie müssten sich in diesem Fall keine Sorgen um IIS machen. Auch wenn ich nicht falsch bin, sollte IIS 6 auch Möglichkeiten haben, HTML-Anfrage an Aspnet-Handler umzuleiten. Ich habe keinen Zugriff auf eine Maschine mit IIS 6 installiert –

+0

siehe meinen zweiten Punkt ... es muss eine statische HTML-Datei sein. – frankadelic

3

OK, ich habe eine Lösung habe, die einzige Art, wie ich dies an der Arbeit kann unter Umgehung des benutzerdefinierten Fehler Abschnitt in der Bahn Konfigurationsdatei.

So ein Beispiel default.aspx

public partial class Default : System.Web.UI.Page 
{ 
    protected void Page_Load(object sender, EventArgs e) 
    { 
     throw new Exception("boom"); 
    } 
} 

Dann in der Datei global.asax:

protected void Application_Error(object sender, EventArgs e) 
{ 
    // Clear the error to take control of process 
    Server.ClearError(); 

    Response.WriteFile(Server.MapPath("500.html")); 
    Response.StatusCode = 500; 
    Response.StatusDescription = "Internal Server Error"; 
} 

Sie können sich wahrscheinlich einen besseren Handling Mechanismus für den 500.html Teil schreiben - ich glaube, Dies sollte tun, was Sie erreichen wollen.

Nur getestet mit VS Cassini Webserver, aber ich sehe keinen Grund, warum das in iis6 nicht funktionieren sollte.

-1

Wenn Sie darauf bestehen, auf den Kern HTTP Wechsel signalisiert dann müssen Sie entweder auf einige Forderungen nachgeben oder vorbereitet werden, um Ihren eigenen Web-Server zu schreiben. Ja, Sie haben laufen IIS7 AppPool integriert und Sie können nach wie vor Umleitung auf und aktive Seite akzeptieren müssen, da Sie zu fälschen versuchen, dass Ihr Server ausgefallen ist und der Server ist nicht auf gefälschten Selbstmord entworfen. Also, wenn es Ihnen eine schlanke Möglichkeit gibt, es zu tun, sind Ihre Möglichkeiten, entweder Dank zu sagen oder entwickeln Sie Ihren eigenen, nicht-HTTP-konformen Server, der Antwortcodes nach Belieben verschlüsseln wird.

+0

Versuchen Sie Folgendes: Erstellen Sie eine klassische ASP-Seite mit Division durch Null (1/0), und führen Sie sie aus. Sie werden sehen, dass eine statische Fehlerseite zurückgegeben wird und der HTTP-Status tatsächlich 500 ist (bestätigen Sie mit Firebug oder Fiddler2). Es ist nicht Server Tod/Selbstmord, es bedeutet nur, dass ein Fehler aufgetreten ist. Keine "Core HTTP Signalisierung" wurde geändert. Sie können den Inhalt der Fehlerseite mithilfe des IIS-Managers> Fehlerseiten neu konfigurieren. Mein Problem ist, dass diese Einstellung nicht für ASPX-Seiten gilt. Ich kann eine Umleitung zu einer HTML-Datei in in web.config einfügen, aber die resultierende Seite gibt einen 200-Status zurück. – frankadelic

+0

sagst du, dass für einen internen Serverfehler (zum Beispiel von einer Ausnahme) der korrekte HTTP-Statuscode 302 ist? oder 200? Gibt einen 302 oder 200 Statuscode NICHT extrem verschlüsselt zurück? : -> – Myster

+0

Die einzige Sache, die "verschlüsselt" wird, ist ASP.NET-Behandlung von Fehlercodes. Das Auslösen einer Ausnahme- und Rückgabe- und Fehlerseite sollte keinen Antwortcode von 200 oder 302 ergeben. Es sollte 500 sein, um "etwas kaputt" anzuzeigen. –

0

Dies könnte mit einem Isapi-Filter erfolgen. Es müsste in c geschrieben werden, aber es kann den Antwortstatus für die HTML-Anfrage ändern, so dass der Browser eine 500 mit Ihnen angepasste HTML-Seite erhält.

Verwandte Themen