Abp vNext : 使用郵件

https://docs.abp.io/en/abp/latest/Emailing

使用郵件

第一步:在項目中已入如下包:

    <PackageReference Include="Volo.Abp.Emailing" Version="6.0.1" />
    <PackageReference Include="Volo.Abp.MailKit" Version="6.0.1" />

添加模塊依賴

namespace AbpManaul
{
    [DependsOn(
        ...
        typeof(AbpEmailingModule),
        typeof(AbpMailKitModule)
    )]
    public class AbpManualApplicationModule : AbpModule
    {
    }
}

第二步:使用 appsettings.json 存儲配置項,如下所示
代碼清單:AbpManual.Web/appsettings.json

{ 
  ...
  "Settings": {
    "Abp.Mailing.Smtp.Host": "smtp.126.com",
    "Abp.Mailing.Smtp.Port": "25",
    "Abp.Mailing.Smtp.UserName": "abpdev",
    "Abp.Mailing.Smtp.Password": "rHGKfmXnrF7p8uZovp2I6A==", // 原值:123, 是郵箱smtp服務的授權碼
    "Abp.Mailing.Smtp.Domain": "",
    "Abp.Mailing.Smtp.EnableSsl": "false",
    "Abp.Mailing.Smtp.UseDefaultCredentials": "false",
    "Abp.Mailing.DefaultFromAddress": "[email protected]",
    "Abp.Mailing.DefaultFromDisplayName": "Abp 手冊"
  },
  "StringEncryption": {
    "DefaultPassPhrase": "DOKIDhw8UbBTB82G" //加密鹽
  }

}

特別注意:
Abp.Mailing.Smtp.Password 必須是一個加密值, 不能使用原值,否則拋如下異常,

 The input data is not a complete block.
System.Security.Cryptography.CryptographicException: The input data is not a complete block.
   at Internal.Cryptography.UniversalCryptoDecryptor.UncheckedTransformFinalBlock(Byte[] inputBuffer, Int32 inputOffset, Int32 inputCount)
   at Internal.Cryptography.UniversalCryptoTransform.TransformFinalBlock(Byte[] inputBuffer, Int32 inputOffset, Int32 inputCount)
   at System.Security.Cryptography.CryptoStream.ReadAsyncCore(Byte[] buffer, Int32 offset, Int32 count, CancellationToken cancellationToken, Boolean useAsync)

如何根據密碼的原值得到加密值,見下一節:加密 SMTP 密碼

Tips:如何郵箱申請開通smtp服務
先去郵箱平臺申請一個郵箱,然後申請開通smtp服務,
這我使用的是126郵箱,Abp.Mailing.Smtp.Password 的原值不是郵箱的登錄密碼,
而是申請開通smtp服務成功後,得到的一個授權碼

第三步:發送郵件

using Microsoft.Extensions.Logging;
using Volo.Abp;
using Volo.Abp.BackgroundJobs;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Emailing;

namespace AbpManual.BackgroundJobs
{
    /// <summary>
    /// https://docs.abp.io/zh-Hans/abp/latest/Background-Jobs
    /// 後臺作業是一個實現IBackgroundJob<TArgs>接口或繼承自BackgroundJob<TArgs>類的類
    /// </summary>
    public class EmailSendingJob : AsyncBackgroundJob<EmailSendingArgs>, ITransientDependency
    {
        private readonly IEmailSender _emailSender;
        private readonly ILogger<EmailSendingJob> _logger;

        public EmailSendingJob(
            IEmailSender emailSender,
            ILogger<EmailSendingJob> logger)
        {
            _emailSender = emailSender;
            _logger = logger;
        }

