ELMAH - 从 Azure 应用程序设置中获取 SMTP 凭据
ELMAH - Get SMTP credentials from Azure Application Settings
我有一个 Azure Web 应用程序使用 ELMAH 来记录未处理的异常。
当我第一次部署它时,web.config 中定义了完整的 SMTP 设置,并且 ELMAH 电子邮件例外:
<system.net>
<mailSettings>
<smtp from="me@mydomain.com">
<network host="smtp.mailprovider.com"
port="123"
userName="myUserName"
password="p@ssw0rd" />
</stmp>
</mailSettings>
</system.net>
用户名和密码已从 web.config 中删除,它们现在存储为应用程序设置,通过 Azure 门户进行配置。
我发送的大部分电子邮件仍然有效,因为电子邮件代码可以访问这些应用程序设置并在实例化 SmtpClient
时使用它们,例如:
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);
}
让 ELMAH 使用存储在应用程序设置中的凭据的最佳方法是什么?
我能看到的选项:
创建 HTTP 请求可能有效,但如果 IMO 其他所有方法均无效,那应该是解决方案。拦截 Mailing 事件不起作用,因为您无权使用该事件中的凭据访问 SmtpClient。
我研究了从代码更新 SMTP 设置的不同方法。起初我认为我可以只获取对 smtp 部分的引用并更新属性,因为它们都有 setter。但是代码在 运行time.
时抛出配置异常
据我所知,在 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 文件。另一种方法是 运行 将代码作为 post Azure 部署任务的一部分。
我最终创建了 Elmah 的自定义版本 ErrorMailModule
,它源自标准版本,但基于 a discussion 中 Atif Aziz 的一些建议覆盖了 SendMail
方法Google 个群组。
唯一需要的更改是创建新模块,并将 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>
我有一个 Azure Web 应用程序使用 ELMAH 来记录未处理的异常。
当我第一次部署它时,web.config 中定义了完整的 SMTP 设置,并且 ELMAH 电子邮件例外:
<system.net>
<mailSettings>
<smtp from="me@mydomain.com">
<network host="smtp.mailprovider.com"
port="123"
userName="myUserName"
password="p@ssw0rd" />
</stmp>
</mailSettings>
</system.net>
用户名和密码已从 web.config 中删除,它们现在存储为应用程序设置,通过 Azure 门户进行配置。
我发送的大部分电子邮件仍然有效,因为电子邮件代码可以访问这些应用程序设置并在实例化 SmtpClient
时使用它们,例如:
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);
}
让 ELMAH 使用存储在应用程序设置中的凭据的最佳方法是什么?
我能看到的选项:
创建 HTTP 请求可能有效,但如果 IMO 其他所有方法均无效,那应该是解决方案。拦截 Mailing 事件不起作用,因为您无权使用该事件中的凭据访问 SmtpClient。
我研究了从代码更新 SMTP 设置的不同方法。起初我认为我可以只获取对 smtp 部分的引用并更新属性,因为它们都有 setter。但是代码在 运行time.
时抛出配置异常据我所知,在 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 文件。另一种方法是 运行 将代码作为 post Azure 部署任务的一部分。
我最终创建了 Elmah 的自定义版本 ErrorMailModule
,它源自标准版本,但基于 a discussion 中 Atif Aziz 的一些建议覆盖了 SendMail
方法Google 个群组。
唯一需要的更改是创建新模块,并将 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>