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

Jus*_*nP8 4 c# asp.net elmah event-handling httpmodule

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

我正在将ElmahLog_Logged事件中的ErrorId ELMAH保存到会话变量中,正如我在此问题中发现的那样.Atif Aziz自己在这篇博文中评论了以下关于此的信息:

如果在邮件发送期间确实想要在记录的错误处获得破解,则必须在ErrorLogModule.Logged事件中将其拾取.这可能很方便,例如,将记录的错误的Id推送到邮件中.为此,您将Id从Logged事件中隐藏到HttpContext中,稍后在Mailing事件中使用它.为此,模块将被注册,以便在Logged事件之后发生Mailing事件.

我认为,因为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>
Run Code Online (Sandbox Code Playgroud)

......而且......

<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>
Run Code Online (Sandbox Code Playgroud)

当然,并且配置正确(我通过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);            
}
Run Code Online (Sandbox Code Playgroud)

如果我将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";
}
Run Code Online (Sandbox Code Playgroud)

Jus*_*nP8 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);
}
Run Code Online (Sandbox Code Playgroud)

此外,只需将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;
}
Run Code Online (Sandbox Code Playgroud)

更新: 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>
Run Code Online (Sandbox Code Playgroud)