问题
I am using Elmah and Elmah.mvc packages in a asp.net, mvc4 web app. I have a specific controller action where I want to handle HttpAntiForgeryExceptions
in a specific manner. I have created a custom HandleErrorAttribute that inherits from HandleErrorAttribute
and implements IExceptionFilter
.
Under the specific circumstances I want to handle, I set the ExceptionContext.ExceptionHandled
to true. The behaviour that the user sees is correct and the error is handled as I want it to be. However, it also logs an error to Elmah, which I don't want it to do, as I would like to keep the Elmah log for true errors.
The controller annotation looks like:
[ValidateAntiForgeryToken]
[CustomHandleAntiforgeryError]
public ActionResult ControllerMethod(Model model)
{
...
}
The CustomHandleAntiforgeryError looks like:
public class CustomHandleAntiforgeryErrorAttribute:
HandleErrorAttribute, IExceptionFilter
{
public override void OnException(ExceptionContext filterContext)
{
if (circumstancesAreOk)
{
filterContext.ExceptionHandled = true;
return;
}
}
}
Is there anything else I need to do to prevent this error being logged with Elmah?
--- EDIT ---
Looking at the Elmah.MVC source the HandleErrorAttribute logs both handled and unhandled errors
public override void OnException(ExceptionContext context)
{
base.OnException(context);
if (!context.ExceptionHandled) // if unhandled, will be logged anyhow
return;
var e = context.Exception;
var httpContext = context.HttpContext.ApplicationInstance.Context;
if (httpContext != null &&
(RaiseErrorSignal(e, httpContext) // prefer signaling, if possible
|| IsFiltered(e, httpContext))) // filtered?
return;
LogException(e, httpContext);
}
I would like a way within my custom attribute to signal to Elmah not to log this error and would appreciate any ideas.
回答1:
See ErrorFiltering from Elmah's documentation. Here's the introduction:
When an unhandled exception is reported to ELMAH by ASP.NET, an application can decide whether to dismiss the exception or not. There are two ways for an application to do this, either programmatically or declaratively via the configuration file. The simpler of the two is programmatically because you do not need to learn anything new except write an event handler in your favorite language. The downside of the programmatic approach is that you need to write code and modify your web application (requiring possibly a static re-compile). With the configuration-based approach, you can simply apply filtering of exceptions to a running application.
回答2:
What I did to solve this I think is ugly, but worked for the weird error filter corner case that I was experiencing. I added a custom HandleErrorAttribute, copied from the Elmah HandleErrorAttribute and included a null check in the OnException method.
public override void OnException(ExceptionContext context)
{
base.OnException(context);
if (!context.ExceptionHandled) // if unhandled, will be logged anyhow
return;
string[] formKeys = context.HttpContext.Request.Form.AllKeys;
var e = context.Exception;
// linked to CustomErrorAttribute
if (e == null)
{
return;
}
bool test = HostingEnvironment.IsHosted;
var httpContext = context.HttpContext.ApplicationInstance.Context;
if (httpContext != null &&
(RaiseErrorSignal(e, httpContext) // prefer signaling, if possible
|| IsFiltered(e, httpContext))) // filtered?
return;
LogException(e, httpContext);
}
Then, in my error filter, which I did not want to trigger messaging to Elmah, as well as setting the ExceptionContext ExceptionHandled to true I set the Exception to null
public class MyCustomErrorFilter : IExceptionFilter
{
public void OnException(ExceptionContext filterContext)
{
if (blah, blah, blah, weird things but not something terrible)
{
filterContext.Exception = null;
filterContext.ExceptionHandled = true;
return;
}
}
}
If it was something more involved and a regular occurrence I would probably fork Elmah and look at creating a custom Elmah build as this feels a little bit hacky to rely on in multiple situations.
来源:https://stackoverflow.com/questions/20907398/how-to-prevent-elmah-logging-errors-handled-in-a-error-attribute