2010-12-21 10 views
63

Ich habe einen ASP.Net-Einzeldatei-Webdienst (eine .ashx-Datei mit einer IHttpHandler Implementierung), die Fehler als Antworten mit 500 internen Serverfehler Statuscodes zurückgeben kann. Dies ist eine relativ einfache Sache in PHP zu tun:Wie wird ein Statuscode 500 in ASP.Net gesendet und trotzdem in die Antwort geschrieben?

header("HTTP/1.1 500 Internal Server Error"); 
header("Content-Type: text/plain"); 
echo "Unable to connect to database on $dbHost"; 

Die ASP.Net (C#) gleichwertig sein sollte:

Context.Response.StatusCode = (int)HttpStatusCode.InternalServerError; 
Context.Response.ContentType = "text/plain"; 
Context.Response.Write("Unable to connect to database on " + dbHost); 

Natürlich ist dies nicht wie erwartet funktionieren; Stattdessen fängt IIS den 500-Statuscode ab, löscht alles, was ich an das Objekt Response geschrieben habe, und sendet entweder Debug-Informationen oder eine benutzerdefinierte Fehlerseite, je nachdem, wie die App konfiguriert ist.

Meine Frage - wie kann ich dieses IIS Verhalten unterdrücken und Fehlerinformationen direkt von meiner IHttpHandler Implementierung senden?

Diese App ist ein Port von PHP; Die Client-Seite ist bereits geschrieben, also bin ich im Wesentlichen mit dieser Spezifikation fest. Das Senden von Fehlern mit einem 200-Statuscode passt leider nicht in die Form.

Idealerweise muss ich das Verhalten programmatisch steuern, da dieser Teil eines SDK ist, dass wir ohne „bearbeiten diese Datei“ und verteilen wollen „diese IIS ändern Einstellung“ Zusatzanleitung.

Danke!

Bearbeiten: Sortiert. war das Ticket. Beeindruckend.

+2

Wenn möglich, dass ich auf einem Produktionsstandort interne Informationen vermeiden würde, wie die Datenbankposition heraus geben - Hacker diese Sachen lieben es, sehr viel einfacher macht ihre Angriffe. – devstuff

+1

Guter Punkt, aber das ist ein gesicherter Web-Service, keine Website. Datenbankverbindung wird nicht einmal ohne vorher erfolgreiche HTTP-Authentifizierung versucht :) –

Antwort

101

+5

Unterstützt in IIS7 - http://msdn.microsoft.com/en-us/library/system.web.httpresponse.tryskipiiscustomererrors%28v=VS.90%29.aspx – AUSteve

+0

Es sind Antworten wie diese, die mich erkennen lassen, dass das Durchkämmen von Framework Objektreferenzen zu einer verlorenen Kunst wird. Wenn ich zweimal Upvote machen könnte, würde ich es tun. –

0

Möglicherweise möchten Sie eine customErrors-Seite einrichten (konfigurierbar über web.config). Sie können Ihren Inhalt über Anfragen in Session speichern (oder über einen alternativen Mechanismus) und dann asp.net konfigurieren, um die benutzerdefinierte Fehlerseite anzuzeigen, die wiederum Ihre benutzerdefinierte Ausgabe anzeigt.

Ein Wort der Vorsicht: Wenn die 500 wegen eines grundlegenden Problems mit der Anwendung (dh StackOverflowException) verursacht wird und Sie versuchen, eine Seite anzuzeigen, die auf asp.net (dh MyCustomErrors.aspx) abhängt, Sie kann in einer Schleife enden.

Weitere Informationen finden Sie unter this page.

+0

Danke Bobby. Ich bin vertraut mit der customErrors-Direktive, aber leider hängt es von der Bearbeitung der Datei web.config ab, die unsere Benutzer möglicherweise nicht ausführen können.Eine mögliche Lösung besteht darin, die Datei web.config programmgesteuert zu ändern, aber dies ist offensichtlich nicht ideal. –

8

Ich habe die folgenden in der Vergangenheit verwendet und war in der Lage, einen 503-Fehler mit einer benutzerdefinierten Nachricht mit dem unten gezeigten Code in der Page_Load-Methode zu werfen. Ich verwende diese Seite hinter einem Load Balancer als Ping-Seite für den Load Balancer, um zu wissen, ob ein Server in Betrieb ist oder nicht.

Hoffe, das hilft.

 protected void Page_Load(object sender, System.EventArgs e) 
    { 
     if (Common.CheckDatabaseConnection()) 
     { 
      this.LiteralMachineName.Text = Environment.MachineName; 
     } 
     else 
     { 
      Response.ClearHeaders(); 
      Response.ClearContent(); 
      Response.Status = "503 ServiceUnavailable"; 
      Response.StatusCode = 503; 
      Response.StatusDescription= "An error has occurred"; 
      Response.Flush(); 
      throw new HttpException(503,string.Format("An internal error occurred in the Application on {0}",Environment.MachineName)); 
     } 
    } 
+0

Hallo Paige. War dies eine .ashx-Datei oder eine normale ASPX-Datei? Ich habe versucht, die Clear/Flush-Methoden hinzuzufügen und es machte keinen Unterschied. Ich habe auch versucht, eine neue HttpException zu werfen, und ich habe gerade etwas zusätzlichen unerwünschten HTML-Unsinn bekommen. Trotzdem netter Versuch. –

+0

Neil. Dies war von einer regulären ASPX-Seite. Leider habe ich verpasst, dass du mit einer .ashx-Datei arbeitest. –

+0

Arbeitete perfekt für mich, danke. –