        public override  async Task ExecuteAsync(EmailSendingArgs args)
        {
            // 模擬隨機產生異常,看看後臺作業是否因失敗再次執行
            if (RandomHelper.GetRandom(0, 10) < 5)
            {
                throw new ApplicationException("A sample exception from the EmailSendingJob!");
            }

            _logger.LogInformation($"############### EmailSendingJob: 郵件已成功發送至郵箱:{args.EmailAddress} ###############");

            //lock (Console.Out)
            //{
            //    var oldColor = Console.ForegroundColor;
            //    Console.ForegroundColor = ConsoleColor.Green;

            //    Console.WriteLine();
            //    Console.WriteLine($"############### EmailSendingJob: 郵件已成功發送至郵箱:{args.EmailAddress} ###############");
            //    Console.WriteLine();

            //    Console.ForegroundColor = oldColor;
            //}

            // 發送郵件
            await _emailSender.SendAsync(
               args.EmailAddress,
               args.Subject,
               args.Body
           );
        }
    }
}

第四步:測試
編輯測試服務
代碼清單:AbpManual.Application/BackgroundJobs/BackgroundJobService.cs

using AbpManual.BackgroundJobs;
using Volo.Abp.Application.Services;
using Volo.Abp.BackgroundJobs;

namespace AbpManaul.BackgroundJobs
{
    public class BackgroundJobService : ApplicationService, IBackgroundJobService
    {
        /// <summary>
        /// 默認後臺作業管理器
        /// https://docs.abp.io/zh-Hans/abp/latest/Background-Jobs
        /// ABP framework 包含一個簡單的 IBackgroundJobManager 實現;
        /// </summary>
        private readonly IBackgroundJobManager _backgroundJobManager;

        public BackgroundJobService(IBackgroundJobManager backgroundJobManager)
        {
            _backgroundJobManager = backgroundJobManager;
        }

        public async Task RegisterAsync(RegisterInput input)
        {
            //TODO: 創建一個新用戶到數據庫中...

            await _backgroundJobManager.EnqueueAsync(
                new EmailSendingArgs
                {
                    EmailAddress = input.EmailAddress,
                    Subject = "You've successfully registered!",
                    Body = "恭喜你註冊成功!"
                }
            );
        }
    }

    public class RegisterInput
    {
        public string Name { get; set; }
        public string EmailAddress { get; set; }
        public string Password { get; set; }
    }
}

點擊執行按鈕,郵件發送成功,如下圖所示:

郵件內容也正確:

加密 SMTP 密碼

Abp.Mailing.Smtp.Password 必須是一個加密值。如果你使用 ISettingManager 設置密碼,你不必擔心。它在內部加密 set 上的值並在 get 上解密。
如果使用 appsettings.json 存儲密碼,則應手動注入 ISettingEncryptionService 並使用其 Encrypt 方法獲取加密值。這可以通過在你的應用程序中創建一個簡單的代碼來完成。然後你可以刪除代碼。
更好的做法是,你可以在應用程序中創建一個 UI 來配置電子郵件設置。在這種情況下,你可以直接使用 ISettingManager 而不用擔心加密。

定義一個函數,獲取加密後的密碼,如下所示:

using Volo.Abp.Emailing;
using Volo.Abp.Settings;

namespace AbpManaul.Application.Settings;

public class SettingService
{
    private readonly ISettingEncryptionService _settingEncryptionService;
    private readonly ISettingDefinitionManager _settingDefinitionManager;

    public SettingService(
            ISettingEncryptionService settingEncryptionService,
            ISettingDefinitionManager settingDefinitionManager)
    {
        _settingEncryptionService = settingEncryptionService;
        _settingDefinitionManager = settingDefinitionManager;
    }

    public string EncryptMailingSmtpPassword(string passsword)
    {

        var setting = _settingDefinitionManager.Get(EmailSettingNames.Smtp.Password);
        var encryptPassword = _settingEncryptionService.Encrypt(setting, passsword);

        return encryptPassword;
    }
}

然後調用函數EncryptMailingSmtpPassword(),獲取加密後的密碼,比如:
調用函數EncryptMailingSmtpPassword(123) 返回 "3zil2vJ325s+uboMEiKCDA=="
然後在使用該值在配置文件 appsettings.jsonAbp.Mailing.Smtp.Password 進行設置,如下所示:

...
  "Settings": {
    ...
    "Abp.Mailing.Smtp.Password": "3zil2vJ325s+uboMEiKCDA==",
    ...
  },
...
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章