In NuGet gibt es jetzt ein ELMAH.MVC-Paket, das eine verbesserte Lösung von Atif sowie einen Controller enthält, der die elmah-Schnittstelle innerhalb des MVC-Routings verwaltet (diese Axd muss nicht mehr verwendet werden).
Das Problem mit dieser Lösung (und mit allen hier) ) ist, dass der elmah-Fehlerbehandler den Fehler auf die eine oder andere Weise tatsächlich behandelt und ignoriert, was Sie möglicherweise als customError-Tag oder über ErrorHandler oder Ihren eigenen Fehlerbehandler einrichten möchten
Die beste Lösung ist meiner Meinung nach, einen Filter zu erstellen, der am Ende aller anderen Filter wirkt und die bereits behandelten Ereignisse protokolliert. Das elmah-Modul sollte sich darum kümmern, die anderen Fehler zu protokollieren, die von der Anwendung nicht behandelt werden. Auf diese Weise können Sie auch den Integritätsmonitor und alle anderen Module verwenden, die asp.net hinzugefügt werden können, um Fehlerereignisse anzuzeigen
Ich habe diesen Blick mit Reflektor auf den ErrorHandler in elmah.mvc geschrieben
public class ElmahMVCErrorFilter : IExceptionFilter
{
private static ErrorFilterConfiguration _config;
public void OnException(ExceptionContext context)
{
if (context.ExceptionHandled) //The unhandled ones will be picked by the elmah module
{
var e = context.Exception;
var context2 = context.HttpContext.ApplicationInstance.Context;
//TODO: Add additional variables to context.HttpContext.Request.ServerVariables for both handled and unhandled exceptions
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;
}
}
In Ihrer Filterkonfiguration möchten Sie nun Folgendes tun:
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
//These filters should go at the end of the pipeline, add all error handlers before
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 die Ausnahme tatsächlich behandelt, dieser VOR diesem letzten Filter angezeigt wird. Andernfalls tritt der Fall auf, in dem die nicht behandelte Ausnahme vom ElmahMVCErrorFilter ignoriert wird, weil Es wurde nicht behandelt und sollte vom Elmah-Modul protokolliert werden. Der nächste Filter markiert die Ausnahme jedoch als behandelt und das Modul ignoriert sie. Dies führt dazu, dass die Ausnahme niemals zu elmah wird.
Stellen Sie nun sicher, dass die Apps für elmah in Ihrer Webkonfiguration ungefähr so aussehen:
<add key="elmah.mvc.disableHandler" value="false" /> <!-- This handles elmah controller pages, if disabled elmah pages will not work -->
<add key="elmah.mvc.disableHandleErrorFilter" value="true" /> <!-- This uses the default filter for elmah, set to disabled to use our own -->
<add key="elmah.mvc.requiresAuthentication" value="false" /> <!-- Manages authentication for elmah pages -->
<add key="elmah.mvc.allowedRoles" value="*" /> <!-- Manages authentication for elmah pages -->
<add key="elmah.mvc.route" value="errortracking" /> <!-- Base route for elmah pages -->
Das wichtigste hier ist "elmah.mvc.disableHandleErrorFilter". Wenn dies falsch ist, wird der Handler in elmah.mvc verwendet, der die Ausnahme tatsächlich behandelt, indem der Standard-HandleErrorHandler verwendet wird, der Ihre customError-Einstellungen ignoriert
Mit diesem Setup können Sie Ihre eigenen ErrorHandler-Tags in Klassen und Ansichten festlegen, während Sie diese Fehler weiterhin über den ElmahMVCErrorFilter protokollieren, Ihrer web.config über das elmah-Modul eine customError-Konfiguration hinzufügen und sogar Ihre eigenen Fehlerbehandler schreiben. Das einzige, was Sie tun müssen, ist daran zu denken, keine Filter hinzuzufügen, die den Fehler tatsächlich behandeln, bevor der von uns geschriebene elmah-Filter verwendet wird. Und ich habe vergessen zu erwähnen: keine Duplikate in Elma.