Was sind die endgültigen Richtlinien für die benutzerdefinierte Fehlerbehandlung in ASP.NET MVC 3?


44

Der Prozess der benutzerdefinierten Fehlerbehandlung in ASP.NET MVC (3 in diesem Fall) scheint unglaublich vernachlässigt zu werden. Ich habe die verschiedenen Fragen und Antworten hier im Internet gelesen, Hilfeseiten für verschiedene Tools (wie Elmah), aber ich habe das Gefühl, dass ich mich in einem vollständigen Kreis befinde und immer noch nicht die beste Lösung habe. Vielleicht können wir mit Ihrer Hilfe einen neuen Standard für die Fehlerbehandlung setzen. Ich möchte die Dinge einfach halten und dies nicht übertreiben.

Hier sind meine Ziele:

Für Serverfehler / Ausnahmen:

  1. Debugging-Informationen in dev anzeigen
  2. Zeigen Sie eine freundliche Fehlerseite in der Produktion an
  3. Fehler protokollieren und per E-Mail an den Administrator in der Produktion senden
  4. Gibt 500 HTTP-Statuscode zurück

Für 404 Not Found-Fehler:

  1. Freundliche Fehlerseite anzeigen
  2. Fehler protokollieren und per E-Mail an den Administrator in der Produktion senden
  3. 404-HTTP-Statuscode zurückgeben

Gibt es eine Möglichkeit, diese Ziele mit ASP.NET MVC zu erreichen?


2
Ich möchte, dass diese Frage ZURÜCK nach SO migriert wird, damit sie mehr Antworten erhält. Ich suche codierte Antworten.
Shawn Mclean

@ Shawn Das ist unwahrscheinlich. Die Frage ist hier mehr thematisch als SO und hat eine akzeptierte Antwort. Auch Fragen werden aus technischen Gründen in der Regel nicht re-migriert. Wenn Sie Hilfe beim Codieren eines bestimmten Fehlerbehandlungsansatzes benötigen, öffnen Sie eine neue Frage zu StackOverflow. Andernfalls können "codierte Antworten" ein zu weites Kriterium sein, um nützlich oder beantwortbar zu sein. Last but not least ist der beste Weg, um die Aufmerksamkeit des Moderators auf eine Frage zu lenken, diese zu markieren. Ihr Kommentar hier wäre wahrscheinlich unbemerkt geblieben, wenn er keine automatische Markierung ausgelöst hätte, indem er die Anzahl der Kommentare auf über 20 gesetzt hätte.
Adam Lear

Früher gab es hier ungefähr 10 Kommentare, wo sind sie alle hingegangen?
RyanW

Ich habe eine Lösung gefunden, die Ihren Zielen entspricht. Ich habe es als eine andere Antwort auf SO: stackoverflow.com/questions/6508415/…
Jesse Webb

1
@AnnaLear Ich stimme Shawn zu. Ich habe diese Seite nur über Google gefunden. Beachten Sie, dass fast alle der folgenden Antworten Links ZURÜCK zum Stapelüberlauf enthalten. Für mich spricht das Bände, denn es hätte überhaupt dort bleiben sollen.
Rebecca

Antworten:


23

Ich werde erzählen, wie ich das gemacht habe, das war Teil der ursprünglichen Frage.

