1、安装引用FluentEmail方法
参照文档:.NET Core(ASP.NET Core)使用FluentEmail发送邮件方法及示例代码
2、Startup.cs中ConfigureServices(IServiceCollection services)中配置
// 配置 IFluentEmail
services.AddFluentEmail(Configuration["email_address"])
.AddRazorRenderer()
.AddSmtpSender(new SmtpClient("smtp.gmail.com", 587)
{
Credentials = new NetworkCredential(Configuration["email_address"], Configuration["email_password"]),
EnableSsl = true
});
// 添加 service
services.TryAddScoped<IEmailSender, EmailSender>();
配置示例中使用GMAIL帐户发送电子邮件,可以使用所需的任何电子邮件服务器。
3、使用FluentEmail发送邮件示例代码
//通过模板发送邮件的接口
public interface IEmailSender
{
Task<bool> SendUsingTemplate(string to, string subject, EmailTemplate template, object model);
}
//邮件模板
public enum EmailTemplate
{
EmailConfirmation,
ChangeEmail
}
public class EmailSender : IEmailSender
{
//需要更改的是TemplatePath常量,该常量需要包含模板文件(.cshtml文件)所在的完整命名空间名称。
private const string TemplatePath = "Web.Api.Infrastructure.Services.Emails.Templates.{0}.cshtml";
private readonly IFluentEmail _email;
private readonly ILogger<EmailSender> _logger;
public EmailSender(IFluentEmail email, ILogger<EmailSender> logger)
{
_email = email;
_logger = logger;
}
public async Task<bool> SendUsingTemplate(string to, string subject, EmailTemplate template, object model)
{
var result = await _email.To(to)
.Subject(subject)
.UsingTemplateFromEmbedded(string.Format(TemplatePath, template), ToExpando(model), GetType().Assembly)
.SendAsync();
if (!result.Successful)
{
_logger.LogError("Failed to send an email.\n{Errors}", string.Join(Environment.NewLine, result.ErrorMessages));
}
return result.Successful;
}
}
注意:在模板中使用匿名对象,我们需要将其转换为Expando objects。这是RazorLight(FluentEmail用于处理Razor模板的库)所具有的“限制” 。
private static ExpandoObject ToExpando(object model)
{
if (model is ExpandoObject exp)
{
return exp;
}
IDictionary<string, object> expando = new ExpandoObject();
foreach (var propertyDescriptor in model.GetType().GetTypeInfo().GetProperties())
{
var obj = propertyDescriptor.GetValue(model);
if (obj != null && IsAnonymousType(obj.GetType()))
{
obj = ToExpando(obj);
}
expando.Add(propertyDescriptor.Name, obj);
}
return (ExpandoObject)expando;
}
private static bool IsAnonymousType(Type type)
{
bool hasCompilerGeneratedAttribute = type.GetTypeInfo()
.GetCustomAttributes(typeof(CompilerGeneratedAttribute), false)
.Any();
bool nameContainsAnonymousType = type.FullName.Contains("AnonymousType");
bool isAnonymousType = hasCompilerGeneratedAttribute && nameContainsAnonymousType;
return isAnonymousType;
}
3、嵌入cshtml模板
上面代码引用cshtml模板需要嵌入资源,要cshtml模板打包在程序集中,在cshtml模板文件中属性窗口:"生成操作"
=》选择 "嵌入的资源"
相关文档: