注释 Debug 空实现#
在 DomainModule
中,默认添加了邮件发送空实现,我本地需要测试,我就把它注释掉了,当然这完全看自己的需求:
//#if DEBUG
// context.Services.Replace(ServiceDescriptor.Singleton<IEmailSender, NullEmailSender>());
//#endif
集成 MailKit#
使用 MailKit
的原因是,在 ABP 源码 Volo.Abp.Emailing.Smtp.SmtpEmailSender
中的建议:
Logger.LogWarning("We don't recommend that you use the SmtpClient class for new development because SmtpClient doesn't support many modern protocols. " +
"Use MailKit(https://docs.abp.io/en/abp/latest/MailKit) or other libraries instead." +
"For more information, see https://github.com/dotnet/platform-compat/blob/master/docs/DE0005.md");
首先查看 MailKit Integration 文档,在 Domain
层安装 Volo.Abp.MailKit
。
安装时需要注意,由于 Volo.Abp.MailKit
依赖 Volo.Abp.Emailing
包,Domain
层又默认安装了
Volo.Abp.Emailing
,在安装 Volo.Abp.MailKit
时会安装最新的版本,可能会导致 Volo.Abp.Emailing
包降级,所以,这两个包的版本号最好一致:
修改默认配置#
需要注意的是,确保为邮箱账号开启了 SMTP 服务。
使用默认的管理员账号 postmaster
登录邮箱,打开 账号列表,确保发件邮箱账号配置如下:
然后再使用 发件邮箱登录,再打开 账号安全,划到最下面,找到 "三方客户端登录安全管理",开启 "三方客户端安全密码",并点击 “生成新密码”,后续代码中会用到。
在 Domain
项目的 Settings/?SettingDefinitionProvider
中添加以下代码:
public class ?SettingDefinitionProvider : SettingDefinitionProvider
{
public override void Define(ISettingDefinitionContext context)
{
//Define your own settings here. Example:
//context.Add(new SettingDefinition(?Settings.MySetting1));
// context.Add will override value of key: https://github.com/abpframework/abp/blob/f47e9252a3d57c12c2ac06e1f09034acd70582e0/framework/src/Volo.Abp.Settings/Volo/Abp/Settings/SettingDefinitionContext.cs#L25
// note: 添加或修改 settings 后,重启 Web 项目即可生效
context.Add(
// Email settings: https://docs.abp.io/en/abp/latest/Emailing#email-settings
// 默认配置参考:Volo.Abp.Emailing.EmailSettingProvider
// 页面上 "发送测试邮件" 按钮点击后,会显示一个弹出层再次确认收发信息,收件人默认是 CurrentUser.Email
new SettingDefinition(
EmailSettingNames.Smtp.Host,
"smtp.qiye.aliyun.com",
L("DisplayName:Abp.Mailing.Smtp.Host"),
L("Description:Abp.Mailing.Smtp.Host")),
// ABP 默认就是 25 端口
//new SettingDefinition(EmailSettingNames.Smtp.Port,
// "25",
// L("DisplayName:Abp.Mailing.Smtp.Port"),
// L("Description:Abp.Mailing.Smtp.Port")),
// 需要注意的是,阿里云企业邮箱 postmaster 账号默认无法登录,因为没有开启 SMTP 服务,需要在 http://mail.yourdomain.com/admin/#/account-email 页面找到该账号,进入详情,
// 必须使用其他账号,通过下面的链接找到 "三方客户端登录安全管理",开启 "三方客户端安全密码",并生成新密码应用到下面的 Password
// 三方客户端登录安全管理:http://mail.secondstrust.com/alimail/entries/v5.1/setting/account-security
new SettingDefinition(
EmailSettingNames.Smtp.UserName,
defaultValue: "这里填写发件人邮箱,比如 x@q.com",
displayName: L("DisplayName:Abp.Mailing.Smtp.UserName"),
description: L("Description:Abp.Mailing.Smtp.UserName")),
new SettingDefinition(
EmailSettingNames.Smtp.Password,
defaultValue: "这里填写生成的三方客户端密码",
displayName: L("DisplayName:Abp.Mailing.Smtp.Password"),
description: L("Description:Abp.Mailing.Smtp.Password"),
// 如果要设置为 isEncrypted:true, 表示存储的 defaultValue 是已经自己手动加密后的字符串,在使用时会自动使用 IStringEncryptionService.Decrypt 解密
isEncrypted: false),
new SettingDefinition(
EmailSettingNames.Smtp.Domain,
defaultValue: "这里填写邮箱域名,比如 q.com",
displayName: L("DisplayName:Abp.Mailing.Smtp.Domain"),
description: L("Description:Abp.Mailing.Smtp.Domain")),
// 如果为 true,则使用默认凭据,而不是上面提供的用户名和密码 (“true” 或 “false”.默认值:“true”)。
new SettingDefinition(
EmailSettingNames.Smtp.UseDefaultCredentials,
"false",
L("DisplayName:Abp.Mailing.Smtp.UseDefaultCredentials"),
L("Description:Abp.Mailing.Smtp.UseDefaultCredentials")),
// 不要启用 SSL,否则会报错
//new SettingDefinition(
// EmailSettingNames.Smtp.EnableSsl,
// "true",
// L("DisplayName:Abp.Mailing.Smtp.EnableSsl"),
// L("Description:Abp.Mailing.Smtp.EnableSsl")),
new SettingDefinition(
EmailSettingNames.DefaultFromAddress,
"这里填写发件人邮箱,比如 x@q.com",
L("DisplayName:Abp.Mailing.DefaultFromAddress"),
L("Description:Abp.Mailing.DefaultFromAddress")),
new SettingDefinition(EmailSettingNames.DefaultFromDisplayName,
"发件人邮箱显示名称,比如 x",
L("DisplayName:Abp.Mailing.DefaultFromDisplayName"),
L("Description:Abp.Mailing.DefaultFromDisplayName"))
);
}
private static LocalizableString L(string name)
{
return LocalizableString.Create<IdentityResource>(name);
}
注意:如果程序部署在阿里云服务器上,可能会无法访问 25
端口,需要修改为:
// ABP 默认就是 25 端口,启用 SSL 后端口改为 465
new SettingDefinition(EmailSettingNames.Smtp.Port,
"465", //"25",
L("DisplayName:Abp.Mailing.Smtp.Port"),
L("Description:Abp.Mailing.Smtp.Port")),
// 阿里云服务器:由于国际与国内均对垃圾邮件进行严格管控,我国《互联网信息服务管理办法》、《中国互联网协会反垃圾邮件规范》均对垃圾邮件进行说明与管理规范。
// 为了共同维护良好的网络环境,阿里云新购服务器不再提供25端口邮件服务,建议您尝试使用465加密端口发送邮件,或与邮件发信提供商咨询是否还有其他smtp发信端口,给您带来的不便深表歉意,
new SettingDefinition(
EmailSettingNames.Smtp.EnableSsl,
"true",
L("DisplayName:Abp.Mailing.Smtp.EnableSsl"),
L("Description:Abp.Mailing.Smtp.EnableSsl")),
原因是:
测试#
启动 Web
项目,使用管理员账号登录,然后打开下面的页面,点击 "发送测试邮件" 按钮,点了之后会显示一个弹出层确认收发信息,点发送,就可以发出去了。
如果不放心,可以使用发件账号登录 阿里云企业邮箱,然后在发件箱里面查看。
被退信#
有些时候,虽然邮件发成功了 (代码不会报错),但收件人可能收不到,因为被阿里云官退信了: