Ora c'è un pacchetto ELMAH.MVC in NuGet che include una soluzione migliorata di Atif e anche un controller che gestisce l'interfaccia elmah all'interno del routing MVC (non è più necessario utilizzare quell'axd)
Il problema con quella soluzione (e con tutte quelle qui ) è che in un modo o nell'altro il gestore degli errori elmah sta effettivamente gestendo l'errore, ignorando ciò che potresti voler impostare come tag customError o tramite ErrorHandler o il tuo gestore degli errori
La migliore soluzione IMHO è creare un filtro che agirà alla fine di tutti gli altri filtri e registrare gli eventi che sono già stati gestiti. Il modulo elmah dovrebbe occuparsi della registrazione degli altri errori non gestiti dall'applicazione. Ciò consentirà inoltre di utilizzare il monitoraggio dello stato e tutti gli altri moduli che possono essere aggiunti ad asp.net per esaminare gli eventi di errore
Ho scritto questo osservando con il riflettore ErrorHandler all'interno di elmah.mvc
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;
}
}
Ora, nella configurazione del filtro, vuoi fare qualcosa del genere:
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());
}
Nota che ho lasciato un commento lì per ricordare alle persone che se vogliono aggiungere un filtro globale che gestirà effettivamente l'eccezione dovrebbe andare PRIMA di quest'ultimo filtro, altrimenti ti imbatterai nel caso in cui l'eccezione non gestita verrà ignorata da ElmahMVCErrorFilter perché non è stato gestito e dovrebbe essere registrato dal modulo Elmah, ma il filtro successivo contrassegna l'eccezione come gestita e il modulo la ignora, determinando che l'eccezione non la trasformi mai in elmah.
Ora, assicurati che le impostazioni delle app per elmah nel tuo webconfig siano simili a queste:
<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 -->
Quello importante qui è "elmah.mvc.disableHandleErrorFilter", se questo è falso userà il gestore all'interno di elmah.mvc che gestirà effettivamente l'eccezione usando il HandleErrorHandler predefinito che ignorerà le tue impostazioni customError
Questa configurazione ti consente di impostare i tuoi tag ErrorHandler in classi e viste, registrando comunque quegli errori attraverso ElmahMVCErrorFilter, aggiungendo una configurazione CustomError al tuo web.config attraverso il modulo elmah, persino scrivendo i tuoi Error Handlers. L'unica cosa che devi fare è ricordare di non aggiungere filtri che gestiranno effettivamente l'errore prima del filtro elmah che abbiamo scritto. E ho dimenticato di menzionare: nessun duplicato in elmah.