myesn

myEsn2E9

hi
github

ABP: 邮件发送集成 MailKit 并配置阿里云企业邮箱

注释 Debug 空实现#

DomainModule 中,默认添加了邮件发送空实现,我本地需要测试,我就把它注释掉了,当然这完全看自己的需求:

//#if DEBUG
//        context.Services.Replace(ServiceDescriptor.Singleton<IEmailSender, NullEmailSender>());
//#endif

集成 MailKit#

使用 MailKit 的原因是,在 ABP 源码 Volo.Abp.Emailing.Smtp.SmtpEmailSender中的建议

Logger.LogWarning("我们不建议您在新开发中使用 SmtpClient 类,因为 SmtpClient 不支持许多现代协议。 " +
                               "请使用 MailKit(https://docs.abp.io/en/abp/latest/MailKit) 或其他库。" +
                               "有关更多信息,请参见 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 包降级,所以,这两个包的版本号最好一致:
image

修改默认配置#

需要注意的是,确保为邮箱账号开启了 SMTP 服务。

使用默认的管理员账号 postmaster 登录邮箱,打开 账号列表,确保发件邮箱账号配置如下:
image

然后再使用 发件邮箱登录,再打开 账号安全,划到最下面,找到 "三方客户端登录安全管理",开启 "三方客户端安全密码",并点击 “生成新密码”,后续代码中会用到。

Domain 项目的 Settings/?SettingDefinitionProvider中添加以下代码:

public class ?SettingDefinitionProvider : SettingDefinitionProvider
{
    public override void Define(ISettingDefinitionContext context)
    {
        //在这里定义您自己的设置。例如:
        //context.Add(new SettingDefinition(?Settings.MySetting1));
        // context.Add 将覆盖键的值:https://github.com/abpframework/abp/blob/f47e9252a3d57c12c2ac06e1f09034acd70582e0/framework/src/Volo.Abp.Settings/Volo/Abp/Settings/SettingDefinitionContext.cs#L25

        // 注意:添加或修改设置后,重启 Web 项目即可生效

        context.Add(
            // 邮件设置: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")),    

原因是:
image

测试#

启动 Web 项目,使用管理员账号登录,然后打开下面的页面,点击 "发送测试邮件" 按钮,点了之后会显示一个弹出层确认收发信息,点发送,就可以发出去了。

image
image
image

如果不放心,可以使用发件账号登录 阿里云企业邮箱,然后在发件箱里面查看。

被退信#

有些时候,虽然邮件发成功了 (代码不会报错),但收件人可能收不到,因为被阿里云官退信了:
image

解决办法:https://help.aliyun.com/document_detail/36620.html

加载中...
此文章数据所有权由区块链加密技术和智能合约保障仅归创作者所有。