preface
In actual project development, we will encounter many scenarios that require sending emails through programs, such as exception alarms, messages, progress notifications, etc. Under normal circumstances, we mostly use the native SmtpClient class library, which can satisfy most of our scenarios. However, it is not concise enough to use. Many scenarios require us to package our own methods to implement them, and the amount of code is very considerable. Fortunately, we have a very great component that can meet most of our application scenarios and is simple to use and powerful. It is the FluentEmail we are talking about today, which is also the email sending component we are actually using in the project. If you have the need to send email in. NET Core, I recommend you to try it.
FluentEmail
FluentEmail is an open source and free email sending component that supports. Net and. NET Core on GitHub. Currently, there are more than 1K Stars. In the past two years, as. NET Core has become increasingly mature, its Star growth trend is still very rapid. Its GitHub address is https://github.com/lukencode/FluentEmail. It is very powerful and practical. It supports Razor's mail template and supports sending emails using SendGrid, MailGun, and SMTP, and it is very simple to use.
NuGet components
FluentEmail is powerful and has independent NuGet packages for support for different scenarios. This low-coupling split not only makes the dependency very clear, but also avoids introducing unnecessary code. The specific functions are included in the following component packages
- FluentEmail.Core - 基础核心包,包含了基础的模型定义和默认的设置,而且以下的引用包都包含了这个核心包。
- FluentEmail.Smtp - 使用 SMTP 服务发送邮件的程序包。
- FluentEmail.Razor - 通过 Razor 模板生成邮件发送内容。
- FluentEmail.Mailgun - 使用 Mailgun 的 Rest 接口发送邮件。
- FluentEmail.SendGrid - 使用 SendGrid 接口发送邮件。
- FluentEmail.Mailtrap - 发送邮件 Mailtrap, 使用的是 FluentEmail.Smtp 包进行发送.
- FluentEmail.MailKit - 使用 MailKit 邮件库发送邮件。
Ordinary mail
Next, we will demonstrate how to use FluentEmail to send mail. Since most of our actual business uses SMTP to send mail, we will use this as a demonstration. First of all, we introduced the FluentEmail.Smtp package into the project. The latest version is 2.8.0
<PackageReference Include="FluentEmail.Smtp" Version="2.8.0" />
Next, we can happily write code. Its coding method is very simple and concise, mainly through chain programming.
//如果使用smtp服务发送邮件必须要设置smtp服务信息
SmtpClient smtp = new SmtpClient
{
//smtp服务器地址(我这里以126邮箱为例,可以依据具体你使用的邮箱设置)
Host = "smtp.126.com",
UseDefaultCredentials = true,
DeliveryMethod = SmtpDeliveryMethod.Network,
//这里输入你在发送smtp服务器的用户名和密码
Credentials = new NetworkCredential("邮箱用户名", "邮箱密码")
};
//设置默认发送信息
Email.DefaultSender = new SmtpSender(smtp);
var email = Email
//发送人
.From("zhangsan@126.com")
//收件人
.To("lisi@qq.com")
//抄送人
.CC("admin@126.com")
//邮件标题
.Subject("邮件标题")
//邮件内容
.Body("邮件内容");
//依据发送结果判断是否发送成功
var result = email.Send();
//或使用异步的方式发送
//await email.SendAsync();
if (result.Successful)
{
//发送成功逻辑
}
else
{
//发送失败可以通过result.ErrorMessages查看失败原因
}
If the content you send contains html format content, you can use the following methods
var email = Email
//发送人
.From("zhangsan@126.com")
//收件人
.To("lisi@qq.com")
//抄送人
.CC("admin@126.com")
//邮件标题
.Subject("邮件标题")
//只需要额外设置第二个参数为true即可
.Body("<h1 align=\"center\">.NET大法好</h1><p>是的,这一点毛病都没有</p>",true);
//发送
var result = email.Send();
We can find out by clicking the method declaration to view Body. The second parameter is used to indicate whether the content is in html format. The default is false.
IFluentEmail Body (string body, bool isHtml = false);
If the recipient of the message is multiple mailbox addresses, another overloaded method of the To method can accept List<FluentEmail.Core.Models.Address>
var email = Email
//发送人
.From("zhangsan@126.com")
//邮件标题
.Subject("邮件标题")
//邮件内容
.Body("<h1 align=\"center\">.NET大法好</h1><p>是的,一点毛病都没有</p>",true);
//构建多个接收人邮箱
string toUserStr = "oldwang@126.com;xiaoming@163.com;xiaoli@qq.com";
List<FluentEmail.Core.Models.Address> toUsers = toUserStr.Split(";")
.Select(i => new FluentEmail.Core.Models.Address { EmailAddress = i }).ToList();
//支持传入Address集合
email.To(toUsers)
//抄送人集合
.CC(toUsers);
//发送
var result = email.Send();
If we need to add an attachment to the email we send, we can use the Attache method to add the attachment
var email = Email
//发送人
.From("zhangsan@qq.com")
//收件人
.To("lisi@126.com")
//抄送人
.CC("admin@126.com")
//邮件标题
.Subject("关于.NET Core怎么样")
//邮件内容
.Body("<h1 align=\"center\">.NET Core</h1><p>.NET Core很优秀吗?是的,一点毛病都没有!!!</p>",true);
//构建附件
var stream = new MemoryStream();
var sw = new StreamWriter(stream);
sw.WriteLine("您好,这是文本里的内容");
sw.Flush();
stream.Seek(0, SeekOrigin.Begin);
var attachment = new FluentEmail.Core.Models.Attachment
{
Data = stream,
ContentType = "text/plain",
Filename = "Hello.txt"
};
//添加附件
email.Attach(attachment);
var result = email.Send();
If you need to add multiple attachments, the Attach method supports passing in the Attachment collection
//构建附件
var stream = new MemoryStream();
var sw = new StreamWriter(stream);
sw.WriteLine("您好,这是文本里的内容");
sw.Flush();
stream.Seek(0, SeekOrigin.Begin);
//附件1
var attachment = new FluentEmail.Core.Models.Attachment
{
Data = stream,
ContentType = "text/plain",
Filename = "Hello.txt"
};
//附件2
var attachment2 = new FluentEmail.Core.Models.Attachment
{
Data = File.OpenRead(@"D:\test.txt"),
ContentType = "text/plain",
Filename = "test.txt"
};
//添加附件
email.Attach(new List<FluentEmail.Core.Models.Attachment> { attachment, attachment2 });
var result = email.Send();
Using Razor templates
In the above content, we introduced using FluentEmail to send email in the normal way, but sometimes we need to send some content that is dynamic or send some complex html web page content. Usually, when we use the native SmptClient, we use the method of splicing html code, but this method is relatively time-consuming and labor-intensive. For. Net programmers, the Razor engine is the most familiar way we build dynamic html pages, and FluentEmail provides us with support for Razor templates. First of all, we introduced the FluentEmail.Razor template support component based on our previous work
<PackageReference Include="FluentEmail.Razor" Version="2.8.0" />
Since ASP.NET Core 2.2 starts using the view compilation function by default, the view will be compiled into the project name.Views.dll, but FluentEmail.Razor needs to read the contents of the view file, so add the following content to the csproj file
<MvcRazorExcludeRefAssembliesFromPublish>true</MvcRazorExcludeRefAssembliesFromPublish>
Then we can use the Razor template to generate email content. How to use it?
//声明使用razor的方式
Email.DefaultRenderer = new RazorRenderer();
//razor内容
var template = "你好@Model.Name先生, 请核实您的电话号码是否为@Model.Phone";
var email = Email
.From("lisi@126.com")
.To("zhangsan@qq.com")
.Subject("手机号核实")
//传递自定义POCO类
//.UsingTemplate<UserInfo>(template, new UserInfo { Name = "张三", Phone吗 = "100110119120" })
//或传递匿名对象
.UsingTemplate(template, new { Name = "张三", Phone吗 = "100110119120" });
var result = await email.SendAsync();
Of course, it supports not only Razor strings, but also Razor view files.
var email = Email
.From("lisi@126.com")
.To("zhangsan@qq.com")
.Subject("手机号核实")
//传递自定义POCO类
//.UsingTemplateFromFile<UserInfo>($"{Directory.GetCurrentDirectory()}/template.cshtml",
// new UserInfo { Name = "张三", Phone吗 = "100110119120" });
//第一个参数为视图文件位置,第二个参数为模型对象
.UsingTemplateFromFile($"{Directory.GetCurrentDirectory()}/template.cshtml",
new { Name = "张三", Phone吗 = "100110119120" });
var result = await email.SendAsync();
FluentEmail. The reason why Razor can support the powerful Razor template engine is mainly due to its internal integration of Razor Light. This is a very powerful Razor engine that can parse Razor template strings or Razor view files into specific string results. For details, please refer to RazorLight's official GitHub address https://github.com/todams/RazorLight. The current official version does not support. NET Core, so you can choose to download the beta version
Install-Package RazorLight -Version 2.0.0-beta10
It's also very simple to use
//razor字符串的方式
var engine = new RazorLightEngineBuilder()
.UseEmbeddedResourcesProject(typeof(Program))
.UseMemoryCachingProvider()
.Build();
string template = "Hello, @Model.Name. Welcome to RazorLight repository";
ViewModel model = new ViewModel {Name = "John Doe"};
//result就是解析后的字符串
string result = await engine.CompileRenderStringAsync("templateKey", template, model);
or how to use razor view files
var engine = new RazorLightEngineBuilder()
.UseFileSystemProject("${Directory.GetCurrentDirectory()}")
.UseMemoryCachingProvider()
.Build();
var model = new {Name = "John Doe"};
string result = await engine.CompileRenderAsync("template.cshtml", model);
Of course, it supports not only these two methods, but it is very powerful both in terms of convenience and functionality. Interested students can check RazorLight's GitHub address on their own, and the explanation is still very detailed. There is no need to discuss too much about how to use RazorLight here.
关于发送的邮件内容,这里有一个非常重要的点需要友情提示一下公共邮箱运营商比如网易或腾讯,有的可能需要手动开启SMTP服务,具体如何设置可以参考https://blog.csdn.net/c13_tianming/article/details/47660635一文。还有一点也比较重要如果你使用公共邮箱运营商的邮箱那么他们会对邮件的标题和内容限制比较大,可能出现的问题比较多,而且开启Smtp服务需要发送短信认证才能开启。好在大部分公司都有自己的邮件系统,在实际发送邮件的过程中可能不会存在这么多的问题。
** Used in conjunction with dependency injection **
In actual development using. NET Core, dependency injection has become an indispensable development model. If you are using. NET Core to develop a project, but you haven't yet been exposed to dependency injection, you need to reflect on yourself first. As a component that keeps pace with the times, FluentEmail can also be used in conjunction with dependency injection. In this way, we can uniformly configure some default settings when registering. There is no need to introduce any additional packages for this operation. If you need to use Smtp, introduce the FluentEmail.Smtp package. If you need to use Razor template, introduce the FluentEmail.Razor package. This part of the injection function is actually included in the FluentEmail.Core package
public void ConfigureServices(IServiceCollection services)
{
SmtpClient smtp = new SmtpClient
{
//smtp服务器地址(我这里以126邮箱为例,可以依据具体你使用的邮箱设置)
Host = "smtp.qq.com",
UseDefaultCredentials = true,
DeliveryMethod = SmtpDeliveryMethod.Network,
//这里输入你在发送smtp服务器的用户名和密码
Credentials = new NetworkCredential("zhangsan@qq.com", "zhangsan")
};
//注入的时候可以添加一些默认的设置
services
//设置默认发送用户
.AddFluentEmail("zhangsan@qq.com")
//添加razor模板支持
//.AddRazorRenderer($"{Directory.GetCurrentDirectory()}/Views")
.AddRazorRenderer()
//配置默认的smtp服务信息
.AddSmtpSender(smtp);
}
Inject ILuentEmail directly into the class that needs to send emails. Don't panic. The Email class we used above actually implements the ILuentEmail interface, so the usage method is completely consistent.
public async Task<IActionResult> SendEmail([FromServices]IFluentEmail email)
{
var result = await email//发送人
//发送人
.From("zhangsan@126.com")
//收件人
.To("lisi@qq.com")
//抄送人
.CC("admin@126.com")
//邮件标题
.Subject("邮件标题")
//邮件内容
.Body("邮件内容").SendAsync();
return View();
}
If you need to send content related to the Razor view template, it will still be the familiar recipe and the familiar flavor. There is no difference, just omitting some of the default configurations we added when registering.
public async Task<IActionResult> SendEmail([FromServices]IFluentEmail email)
{
var template = "你好@Model.Name先生, 请核实您的电话号码是否为@Model.Phone";
var result = await email//发送人
.From("lisi@126.com")
.To("zhangsan@qq.com")
.Subject("手机号核实")
//传递自定义POCO类
//.UsingTemplate<UserInfo>(template, new UserInfo { Name = "张三", Phone吗 = "100110119120" })
//或传递匿名对象
.UsingTemplate(template, new { Name = "张三", Phone吗 = "100110119120" })
.SendAsync();
return View();
}
summary
We will introduce the basic use of FluentEmail here. I personally feel that its own functions are still very powerful and very simple to use. To be honest, before I came into contact with FluentEmail, I often saw other languages integrated email sending components in the garden. They were indeed very powerful. For example, integrating spring-boot-starter-mail into springboot is really very convenient. Later, I accidentally came into contact with FluentEmail and was quite pleased. First, it was its powerful functions and ease of use. NET Core to further optimize its use. At least in. Net and. NET Core, we also have a very convenient email sending component. The author of FluentEmail also called on more developers to understand and participate in the development and practice of FluentEmail. Finally, he posted its GitHub address https://github.com/lukencode/FluentEmail again. If you are interested, you can go and learn about it and don't forget to give a Star.