ELMAH - 从Azure应用程序设置中获取SMTP凭据

时间:2016-09-08 15:46:24

标签: azure elmah

我使用ELMAH获取Azure Web App来记录未处理的异常。

当我第一次部署它时,web.config在其中定义了完整的SMTP设置,ELMAH通过电子邮件发送了例外:

$new_data = preg_replace("/$find_url\b/i", $replace, $data);

此后,用户名和密码已从web.config中删除,现在它们已存储为通过Azure门户配置的应用程序设置。

我发送的大多数电子邮件仍然可以正常工作,因为电子邮件代码可以访问这些应用程序设置并在实例化<system.net> <mailSettings> <smtp from="me@mydomain.com"> <network host="smtp.mailprovider.com" port="123" userName="myUserName" password="p@ssw0rd" /> </stmp> </mailSettings> </system.net> 时使用它们,例如:

SmtpClient

让ELMAH使用存储在应用程序设置中的凭据的最佳方式是什么?

我可以看到的选项:

  • 维基上有一个page,解释了如何使用ELMAH的ErrorTweetModule来处理带有任何URL错误详细信息的HTTP表单帖子。接收帖子的控制器然后可以使用存储的凭证通过电子邮件发送详细信息。
  • WebBase有一个指向article的链接,建议您可以直接向收件人的SMTP服务器发送电子邮件而无需身份验证,但是如果您设置了DomainKeys,这可能不起作用,我这样做。
  • answer指向article关于拦截var userName = WebConfigurationManager.AppSettings["smtp.userName"]; var password = WebConfigurationManager.AppSettings["smtp.password"]; var credentials = new NetworkCredential(userName, password); using (var smtpClient = new SmtpClient { Credentials = credentials }) { await smtpClient.SendMailAsync(mailMessage); } 事件的链接,以自定义消息。

2 个答案:

答案 0 :(得分:3)

我最终创建了一个自定义版本的Elmah ErrorMailModule,源自标准版本,但是基于Atif Aziz在a discussion Google群组上的一些建议而覆盖了SendMail方法

所需的唯一更改是创建新模块,并切换Web.Config以使用自定义模块而不是标准模块。

模块

using System;
using System.Net.Mail;

namespace Test
{
    public class ErrorMailModule : Elmah.ErrorMailModule
    {
        protected override void SendMail(MailMessage mail)
        {
            if (mail == null) throw new ArgumentNullException(nameof(mail));

            // do what you want with the mail
            // (in my case this fires up the email service, which 
            // gets the credentials from the Azure settings)
        }
    }
}

Web配置更改

所需要的只是将Elmah.ErrorLogModule, Elmah的两次出现更改为您自己的模块,在本例中为Test.ErrorMailModule

所以,而不是......

<system.web>
  <httpModules>
    <add name="ErrorMail" type="Elmah.ErrorMailModule, Elmah" />
  </httpModules>
</system.web>
<system.webServer>
  <modules>
    <add name="ErrorMail" type="Elmah.ErrorMailModule, Elmah" preCondition="managedHandler" />
  </modules>
</system.webServer>

......你现在应该有这个:

<system.web>
  <httpModules>
    <add name="ErrorMail" type="Test.ErrorMailModule" />
  </httpModules>
</system.web>
<system.webServer>
  <modules>
    <add name="ErrorMail" type="Test.ErrorMailModule" preCondition="managedHandler" />
  </modules>
</system.webServer>

您仍需要errorMail部分,因为Elmah仍负责创建电子邮件。我看起来像这样:

<elmah>
  <errorMail from="user@domain.com" to="user@domain.com" subject="Custom Email Module"/>
</elmah>

答案 1 :(得分:1)

创建HTTP请求可能有效,但如果其他一切都不起作用,这应该是解决方案IMO。拦截邮件事件不起作用,因为您无法使用该事件中的凭据访问SmtpClient。

我查看了从代码更新SMTP设置的不同方法。起初我虽然我可以获得对smtp部分的引用并更新属性,因为它们都有setter。但是代码在运行时抛出了一个配置异常。

根据我的发现,在smtp部分更新用户名和密码的唯一方法是阅读web.config,更新它并编写新版本。以下是编写web.config更新的示例:

var configuration = WebConfigurationManager.OpenWebConfiguration("~");
var section = configuration.GetSection("system.net/mailSettings/smtp") as SmtpSection;
section.Network.UserName = ConfigurationManager.AppSettings["myusername"];
section.Network.Password = ConfigurationManager.AppSettings["mypassword"];
configuration.Save();

代码实际上更新了web.config。代码可以在启动时运行,但这也会在本地修改您的web.config文件。另一种方法是将代码作为Azure部署后部署任务的一部分运行。