我使用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使用存储在应用程序设置中的凭据的最佳方式是什么?
我可以看到的选项:
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);
}
事件的链接,以自定义消息。答案 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)
}
}
}
所需要的只是将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部署后部署任务的一部分运行。