项目

邮件发送

ABP 为邮件发送提供了多种服务、设置及集成功能:

安装

如果您使用的是 应用启动模板 ,此包已默认安装。

建议使用 ABP CLI 安装此包。在项目文件夹(.csproj 文件所在目录)打开命令行窗口,输入以下命令:

abp add-package Volo.Abp.Emailing

如果尚未安装 ABP CLI,请先进行安装。其他安装选项请参阅 包详情页面

发送邮件

IEmailSender

在任何服务中注入 IEmailSender,并使用 SendAsync 方法发送邮件。

示例

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",     // 目标邮箱地址
                "邮件主题",               // 主题
                "这是邮件正文..."        // 邮件正文
            );
        }
    }
}

SendAsync 方法支持多个重载参数,例如:

  • from:可作为第一个参数设置发件人邮箱地址。若未提供,则使用默认发件人地址(见下方邮件设置)。
  • to:可设置目标邮箱地址。
  • subject:可设置邮件主题。
  • body:可设置邮件正文。
  • isBodyHtml:指示邮件正文是否包含 HTML 标签。默认值为 true
  • additionalEmailSendingArgs:此参数用于向 IEmailSender 实现传递额外参数,包括:抄送(CC)、EmailAttachment 列表及其他属性。

建议使用 IEmailSender 发送邮件,因其可使代码与邮件提供商无关。

MailMessage

除基本参数外,还可传递标准 MailMessage 对象参见)给 SendAsync 方法,以设置更多选项,如添加附件。

ISmtpEmailSender

邮件发送默认通过标准 SmtpClient 类(参见)实现,实现类为 SmtpEmailSender。该类同时公开 ISmtpEmailSender 服务(除 IEmailSender 外)。

多数情况下,建议直接使用 IEmailSender 以保持代码与提供商无关。但如需使用相同邮件设置创建 SmtpClient 对象,可注入 ISmtpEmailSender 并使用其 BuildClientAsync 方法获取 SmtpClient 对象,自行发送邮件。

邮件排队 / 后台作业

IEmailSender 提供 QueueAsync 方法,可将邮件加入后台作业队列,在后台线程中发送。这样不会因等待邮件发送而占用用户时间。QueueAsync 方法与 SendAsync 方法的参数相同。

邮件排队具备容错能力,因后台作业系统具有重试机制,可应对临时网络/服务器问题。

有关后台作业系统的更多信息,请参阅 后台作业文档

邮件设置

邮件发送使用设置系统定义设置并在运行时获取值。Volo.Abp.Emailing.EmailSettingNames 定义了设置名称的常量,如下所示:

  • Abp.Mailing.DefaultFromAddress:未指定发件人时用作发件人邮箱地址(如上例所示)。
  • Abp.Mailing.DefaultFromDisplayName:未指定发件人时用作发件人显示名称(如上例所示)。
  • Abp.Mailing.Smtp.Host:SMTP 服务器的 IP/域名(默认:127.0.0.1)。
  • Abp.Mailing.Smtp.Port:SMTP 服务器的端口(默认:25)。
  • Abp.Mailing.Smtp.UserName:用户名(若 SMTP 服务器需认证)。
  • Abp.Mailing.Smtp.Password:密码(若 SMTP 服务器需认证)。此值为加密值(见下文)。
  • Abp.Mailing.Smtp.Domain:用户名的域(若 SMTP 服务器需认证)。
  • Abp.Mailing.Smtp.EnableSsl:指示 SMTP 服务器是否使用 SSL("true" 或 "false",默认:"false")。
  • Abp.Mailing.Smtp.UseDefaultCredentials:若为 true,则使用默认凭据而非提供的用户名和密码("true" 或 "false",默认:"true")。

邮件设置可通过设置管理模块的设置页面进行管理:

邮件设置

若使用 ABP 启动模板创建解决方案,设置管理模块已默认安装。

若不使用设置管理模块,可在 appsettings.json 文件中定义设置:

"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 应用"
}

可通过 ISettingManager 以编程方式设置/更改这些设置,并将值存储在数据库中。更多关于设置系统的信息,请参阅设置系统文档

加密 SMTP 密码

