ABP FRAMEWORK 简单邮件发送
2023-11-15

官方文档: https://docs.abp.io/zh-Hans/abp/latest/Emailing
1、项目使用abp cli 初始化 abp new Email.Console -t console
2、安装 abp add-package Volo.Abp.Emailing 或者 nuget直接搜索 Volo.Abp.Emailing
3、继承自AbpModule的类头上添加 typeof(AbpEmailingModule)

using System.Threading.Tasks;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Emailing;

namespace MyProject
{
    public class MyService : ITransientDependency
    {
        private readonly IEmailSender _emailSender;

        public MyService(IEmailSender emailSender)
        {
            _emailSender = emailSender;
        }

        public async Task DoItAsync()
        {
            await _emailSender.SendAsync(
                "target@domain.com",     // target email address
                "Email subject",         // subject
                "This is email body..."  // email body
            );
        }
    }
}

4、appsettings.json添加,此处信息从邮箱提供商处得来,我使用的QQ邮箱 文档地址:https://service.mail.qq.com/cgi-bin/help?subtype=1&&id=28&&no=331

"Settings": {
  "Abp.Mailing.Smtp.Host": "127.0.0.1",
  "Abp.Mailing.Smtp.Port": "25",
  "Abp.Mailing.Smtp.UserName": "",
  "Abp.Mailing.Smtp.Password": "",
  "Abp.Mailing.Smtp.Domain": "",
  "Abp.Mailing.Smtp.EnableSsl": "false",
  "Abp.Mailing.Smtp.UseDefaultCredentials": "true",
  "Abp.Mailing.DefaultFromAddress": "noreply@abp.io",
  "Abp.Mailing.DefaultFromDisplayName": "ABP application"
}

以上就基础就全部配置完成了,但是我遇到一个问题,发送时抛出异常 提示password没有值,其他属性都能获取到值,就是password获取不到值,很纳闷为什么,搜索引擎一下,原来是password需要加密,使用密文,官方说明如下

加密 SMTP 密码

Abp.Mailing.Smtp.Password 必须是一个加密值。如果你使用 ISettingManager 设置密码,你不必担心。它在内部加密 set 上的值并在 get 上解密。

如果使用 appsettings.json 存储密码,则应手动注入 ISettingEncryptionService 并使用其 Encrypt 方法获取加密值。这可以通过在你的应用程序中创建一个简单的代码来完成。然后你可以删除代码。更好的是,你可以在应用程序中创建一个 UI 来配置电子邮件设置。在这种情况下,你可以直接使用 ISettingManager 而不用担心加密。

那么这个时候有两种解决办法

1、使用密文 参考:https://hnbc.info/index.php/archives/33/#comment-22

如何进行加密呢?我们可自己下一段端代码,对密码进行加密,调试方式获取加密字符串后,再把这段代码删除即可。
代码如下_settingDefinitionManager和_settingEncryptionService注入即可,用完再删除就行。

private readonly ISettingEncryptionService _settingEncryptionService;
private readonly ISettingDefinitionManager _settingDefinitionManager;
public TestAppService(
    ISettingEncryptionService settingEncryptionService,
    ISettingDefinitionManager settingDefinitionManager)
{

    _settingEncryptionService = settingEncryptionService;
    _settingDefinitionManager = settingDefinitionManager;
}

public async Task EncryptPwd()
{

    var setting = _settingDefinitionManager.Get(EmailSettingNames.Smtp.Password);
    var psd = _settingEncryptionService.Encrypt(setting,"密码");
}

2、使用明文

如果一定要使用明文的话。可以新建一个类继承 SettingDefinitionProvider 然后配置

    public override void Define(ISettingDefinitionContext context)
    {
        context.Add(
            new SettingDefinition("Abp.Mailing.Smtp.Password", isEncrypted: false)
        );
        // or 两种写法皆可
        // var smtpPassword = context.GetOrNull("Abp.Mailing.Smtp.Password");
        // if (smtpPassword != null)
        // {
        //     smtpPassword.IsEncrypted = false;
        // }
    }

都可以达到目的,不过还是使用加密的比较稳妥啦。