Elmah 过滤主要作用于异常类型。程序化过滤允许我检查添加到异常中的信息,但我还没有遇到具有ElmahFilteringData 属性的异常类型,而且我不想“侵入”我想要记录的异常。以下是我仅针对某些异常信号发送电子邮件通知的方法:
首先我有一个特殊的包装异常,纯粹是为了告诉 Elmah 不要为这种类型的异常发送电子邮件通知:
public class ElmahEMailBlockWrapperException: Exception
{
public const string Explanation = "This is a wrapper exception that will be blocked by Elmah email filtering. The real exception is the InnerException";
public ElmahEMailBlockWrapperException(Exception wrappedException):base(Explanation, wrappedException) {}
}
然后,当我提出异常时,我通常只希望记录而不是通过电子邮件发送,但有时可能会通过电子邮件发送,我在异常记录服务中使用此代码:
public void LogException(Exception exception, bool includeEmail)
{
if (includeEmail)
{
ErrorSignal.FromContext(HttpContext.Current).Raise(exception);
}
else
{
// Wrap the input exception in a special exception type that the Elmah email filter can block.
var wrappedException = new ElmahEMailBlockWrapperException(exception);
ErrorSignal.FromContext(HttpContext.Current).Raise(wrappedException);
}
}
现在,在 Global.asax 中的 Elmah 过滤器事件中,我打开异常以记录它,如果它被包装,则从电子邮件通知管道中将其关闭:
public void ErrorLog_Filtering(object sender, ExceptionFilterEventArgs e)
{
// If the exception was wrapped in a ElmahEMailBlockWrapperException exception to be blocked by the ErrorMail filter, the InnerException
// of the the ElmahEMailBlockWrapperException is the real exception to be logged, so we extract it, log it, and dismiss the wrapper.
var ebw = e.Exception.GetBaseException() as ElmahEMailBlockWrapperException;
if (ebw != null)
{
ErrorLog.GetDefault(HttpContext.Current).Log(new Error(ebw.InnerException));
e.Dismiss();
}
}
public void ErrorMail_Filtering(object sender, ExceptionFilterEventArgs e)
{
// If the exception was wrapped, i.e. raised only to be logged by Elmah and not emailed, dismiss it.
if (e.Exception.GetBaseException() is ElmahEMailBlockWrapperException)
{
e.Dismiss();
}
}