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模板文件中属性窗口:"生成操作"
=》选择 "嵌入的资源"
相关文档: