邮件发送
ABP 为邮件发送提供了多种服务、设置及集成功能:
- 提供用于发送邮件的
IEmailSender服务。 - 定义用于配置邮件发送的 设置。
- 集成 后台作业系统 ,通过后台作业发送邮件。
- 提供 MailKit 集成包。
安装
如果您使用的是 应用启动模板 ,此包已默认安装。
建议使用 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 服务,通过自定义实现从其他源获取配置。默认情况下,ISmtpEmailSenderConfiguration 由 SmtpEmailSenderConfiguration 实现,其从上文所述的设置系统获取配置。
文本模板集成
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 模式下也发送真实邮件,请移除这些行。
抠丁客



