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("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 包降级,所以,这两个包的版本号最好一致:
image

修改默认配置#

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

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

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

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.secondstrust.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

Loading...
Ownership of this post data is guaranteed by blockchain and smart contracts to the creator alone.