Abp.Mailing.Smtp.Password 必须为加密值。若使用 ISettingManager 设置密码,无需担心,其内部会在设置时加密并在获取时解密。

若使用 appsettings.json 存储密码,需手动注入 ISettingEncryptionService 并使用其 Encrypt 方法获取加密值。可通过在应用中编写简单代码实现,完成后可删除代码。更好的做法是在应用中创建 UI 来配置邮件设置,此时可直接使用 ISettingManager 而无需担心加密问题。

ISmtpEmailSenderConfiguration

若不想使用设置系统存储邮件发送配置,可替换 ISmtpEmailSenderConfiguration 服务,通过自定义实现从其他源获取配置。默认情况下,ISmtpEmailSenderConfigurationSmtpEmailSenderConfiguration 实现,其从上文所述的设置系统获取配置。

文本模板集成

ABP 提供强大灵活的 文本模板系统 。可使用文本模板系统创建动态邮件内容。注入 ITemplateRenderer 并使用 RenderAsync 渲染模板,然后将结果作为邮件正文。

除可定义和使用自己的文本模板外,邮件发送系统还提供两个简单的内置文本模板。

示例:使用标准简单消息模板发送邮件

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

namespace Acme.BookStore.Web
{
    public class MyService : ITransientDependency
    {
        private readonly IEmailSender _emailSender;
        private readonly ITemplateRenderer _templateRenderer;

        public MyService(
        IEmailSender emailSender,
        ITemplateRenderer templateRenderer)
        {
            _emailSender = emailSender;
            _templateRenderer = templateRenderer;
        }

        public async Task DoItAsync()
        {
            var body = await _templateRenderer.RenderAsync(
                StandardEmailTemplates.Message,
                new
                {
                    message = "这是邮件正文..."
                }
            );
            
            await _emailSender.SendAsync(
                "target-address@domain.com",
                "邮件主题",
                body
            );
        }
    }
}

生成的邮件正文如下所示:

<!DOCTYPE html>
<html lang="zh" xmlns="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="utf-8" />
</head>
<body>
    这是邮件正文...
</body>
</html>

邮件系统使用以下名称定义内置文本模板:

"Abp.StandardEmailTemplates.Message" 是最简单的模板,包含文本消息:

{{model.message}}

此模板使用 "Abp.StandardEmailTemplates.Layout" 作为其布局。

"Abp.StandardEmailTemplates.Layout" 是提供 HTML 文档布局的简单模板:

<!DOCTYPE html>
<html lang="zh" xmlns="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="utf-8" />
</head>
<body>
    {{content}}
</body>
</html>

最终渲染的消息如上所示。

这些模板名称是 Volo.Abp.Emailing.Templates.StandardEmailTemplates 类中定义的常量。

覆盖/替换标准模板

通常需要用自己的模板替换标准模板,以创建具有品牌特色的邮件内容。为此,可利用虚拟文件系统(VFS)的强大功能,或在自定义模板定义提供程序中替换它们。

模板在虚拟文件系统中的路径如下:

  • /Volo/Abp/Emailing/Templates/Layout.tpl
  • /Volo/Abp/Emailing/Templates/Message.tpl

若在虚拟文件系统的相同位置添加文件,您的文件将覆盖它们。

模板支持内联本地化,这意味着可利用本地化系统使模板支持多文化。

详情请参阅 文本模板系统 文档。

注意,您可为应用定义和使用自己的模板,而非使用标准简单模板。这些标准模板主要用于可复用模块,这些模块不定义自己的模板,而是依赖内置模板。通过覆盖标准邮件布局模板,可轻松自定义所用模块发送的邮件。

NullEmailSender

NullEmailSender 是一个内置类,实现 IEmailSender 接口,但将邮件内容写入标准日志系统,而非实际发送邮件。

此类在开发阶段尤其有用,因为通常不希望发送真实邮件。应用启动模板DEBUG 模式下已在领域层通过以下配置使用此类:

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

因此,若在 DEBUG 模式下未收到邮件,不必困惑。在生产环境(RELEASE 模式)下,邮件将按预期发送。若希望在 DEBUG 模式下也发送真实邮件,请移除这些行。

另请参阅

在本文档中