Zunächst die Probleme, auf die ich gestoßen bin:

  1. Wenn customErrors aktiviert ist (dh in der Produktion) HandleError, verschluckt das globale Attribut Ausnahmen und rendert Ihre Fehleransicht. Sie können es jedoch nicht mit einem Addon-Tool wie elmah protokollieren, da elmah es nie sieht. Sie könnten es Ihrer Ansicht nach protokollieren, aber es ist eine Ansicht, die falsch zu sein scheint. Das globale HandleError-Attribut wird in der MVC 3 RTM Visual Studio-Projektvorlage als neu angezeigt.

  2. customErrors mit URLs für MVC-Endpunkte geben 302 Statuscodes zurück. Es gibt die redirectmode-Eigenschaft, aber Sie können keine MVC-URLs in customErrors abgleichen und den ResponseRewrite-Modus verwenden. ( https://stackoverflow.com/questions/781861/customerrors-does-not-work-when-setting-redirectmode-responserewrite/3770265#3770265 )

  3. Das vollständige Vermeiden von customErrors und das Behandeln aller benutzerdefinierten Elemente in Ihrer App führt zu einer hohen Komplexität, IMO. (Geliebt: https://stackoverflow.com/questions/619895/how-can-i-properly-handle-404s-in-asp-net-mvc/2577095#2577095 , aber es war nicht richtig für unser Projekt)

Meine Lösung

Ich habe MVC komplett aus der Gleichung genommen. Ich habe den HandleErrorAttributeglobalen Filter in global.asax entfernt und mich ganz auf die customErrors-Konfiguration konzentriert, indem ich ihn auf die Verwendung von WebForm-Umleitungen und den Umleitungsmodus auf umgestellt habe ResponseRewrite, um die 302 HTTP-Antwortcodes zu vermeiden.

<customErrors mode="On" defaultRedirect="/Error.aspx" redirectMode="ResponseRewrite">
  <error statusCode="404" redirect="/NotFound.aspx" />
</customErrors>

NotFound.aspxSetzen Sie dann im Ereignis Response.StatusCodepage_load den Wert auf 404 und in der Datei Error.aspx den Code 500.

Ergebnisse:

Die Ziele für beide wurden mit den Elmah-Protokollen, der angezeigten Fehlerseite und dem Statuscode mit einer Codezeile auf den Code-Behinds erreicht. Wir machen es nicht auf die "MVC-Art" wie die frühere Lösung, aber ich bin damit einverstanden, wenn es sich um zwei Codezeilen handelt.


5

Ich denke, dass MVC, ASP und Ihr bevorzugtes Protokollierungs- / Ausnahmebehandlungs-Framework Ihre Ziele recht gut handhaben können. Sowohl ELMAH als auch Enterprise Library bieten eine benutzerfreundliche Ausnahmebehandlung und Protokollierung. Wählen Sie also Ihren Favoriten aus. Ich werde hier nicht auf die Vor- und Nachteile eingehen.

HINWEIS: Sie können keine benutzerfreundliche Fehlerseite anzeigen UND kein HTTP 404 oder 500 zurückgeben, wie in Ihrer Frage vorgeschlagen. Wenn Sie eine angezeigte Fehlerseite zurückgeben, lautet der an Ihren Browser zurückgegebene HTTP-Code 302. Dies ist eine Weiterleitung zur angezeigten Fehlerseite.

Freundliche Fehlerseiten

Es hört sich so an, als könnten Sie Ihre Ziele mit den altmodischen web.config-Einstellungen erreichen, die seit einiger Zeit Teil von ASP.net sind. Sie erwähnen das Anzeigen von Debug-Informationen in dev und das Anzeigen benutzerfreundlicher Seiten in production. Sie können dazu den benutzerdefinierten Fehlerbereich der web.config verwenden (Set CustomErrors = "Off", um Debug-Informationen anzuzeigen). Ich gehe davon aus, dass Sie mit dem CustomErrors-Attribut vertraut sind, wenn Sie es nicht lesen:

http://msdn.microsoft.com/en-us/library/h0hfz6fc.aspx

Wenn Sie genauer steuern möchten, welche Fehleransichten angezeigt werden, verwenden Sie das HandleError-Attribut von MVC. Auf diese Weise können Sie für jede Aktion / Steuerung unterschiedliche Fehleransichten auswählen.

http://weblogs.asp.net/scottgu/archive/2008/07/14/asp-net-mvc-preview-4-release-part-1.aspx

Ausnahmeprotokollierung

Es hört sich so an, als ob Sie auf alle Ihre Ausnahmen auf dieselbe Weise reagieren möchten ('Fehler protokollieren und per E-Mail an den Administrator in der Produktion senden'). In diesem Fall können Sie am einfachsten Code hinzufügen

Application_Error (Objektabsender, EventArgs e)

in deinem global.asax. Hier können Sie an das von Ihnen gewählte Protokollierungsframework übergeben.

Wenn Sie mehr Kontrolle über die Protokollierung / Behandlung von Ausnahmen haben möchten, können Sie HandleErrorAttribute in Unterklassen unterteilen und überschreiben

OnException(System.Web.Mvc.ExceptionContext filterContext)

Dies ist ein weiterer Ort, an dem Sie an das von Ihnen gewählte Protokollierungsframework weitergeben können.

https://stackoverflow.com/questions/183316/asp-net-mvc-handleerror

Dies gibt Ihnen mehr Kontrolle als die oben erwähnte Application_Error-Technik.

Im Allgemeinen können Sie mit MVC die Fehlerbehandlung sehr genau steuern. Wenn Sie dieses Steuerelement nicht benötigen, können Sie auf die ASP.net-Methoden zurückgreifen, um beispielsweise Fehlerseiten in Ihrer web.config zu definieren.


Vielen Dank für das Hinzufügen Ihrer Gedanken. Ich denke, der 302-Statuscode ist eine schlechte Designauswahl des ursprünglichen ASP.NET-Teams. Darauf werde ich auch in meinen Antworten eingehen, dazu gibt es einige Möglichkeiten. Es scheint, dass einige in der MVC-Welt customErrors komplett aufgeben und alles in der App verwalten, um eine bessere Wiederverwendbarkeit und mehr Kontrolle zu gewährleisten. Aber ich hatte nur begrenzten Erfolg bei der Implementierung dieser und fügte eine Menge Code hinzu, der besser zu sein schien. Mehr in meinen Antworten unten.

Ich bevorzuge es, die OnException-Methode für die Protokollierung zu überschreiben, auf diese Weise weiß ich, dass ich alles protokollieren kann, auch Fehler, die durch einen Ajax-Aufruf auftreten und bei denen ich feststelle, dass sie Ihren Application_Error nicht auslösen.
Alicia

@Alicia vollständiger Beispielcode?
Kiquenet
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.