2008-10-13 5 views
5

Ich versuche, mich um die Fehlerbehandlung in MVC. Was ich suchen ist eine zentrale Möglichkeit, Fehler zu finden, sie zu protokollieren, wenn möglich zu lösen, wenn nötig, andere Maßnahmen ergreifen und schließlich die richtige Sicht für den Benutzer zeigen.Handle Fehler mit ErrorController anstelle einer direkten Ansicht

Ich denke, dass ich den [HandleError] Filter dafür verwenden kann, aber ich sehe keine Möglichkeit, es zu einem Controller/Action zu leiten. Die einzige Option, die ich sehe, zeigt direkt auf eine Ansicht.

Antwort

4

HandleErrorAttribute das kommt mit MVC ist ein ziemlich einfaches IExceptionFilter.

Sie haben ein paar Optionen zu erreichen, was ich denke, Sie wollen.

Sie entweder verwenden können [Handle (Type = typeof (MyException), View = "Errorview")] auf Aktionen/Controller oder Ihre eigenen

HandleErrorAttribute ist nicht sehr komplex umzusetzen. Ich denke, MS empfiehlt Ihnen, diesen Code zu kopieren und an Ihre Anforderungen anzupassen.

Die OnException-Überschreibung ermöglicht Ihnen den Zugriff auf alle Informationen, die Sie möglicherweise benötigen - Controller, Aktion, Routendaten usw. - über ExceptionContext.

Denken Sie daran, ExceptionHandled zu setzen. Dann können Sie filterContext.Result auf eine neue RedirectToAction-Instanz setzen, die auf Ihren ErrorController und Ihre Aktion umleitet - offensichtlich können Sie den spezifischen Controller und die Aktion mit Eigenschaften versehen.

+0

Der Standard-HandleError erlaubt mir nicht, zu einem Controller zu leiten, denke ich. Das brauche ich nicht. Ich denke, ich muss dann meine eigenen rollen. Haben Sie kein gutes Material, um hier zu referenzieren? –

+0

Yup, http://haacked.com/archive/2008/08/14/aspnetmvc-filters.aspx – CVertex

+1

Jep, bemerkte die Links in Ihrer Antwort ein bisschen spät: P Danke. Ich erstelle jetzt ein RerouteFilterAttribute. Ich habe jetzt ein paar Versuche/Fehler, aber ich komme dorthin. –

1

Warum erstellen Sie nicht Ihr eigenes ErrorResult von ActionResult?

0

Was ich tue (was kann oder auch nicht eine gute Praxis sein), ist dies:

Wenn ein Fehler auftritt:

  • Wenn ich es erwartet und damit umgehen kann, kann ich (Anmeldung mit ELMAH)
  • Wenn ich es erwartet hatten und es nicht verarbeiten kann, ich log es ELMAH und eine Viewresult zurück, die Seite meine Fehler
    • Fügen sie eine Beschreibung des Fehlers ist, eine Standard-Nachricht und ein Link zurück zu dem, was ich dabei wurde
  • Wenn ich es nicht erwarten, meine Überschreibung von OnError in meiner Basis-Controller-Klasse macht den vorherigen Schritt
  • Alle anderen Fehler, die von ELMAH automatisch protokolliert werden können nicht bearbeitet werden und die Anfrage yellowscreens

Die meisten meiner allgemeinen Fehlerbehandlung geht in der Basisklasse für alle meine Controller. Das einzige Problem ist, dass ich einen Controller und einen Action-Wert in der Basisklasse manuell setzen muss, damit er einen ActionLink für die Weiterleitung auf der Fehlerseite generieren kann.

+0

Filter scheinen der Weg für die Fehlerbehandlung zu sein, anstatt einen Fehler zu überschreiben. Sie sind schön orthogonal zu Controllern. – CVertex

+0

Schätzen Sie die Rückmeldung, aber ich würde lieber nicht die Fehlerbehandlung in die gleiche Klasse wie meine Basis-Controller setzen. Dies würde meine Basisklasse weniger wiederverwendbar machen, da die Fehlerbehandlungslogik normalerweise für jede Site unterschiedlich ist. Ich erstelle gerade einen RerouteErrorAttribute-Filter, um die Aufgabe zu erledigen. –

2

Leppi, iWenn Sie an Action Result senden möchten, können Sie Aktion und Controller zum Umleiten bei Fehler definieren. Es ist ein gutes Beispiel, aber persönlich mag ich keine benutzerdefinierten Seiten oder http Codes zu Codes

Hier ist und Beispiel für meine IExtensionFilter. Mein Base Controler hat einen Standard-IExceptionFilter, um alle nicht kontrollierten Fehler zu verarbeiten.

[SuppressMessage("Microsoft.Performance", "CA1813:AvoidUnsealedAttributes", 
    Justification = "This attribute is AllowMultiple = true and users might want to override behavior.")] 
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = true)] 
public class GenericExceptionHandlerFilter : ActionFilterAttribute, IExceptionFilter 
{ 

    public Type ExceptionType { get; set;} 
    public string RedirectToAction { get; set;} 
    public string RedirectToController { get; set;} 

    protected bool ApplyFilter(ExceptionContext filterContext) 
    { 
     Type lExceptionType = filterContext.Exception.GetType(); 
     return (ExceptionType == null || 
       lExceptionType.Equals(ExceptionType)); 
    } 


    #region IExceptionFilter Members 
    public void OnException(ExceptionContext filterContext) 
    { 

     if (ApplyFilter(filterContext)) 
     { 
      IbfControllerLogger.Log(filterContext.Exception); 

      filterContext.ExceptionHandled = true; 

      #region Calculate Action Controller Error 
      RouteValueDictionary lRoutes = new RouteValueDictionary(new 
       { 
        action = RedirectToAction, 
        controller = String.IsNullOrEmpty(RedirectToController) ? (string)filterContext.RouteData.Values["controller"] : RedirectToController 
       }); 
      UrlReWriterUtils.UrlReWriter(filterContext.Controller.ViewData, lRoutes); 
      #endregion 

      filterContext.Controller.TempData[TempDataName.C_TEMPDATA_EXCEPTIONERROR] = filterContext.Exception; 
      filterContext.Result = new RedirectToRouteResult(lRoutes); 
     } 
    } 
    #endregion