如何将SQL ELMAH_Error.ErrorID附加到ELMAH错误电子邮件主题?

时间:2011-12-22 02:59:19

标签: c# asp.net event-handling httpmodule elmah

我正在使用ELMAH将错误记录到SQL数据库并发送电子邮件。我想将ELMAH_Error.ErrorId附加到ELMAH电子邮件的主题。

我将ElmahLog_Logged事件中的ErrorId ELMAH保存到会话变量中,正如我在this question中发现的那样。 Atif Aziz自己就this blog post评论了以下有关此事的信息:

  

如果在邮寄过程中确实想要记录错误,那么就可以了   必须在ErrorLogModule.Logged事件中获取它。这可能是   例如,将记录的错误的Id推送到邮件中。   要做到这一点,你要将Id从Logged事件中删除到   HttpContext并稍后在Mailing事件中使用它。为了这个工作,   这些模块将被注册为Mailing事件   在Logged事件之后发生。

我认为,因为httpModules首先添加了ErrorLog而第二个是ErrorMail,所以这将实现在Logged事件之后注册Mailing事件。我想这是在谈论事件的顺序,而不是模块应用的顺序。

如何注册HttpModules的事件顺序?

我试过下面的代码无济于事。下面的代码阻止电子邮件发送,但错误仍记录到SQL表中。

Web.Config中:

<system.web>
    <httpModules>
        <add name="ErrorLog" type="Elmah.ErrorLogModule, Elmah" />
        <add name="ErrorMail" type="Elmah.ErrorMailModule, Elmah" />
        <add name="ErrorFilter" type="Elmah.ErrorFilterModule, Elmah" />
    </httpModules>
    <httpHandlers>
        <add verb="POST,GET,HEAD" path="elmah.axd" type="Elmah.ErrorLogPageFactory, Elmah" />
    </httpHandlers>
</system.web>

......和......

<system.webServer>
    <validation validateIntegratedModeConfiguration="false" />
    <modules>
        <add name="ErrorLog" type="Elmah.ErrorLogModule, Elmah" preCondition="managedHandler" />
        <add name="ErrorMail" type="Elmah.ErrorMailModule, Elmah" preCondition="managedHandler" />
        <add name="ErrorFilter" type="Elmah.ErrorFilterModule, Elmah" preCondition="managedHandler" />
    </modules>
    <handlers>
        <add name="Elmah" path="elmah.axd" verb="POST,GET,HEAD" type="Elmah.ErrorLogPageFactory, Elmah" preCondition="integratedMode" />
    </handlers>
</system.webServer>

当然,并且已正确配置(我通过NuGet安装)。

的Global.asax.cs:

protected void ErrorLog_Logged(object sender, ErrorLoggedEventArgs args)
{
    Session["ElmahId"] = args.Entry.Id;
}

protected void ErrorMail_Mailing(object sender, ErrorMailEventArgs e)
{
    var elmahErrorId = Session["ElmahId"].ToString();
    e.Mail.Subject = String.Format("{0}, see ELMAH_Error.ErrorID = {1}", e.Mail.Subject, elmahErrorId);            
}

如果我将global.asax.cs中的ErrorMail_Mailing事件代码更改为以下代码,我会收到带有ErrorMail_Mailing事件代码中指定主题的电子邮件。我甚至试图将Session.SessionID放在主题中并且杀死了电子邮件功能。 这让我认为ErrorMail_Mailing事件没有Session访问权限。这是正确的吗?

protected void ErrorMail_Mailing(object sender, ErrorMailEventArgs e)
{
    e.Mail.Subject = "I changed the subject in global.asax";
}

1 个答案:

答案 0 :(得分:5)

答案非常简单。 ErrorMailEventsArgs.Error对象包含异常时的会话信息。 ErrorMail_Mailing甚至无法访问会话上下文。因此,解决方案就像从ErrorMailEventArgs中提取变量一样简单。

protected void ErrorMail_Mailing(object sender, ErrorMailEventArgs e)
{
    var elmahErrorId = e.Error.SessionVariables["ElmahId"].ToString();
    if (!string.IsNullOrEmpty(elmahErrorId))
        e.Mail.Subject = String.Format("{0}, see ELMAH_Error.ErrorID = {1}", e.Mail.Subject, elmahErrorId);
}

此外,只需将ElmahId置于Session中的ErrorLog_Logged事件中,如果您的ErrorMail处理程序在ErrorLog之后注册(通过首先在web.config中添加ErrorLog完成),该会话变量将在Session Variables部分中标准ELMAH错误电子邮件。

protected void ErrorLog_Logged(object sender, ErrorLoggedEventArgs args)
{
    Session["ElmahId"] = args.Entry.Id;
}

更新: Atif Aziz提出Errors.SessionVariables不在原始ELMAH源中,而是在补丁中。这是我的packages.config:

<packages>
    <package id="elmah.corelibrary" version="1.2" />
    <package id="elmah" version="1.2.0.1" />
    <package id="elmah.sqlserver" version="1.2" />
</packages>