Es gibt jetzt ein ELMAH.MVC-Paket in NuGet, das eine verbesserte Lösung von Atif enthält und auch einen Controller, der die elmah-Schnittstelle innerhalb des MVC-Routings behandelt (keine Notwendigkeit mehr, dieses axd zu verwenden)
Das Problem bei dieser Lösung (und bei allen anderen hier) ist, dass auf die eine oder andere Weise der Elmah-Fehlerhandler tatsächlich den Fehler behandelt und ignoriert, was Sie möglicherweise als benutzerdefiniertes Fehler-Tag oder durch ErrorHandler oder Ihren eigenen Fehlerhandler festlegen möchten
Die beste Lösung ist meiner Meinung nach, einen Filter zu erstellen, der am Ende aller anderen Filter wirkt und die Ereignisse protokolliert, die bereits behandelt wurden. Das Elmah-Modul sollte sich um das Protokollieren der anderen Fehler kümmern, die von der Anwendung nicht behandelt werden. Dies ermöglicht es Ihnen auch, den Gesundheitsmonitor und alle anderen Module, die zu asp.net hinzugefügt werden können, zu verwenden, um Fehlerereignisse zu betrachten
Ich habe dies geschrieben, indem ich mir mit Reflektor den ErrorHandler innerhalb von elmah.mvc angesehen habe
public class ElmahMVCErrorFilter : IExceptionFilter
{
private static ErrorFilterConfiguration _config;
public void OnException(ExceptionContext context)
{
if (context.ExceptionHandled) //Die unbehandelten werden vom Elmah-Modul ausgewählt
{
var e = context.Exception;
var context2 = context.HttpContext.ApplicationInstance.Context;
//TODO: Fügen Sie zusätzliche Variablen zu context.HttpContext.Request.ServerVariables für behandelte und unbehandelte Ausnahmen hinzu
if ((context2 == null) || (!_RaiseErrorSignal(e, context2) && !_IsFiltered(e, context2)))
{
_LogException(e, context2);
}
}
}
private static bool _IsFiltered(System.Exception e, System.Web.HttpContext context)
{
if (_config == null)
{
_config = (context.GetSection("elmah/errorFilter") as ErrorFilterConfiguration) ?? new ErrorFilterConfiguration();
}
var context2 = new ErrorFilterModule.AssertionHelperContext((System.Exception)e, context);
return _config.Assertion.Test(context2);
}
private static void _LogException(System.Exception e, System.Web.HttpContext context)
{
ErrorLog.GetDefault((System.Web.HttpContext)context).Log(new Elmah.Error((System.Exception)e, (System.Web.HttpContext)context));
}
private static bool _RaiseErrorSignal(System.Exception e, System.Web.HttpContext context)
{
var signal = ErrorSignal.FromContext((System.Web.HttpContext)context);
if (signal == null)
{
return false;
}
signal.Raise((System.Exception)e, (System.Web.HttpContext)context);
return true;
}
}
Jetzt möchten Sie in Ihrer Filterkonfiguration etwas wie folgt tun:
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
//Diese Filter sollten am Ende des Pipelines stehen, fügen Sie alle Fehlerbehandler davor hinzu
filters.Add(new ElmahMVCErrorFilter());
}
Beachten Sie, dass ich dort einen Kommentar hinterlassen habe, um die Leute daran zu erinnern, dass, wenn sie einen globalen Filter hinzufügen möchten, der tatsächlich die Ausnahme behandelt, dieser VOR diesem letzten Filter stehen sollte, sonst geraten Sie in den Fall, dass die unbehandelte Ausnahme vom ElmahMVCErrorFilter ignoriert wird, da sie nicht behandelt wurde und vom Modul protokolliert werden sollte, aber dann markiert der nächste Filter die Ausnahme als behandelt und das Modul ignoriert sie, was dazu führt, dass die Ausnahme nie in Elmah landet.
Stellen Sie nun sicher, dass die App-Einstellungen für elmah in Ihrer Web.config so aussehen:
Der wichtige hier ist "elmah.mvc.disableHandleErrorFilter", wenn dies falsch ist, wird der Handler innerhalb von Elmah.Mvc verwendet, der tatsächlich die Ausnahme behandelt, indem er den Standard HandleErrorHandler verwendet, der Ihre customError-Einstellungen ignoriert
Diese Konfiguration ermöglicht es Ihnen, Ihre eigenen ErrorHandler-Tags in Klassen und Ansichten festzulegen, während Sie diese Fehler durch den ElmahMVCErrorFilter protokollieren, eine customError-Konfiguration über das Elmah-Modul zu Ihrer Web.config hinzufügen, sogar Ihre eigenen Fehlerhandler schreiben. Das einzige, was Sie tun müssen, ist daran zu denken, keine Filter hinzuzufügen, die tatsächlich den Fehler behandeln, bevor der von uns geschriebene Elmah-Filter hinzugefügt wird. Und ich habe vergessen zu erwähnen: Keine Duplikate in Elmah.
12 Stimmen
Wow, ich hoffe, Jeff oder Jared würden diese Frage beantworten. Sie verwenden ELMAH für Stackoverflow ;)
11 Stimmen
Hmm, komisch - wir verwenden nicht das HandleErrorAttribute - Elmah ist in unserem -Abschnitt der web.config eingerichtet. Gibt es Vorteile bei der Verwendung des HandleErrorAttribute?
1 Stimmen
Nun ja, ich glaube, dass du diese nervige Querystring-Abfrage nicht in der URL erhältst, und wenn ein Fehler auftritt, wird die URL nicht auf die im benutzerdefinierten Fehler im Web.config angegebene umgeleitet... für mich ist es einfach sauberer
0 Stimmen
@dswatik Ja, ich denke, eine Fehleransicht, die auf der aktuellen URL erscheint, anstatt einer umgeleiteten, wäre vielleicht sauberer - wir werden es überprüfen!
0 Stimmen
@Jarrod Vielen Dank, das wäre sehr geschätzt :)
9 Stimmen
@Jarrod - Es wäre schön zu sehen, was an deinem ELMAH-Fork "benutzerdefiniert" ist.
3 Stimmen
@dswatik Sie können Weiterleitungen auch verhindern, indem Sie redirectMode in der web.config auf ResponseRewrite einstellen. Siehe blog.turlov.com/2009/01/…
6 Stimmen
Ich bin immer wieder auf Web-Dokumentationen und Beiträge gestoßen, die das [HandleError]-Attribut und Elmah erwähnen, aber ich konnte das Verhalten, das dies löst (z.B. Elmah protokolliert den "behandelten" Fehler nicht), nicht beobachten, als ich den Dummy-Fall eingerichtet habe. Dies liegt daran, dass ab Elmah.MVC 2.0.x dieses benutzerdefinierte HandleErrorAttribute nicht mehr erforderlich ist; es ist im NuGet-Paket enthalten.
0 Stimmen
Protokoll schreiben in Mvc unter Verwendung von HandleErrorInfo