2015-05-06 2 views
8

Ich habe ein ziemlich interessantes Problem mit der benutzerdefinierten Fehlerseiten-Verwaltung für eine neue ASP.NET MVC-Anwendung.ASP.NET MVC customError Seite wird nicht für einige der 400 Fehler angezeigt

Dieses Problem ist wie folgt:
- wenn ich eine URL bin Aufruf (egal welche) mit einem „schlechten“ Argumente am Ende der URL, wie ..../c<, wird die Anwendung der Anzeige der richtigen Serverfehler Seite wie in der web.config angewiesen;
- wenn ich die URL in eine unangenehmere ändere, wie .../<c (um mehr wie ein HTML-Tag zu sehen, gibt es keine Serverfehlerseite mehr im Browser angezeigt und stattdessen bekomme ich eine einfache YSOD mit einer Nachricht wie An exception occurred while processing your request. Additionally, another exception occurred while executing the custom error page for the first exception. The request has been terminated.

nach ELMAH endeten beiden Anträge mit einem 400-Statuscode und die Nachricht Wesen:
- für den ersten: System.Web.HttpException (0x80004005): A potentially dangerous Request.Path value was detected from the client (<). at System.Web.HttpRequest.ValidateInputIfRequiredByConfig() at System.Web.HttpApplication.PipelineStepManager.ValidateHelper(HttpContext context)
- für die zweiten: System.Web.HttpException (0x80004005): A potentially dangerous Request.Path value was detected from the client (<). at System.Web.HttpRequest.ValidateInputIfRequiredByConfig() at System.Web.HttpApplication.PipelineStepManager.ValidateHelper(HttpContext context)

So, Beide Fehler sind identisch, der Statuscode ist derselbe, aber für einen der Fehler wird die benutzerdefinierte Fehlerseite nicht getti ng angezeigt. Ich bin auch auf global.asax im Debug-Modus gegangen und überprüft die Server.GetLastError() in protected void Application_Error(object sender, EventArgs e) und wieder, beide Fehler waren die gleichen, nichts ist anders.

In web.config, das ist, wie mein <customErrors> Tag wie folgt aussieht:

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

Kann mir bitte jemand sagen, warum das Verhalten in diesen beiden Fällen unterschiedlich ist?

Vielen Dank für Ihre Zeit.

+0

Worauf hosten Sie? Cassini? IIS6? IIS7 +? –

+0

IIS 8.5 (Windows 8.1) und auch Azure-Website. – Edi

Antwort

12

Es gibt viele Fehlinformationen und/oder veraltete Lösungen zur Fehlerbehandlung in IIS 7+. Die wichtigsten Dinge zu verstehen sind: -

  • .NET 4.0 machte brechen Änderungen an ASP.NET Anfrage Validierung.
  • IIS 7+ führte eine neue Methode zur Verarbeitung von benutzerdefinierten Fehlerseiten ein.

Die meisten Menschen Sammelsurium Lösungen verwenden alle customErrors, httpErrors die Application_Error Handler beteiligt, und oft requestValidationMode="2.0" auf der httpRuntime-Eigenschaft und/oder vollständig Anforderungsvalidierung deaktivieren! Dies macht es wirklich schwierig, die Lösungen anderer Leute zu verwenden, weil alle und alle diese das Verhalten beeinflussen können. Ich hatte eine schnelle Suche und fand einige Halbduplexe ohne angenommene Antworten, wahrscheinlich aus diesem Grund.

Der Grund, warum diese zwei Fehler Ihnen ein unterschiedliches Verhalten geben, ist, dass sie bei verschiedenen Stufen in der Anforderungspipeline auftreten. Der customErrors Knoten in Ihrem web.config interagiert mit Fehlern "innerhalb" Ihrer Anwendung, während die Überprüfung der Anforderung stattfindet "außerhalb" Ihre Anwendung. IIS lehnt die gefährliche Anforderung vor ab, die zu Ihrem Anwendungscode kommt, und so Ihre customErrors Ersetzung nicht geschieht.

Also, wie reparieren wir das?

Idealerweise möchten Sie eine Lösung mit möglichst wenigen beweglichen Teilen. IIS7 gibt uns eine neue Möglichkeit, Fehlerseitenersatz auf der IIS-Ebene statt auf der Anwendungsebene anzugeben - httpErrors Knoten. Auf diese Weise können wir alle unsere Fehler an einem Ort fangen: -

<configuration> 
    ... 
    <system.webServer> 
    ... 
    <httpErrors errorMode="Custom" existingResponse="Replace"> 
     <clear /> 
     <error statusCode="400" responseMode="ExecuteURL" path="/ServerError.aspx"/> 
     <error statusCode="403" responseMode="ExecuteURL" path="/ServerError.aspx" /> 
     <error statusCode="404" responseMode="ExecuteURL" path="/PageNotFound.aspx" /> 
     <error statusCode="500" responseMode="ExecuteURL" path="/ServerError.aspx" /> 
    </httpErrors> 
    ... 
    </system.webServer> 
    ... 
</configuration> 

Wenn Sie über SEO kümmern (! Und Sie sollten), haben Sie noch sicherstellen, dass der Controller/Seite setzt einen entsprechenden Statuscode: -

this.Response.StatusCode = 500; // etc. 

Sie sollten Ihren customErrors Knoten vollständig entfernen. Es wird normalerweise für die Abwärtskompatibilität verwendet. Sie sollten auch sicherstellen, dass requestValidationModenicht auf dem Knoten httpRuntime festgelegt ist. (! Außer, natürlich, Fehler beim Parsen von web.config): - ASP.NET MVC Custom Errors

MSDN Dokumentation: -

Dies sollte die meisten Fehler

Verwandte fangen http://www.iis.net/configreference/system.webserver/httperrors

Hinweis: in Ihrem Fall, Wenn Sie defaultPath auf dem Knoten httpErrors festlegen möchten, erhalten Sie eine Sperrverletzung wegen ApplicationHost.config Einstellungen. Sie können entweder tun, was ich tat und setzen nur path individuell für die Fehlercodes, die Sie interessieren, oder Sie können auf die Erschließung des Knotens einen Blick: -

Meine Intuition ist, dass es in Umgebungen mit geringer Kontrolle wie Azure App Service/Azure-Websites mehr Probleme bereitet als es lohnt. Sie können auch die Pfade für einzelne Statuscodes festlegen.

Ich habe eine full working example of using httpErrors for custom error pages up on github gesetzt. Sie können auch see it live on azure web sites.

+0

Bei weitem ist dies die detaillierteste und perfekte Antwort, die ich seit Jahren gesehen habe. Vielen Dank!!! Es funktioniert perfekt !!! – Edi

+0

Ich bin zurück mit einer weiteren Frage: es scheint, dass ich in meiner web.config ein HttpModule (ImageProcessorModule) konfiguriert habe, das alle meine Anrufe abfängt (ist ganz normal), aber wenn ich mich mit der 'A möglicherweise gefährlichen Anfrage befasse. RawUrl-Wert wurde vom Client erkannt ", ich sehe den Fehler im Klartext und keine 500 benutzerdefinierte Fehlerseite wird angezeigt; Wenn ich jedoch dieses Modul auskommentiere, um die Anfragen nicht abzufangen, sehe ich die benutzerdefinierte Fehlerseite ... Was fehlt mir? Warum zeigt das System die benutzerdefinierte Fehlermeldung nicht an, obwohl die web.config dies sagt ?! Vielen Dank!!! – Edi

+0

Sie könnten das am besten als separate Frage mit mehr Informationen veröffentlichen. Ich bin mir der Fälle bewusst, in denen Fehler in httpModules Probleme mit benutzerdefinierten Fehlern verursacht haben, aber ich würde mehr brauchen, um weiterzumachen, bevor ich es eingrenzen konnte. –

Verwandte Themen