Frage

Ich bin auf der Suche nach einer einfachen Lösung Ausnahme Logging mit Fehlern in meiner ASP.Net MVC 1.0 Anwendung Handhabung kombiniert zu tun.

Ich habe viele Artikel lesen, einschließlich Fragen hier auf Stackoverflow geschrieben, die alle unterschiedliche Lösungen für unterschiedliche Situationen bieten. Ich bin noch nicht mit einer Lösung zu kommen, die meinen Bedürfnissen entspricht.

Hier sind meine Anforderungen:

  1. Um die [Handle] Attribut (oder etwas Gleichwertiges) auf meinem Controller verwenden, um alle Ausnahmen zu behandeln, die von einem der Aktionen oder Ansichten geworfen werden konnte. Dies sollte alle Ausnahmen behandeln, die nicht speziell auf eine der Aktionen behandelt wurden (wie in Punkt 2 beschrieben). Ich möchte in der Lage sein, zu bestimmen, welche anzeigen ein Benutzer im Fehlerfall umgeleitet werden müssen, für alle Aktionen im Controller.

  2. Ich möchte das [Handle] Attribut angeben können (oder etwas Gleichwertiges) an der Spitze der spezifischen Aktionen bestimmte Ausnahmen zu fangen und Benutzer Ausnahme angemessen auf einen Blick umleiten. Alle anderen Ausnahmen müssen noch vom [Handle] -Attribut auf dem Controller-behandelt werden.

  3. In beiden oben genannten Fällen möchte ich die Ausnahmen angemeldet sein, unter Verwendung von log4net (oder jede andere Logging-Bibliothek).

Wie gehe ich über die oben zu erreichen? Ich habe darum, alle meine Controller von einer Basis Controller erben lesen, die die OnException Methode überschreibt, und worin ich meine Protokollierung tun. Doch dies wird Chaos um mit Benutzern zu den entsprechenden Ansichten Umleiten, oder es chaotisch machen.

Ich habe meine eigene Filteraktion gelesen über das Schreiben, die IExceptionFilter zu handhaben implementiert, aber das wird in Konflikt mit dem [Handle] Attribut.

Bisher sind meine Gedanken, dass die beste Lösung ist mein eigenes Attribut zu schreiben, die von HandleErrorAttribute erbt. Auf diese Weise erhalte ich alle Funktionen von [Handle] und kann meine eigenen log4net Protokollierung hinzufügen. Die Lösung ist wie folgt:

    public class HandleErrorsAttribute: HandleErrorAttribute {

      private log4net.ILog log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);

      public override void OnException(ExceptionContext filterContext)
      {
          if (filterContext.Exception != null)
          {
            log.Error("Error in Controller", filterContext.Exception);
          }

          base.OnException(filterContext);
      }
   }

Wird die obige Code Arbeit für meine Anforderungen? Wenn nicht, welche Lösung meiner Anforderungen nicht erfüllt?

War es hilfreich?

Lösung

Ich bin immer noch ein wenig verwirrt mit all den verschiedenen Lösungen gibt, und wie können Attribute miteinander interferieren, aber ich ging mit dieser Lösung:

public class LogErrorsAttribute: FilterAttribute, IExceptionFilter
{
    #region IExceptionFilter Members

    void IExceptionFilter.OnException(ExceptionContext filterContext)
    {
        if (filterContext != null && filterContext.Exception != null)
        {
            string controller = filterContext.RouteData.Values["controller"].ToString();
            string action = filterContext.RouteData.Values["action"].ToString();
            string loggerName = string.Format("{0}Controller.{1}", controller, action);

            log4net.LogManager.GetLogger(loggerName).Error(string.Empty, filterContext.Exception);
        }

    }

    #endregion
}

Ich benutze immer noch die [Handle] Attribut wie in der ursprünglichen Frage erklärt, und ich dekorieren nur jeden Controller mit einem [LogErrors] Attribut.

Dies funktioniert für mich, da es die Fehlerprotokollierung an einem Ort hält und verursacht keine doppelte Ausnahmen mehrfach angemeldet sein (was passieren wird, wenn ich verlängern [Handle] und das Attribut an mehreren Stellen verwenden).

Ich glaube nicht, wird es möglich sein, sowohl die Ausnahme Protokollierung und Fehler zu kombinieren in einer atrribute oder Klasse Handhabung, ohne es sehr mühsam und komplexer werden, oder beeinträchtigen die Verwendung von [Handle]

Aber das funktioniert für mich, da ich jeden Controller nur einmal dekorieren, mit dem [LogErrors] Attribut, und dekorieren Controller und Aktionen mit [Handle] genau, wie ich will, ohne dass sie sich gegenseitig zu stören.

Update:

Hier ist ein Beispiel dafür, wie ich es verwenden:

[LogErrors(Order = 0)]
[HandleError(Order = 99)]
public class ContactController : Controller
{
    public ActionResult Index()
    {
        return View(Views.Index);
    }

    public ActionResult Directions()
    {
        return View(Views.Directions);
    }


    public ActionResult ContactForm()
    {
        FormContactMessage formContactMessage = new FormContactMessage();

        return View(Views.ContactForm,formContactMessage);
    }

    [HandleError(ExceptionType = typeof(SmtpException), View = "MessageFailed", Order = 1)]
    [AcceptVerbs(HttpVerbs.Post)]
    public ActionResult ContactForm(FormContactMessage formContactMessage)
    {
        if (ModelState.IsValid)
        {
            if (formContactMessage.IsValid)
            {
                SmtpClient client = new SmtpClient();

                MailAddress recipientAddress = new MailAddress(Properties.Settings.Default.ContactFormRecipientEmailAddress);
                MailAddress senderAddress = new MailAddress(Properties.Settings.Default.ContactFormSenderEmailAddress);
                MailMessage mailMessage = formContactMessage.ToMailMessage(recipientAddress, senderAddress);

                client.Send(mailMessage);

                return View("MessageSent");
            }
            else
            {
                ModelState.AddRuleViolations(formContactMessage.GetRuleViolations());
            }
        }
        return View(Views.ContactForm, formContactMessage);
    }

    private static class Views
    {
        public static string Index { get { return "Index"; } }
        public static string Directions { get { return "Directions"; } }
        public static string ContactForm { get { return "ContactForm"; } }

    }
}

In dem obigen Code, SmtpExceptions in der ContactForm Aktion Überlastung sind in einer ganz bestimmten Art und Weise behandelt - der Benutzer präsentiert mit View spezifisch gescheitert gesendeten Nachrichten, in diesem Fall ist es „MessageFailed“ genannt wird. Alle anderen Ausnahmen werden durch das Standardverhalten von [Handle] behandelt. Beachten Sie auch, dass die Protokollierung von Fehlern erfolgt zuerst, gefolgt von der Fehlerbehandlung. Dies wird durch die folgenden angegeben:

[LogErrors(Order = 0)]
[HandleError(Order = 99)]

Update:

Es gibt eine alternative Lösung für dieses Problem, mit einer sehr guten explanantion. Ich empfehle, durch sie zu lesen beteiligt, ein besseres Verständnis der Probleme zu erhalten.

ASP.NET MVC Handle Attribut, Fehler von benutzerdefinierten Seiten und Protokollierung Ausnahmen (Dank an Scott Shepherd unten, der den Link in einer Antwort unten zur Verfügung gestellt).

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top