Jetzt gibt es ein ELMAH.MVC-Paket in NuGet, das eine verbesserte Lösung von Atif enthält und auch einen Controller, der die elmah-Schnittstelle innerhalb der MVC-Routing (keine Notwendigkeit mehr, diese axd zu verwenden) behandelt.
Das Problem bei dieser Lösung (und bei allen anderen hier) ist, dass die elmah-Fehlerbehandlung auf die eine oder andere Weise tatsächlich den Fehler behandelt und dabei ignoriert, was Sie möglicherweise als benutzerdefiniertes customError-Tag oder durch ErrorHandler oder Ihren eigenen Fehlerbehandler festlegen möchten.
Die beste Lösung meiner Meinung nach besteht darin, einen Filter zu erstellen, der am Ende aller anderen Filter agiert und die bisher behandelten Ereignisse protokolliert. Das elmah-Modul sollte sich um die Protokollierung der anderen Fehler kümmern, die von der Anwendung nicht behandelt werden. Dadurch können Sie auch den Health Monitor und alle anderen Module verwenden, die in asp.net hinzugefügt werden können, um Fehlerereignisse zu betrachten
Das habe ich geschrieben, als ich mit Reflektor auf den ErrorHandler innerhalb von elmah.mvc geschaut habe
public class ElmahMVCErrorFilter : IExceptionFilter
{
private static ErrorFilterConfiguration _config;
public void OnException(ExceptionContext context)
{
if (context.ExceptionHandled) //Die nicht behandelten werden vom elmah-Modul aufgegriffen
{
var e = context.Exception;
var context2 = context.HttpContext.ApplicationInstance.Context;
//TODO: Zusätzliche Variablen zu context.HttpContext.Request.ServerVariables für behandelte und nicht behandelte Ausnahmen hinzufügen
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 Ähnliches tun:
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
//Diese Filter sollten am Ende der Pipeline stehen, fügen Sie alle Fehlerbehandler vorher 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 platziert werden sollte, da Sie sonst in den Fall geraten, dass die unbehandelte Ausnahme vom ElmahMVCErrorFilter ignoriert wird, weil 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 ankommt.
Vergewissern Sie sich nun, dass die appsettings für elmah in Ihrem Web.config so ähnlich wie folgt aussehen:
Der wichtige hier ist "elmah.mvc.disableHandleErrorFilter", wenn dies falsch ist, wird der Handler innerhalb elmah.mvc verwendet, der tatsächlich die Ausnahme behandelt, indem der Standard-HandleErrorHandler verwendet wird, der Ihre benutzerdefinierten Error-Einstellungen ignoriert
Mit dieser Konfiguration können Sie Ihre eigenen ErrorHandler-Tags in Klassen und Ansichten festlegen, während Sie diese Fehler durch den ElmahMVCErrorFilter protokollieren, eine benutzerdefinierte Error-Konfiguration in Ihrer Web.config durch das elmah-Modul hinzufügen, sogar Ihre eigenen Error-Handler schreiben. Das Einzige, was Sie tun müssen, ist daran zu denken, keine Filter hinzuzufügen, die den Fehler tatsächlich vor dem von uns geschriebenen elmah-Filter behandeln. 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, seltsam - wir verwenden den HandleErrorAttribute nicht - Elmah ist in unserem -Bereich von web.config eingerichtet. Gibt es Vorteile bei der Verwendung des HandleErrorAttribute?
1 Stimmen
Nun ja, ich glaube, du bekommst diese lästige Abfragezeichenfolge nicht in der URL, und wenn ein Fehler auftritt, wird die URL nicht auf die im benutzerdefinierten Fehler im web.config angegebene umgeleitet... für mich einfach sauberer
0 Stimmen
@dswatik Ja, ich denke, dass eine Fehleransicht, die auf der aktuellen URL erscheint, anstatt einer umgeleiteten, möglicherweise sauberer ist - wir werden es überprüfen!
0 Stimmen
@Jarrod Danke, das wäre geschätzt :)
9 Stimmen
@Jarrod - Es wäre schön zu sehen, was an Ihrer ELMAH-Gabel "benutzerdefiniert" ist.
3 Stimmen
@dswatik Sie können auch Weiterleitungen verhindern, indem Sie redirectMode in web.config auf ResponseRewrite setzen. Siehe blog.turlov.com/2009/01/…
6 Stimmen
Ich stieß immer wieder auf Web-Dokumentationen und Beiträge, die von dem [HandleError]-Attribut und Elmah sprachen, aber ich sah nicht das Verhalten, das dadurch gelöst wird (z.B. Elmah loggt den "handled" Fehler nicht), als ich den Dummy-Fall einrichtete. 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 mit HandleErrorInfo