.NET CORE 下通过 SmtpClient 发送邮件

通过本文你可以实现:使用 .NET SmtpClient 来发送邮件

  • 基础使用:仅含有邮件内容,无附件;
  • 发送含有附件的邮件;
  • 以及抄送等功能。

接口及实现:

public class MailNotificationConfiguration
{
    public string SMTP { get; set; }
    public string[] Notify { get; set; }
    public string[] EmailWhiteList { get; set; }
}

public interface INotificationService
{
    Task NotifyByMailAsync(string subject, string body, string[] to, object att = null, string[] cc = null);

    string MakeEmailBody(string name, params string[] contentLines);
}

public class NotificationService : INotificationService
{
    private readonly MailNotificationConfiguration _notificationConfig; 
    private readonly string _env;
    /// <summary>
    /// 
    /// </summary>
    /// <param name="config"></param>
    /// <param name="environment">value of environment variable:ASPNETCORE_ENVIRONMENT</param>
    public NotificationService(MailNotificationConfiguration config, string env)
    {
        _notificationConfig = config;
        _env = env;
    }

    public string MakeEmailBody(string name, params string[] contentLines)
    {
        var contentSb = new StringBuilder("<html>");
        contentSb.Append("<body>");
        contentSb.Append($"<p>Hi {name}, </p>");
        contentSb.Append("<div>");
        if (contentLines != null && contentLines.Count() > 0)
        {
            foreach (var item in contentLines)
            {
                contentSb.AppendLine($"<p>{item}</p>");
            }
        }
        contentSb.Append("<div>");
        contentSb.Append("<br/>");
        contentSb.Append("<div>");
        contentSb.Append("<p>Thanks & Regards</p>");
        contentSb.Append("<p>XXXX</p>");
        contentSb.Append("<p><b style='background-color:yellow'>Note: This mail is sent automatically, please do not reply.</b></p>");
        contentSb.Append("</div>");
        contentSb.Append("</body>");
        contentSb.Append("</html>");

        return contentSb.ToString();
    }

    public async Task NotifyByMailAsync(string subject, string body, string[] to, object att = null, string[] cc = null)
    {
        var mail = new MailMessage()
        {
            From = new MailAddress("SENDING_EMAIL_NAME@XXXX.com", "EMAIL_DISPLAY_NAME"),
            BodyEncoding = Encoding.UTF8,
            IsBodyHtml = true,
            DeliveryNotificationOptions = DeliveryNotificationOptions.OnFailure,
            Subject = IsProductEnvironment()
                        ? subject
                        : $"[{_env}] {subject}",
            Body = body
        };

        var inMailAttachment = att as Attachment;

        if (inMailAttachment != null)
        {
            mail.Attachments.Add(inMailAttachment);
        }
        to.ToList().ForEach(n => mail.To.Add(n));

        cc?.ToList().ForEach(ccAddress => mail.CC.Add(ccAddress));

        try
        {
            using var client = new SmtpClient
            {
                Host = _notificationConfig.SMTP, //mail server host
                DeliveryMethod = SmtpDeliveryMethod.Network
            };

            if (IsProductEnvironment())
            {
                await client.SendMailAsync(mail);
            }
            else
            {
                //验证是否白名单用户,对 mail.To 属性进行过滤,仅发送给白名单用户
                /* mail.To = 白名单用户*/
                if (mail.To.Count() > 0)
                    await client.SendMailAsync(mail);
            }
        }
        catch (Exception ex)
        {
            ;
        }
        finally
        {
            if (inMailAttachment != null)
                inMailAttachment.Dispose();
        }
    }

    private bool IsProductEnvironment()
    {
        return _env == "Production" || _env == "Stage";
    }
}

配置信息

appsettings.json

{
  "MailNotification": {
    "SMTP": "email server host address",
    "Notify": [ "1@1.com", "2@2.com"],
    "EmailWhiteList": [
      "user1",
      "user2",
    ]
  }
}

使用示例:

在 IOC 中进行注入

public void ConfigureServices(IServiceCollection services)
{
   services.Configure<MailNotificationConfiguration>(Configuration.GetSection("MailNotification"));
   services.AddSingleton<INotificationService, NotificationService>(sp => new NotificationService(sp.GetService<IOptions<MailNotificationConfiguration>>().Value, Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT")));
}

基础使用示例

public class SomeController : ControllerBase
{
    private readonly INotificationService _notificationService;
    public SomeController(INotificationService notificationService)
    {
        _notificationService = notificationService;
    }

    public async Task<IActionResult> SendEmail()
    {
         var toMails = new []{};
        var contents = new string[]
        {
             "1",
             "2",
             "3"
        };
        var body = _notificationService.MakeEmailBody("team", contents);
       await  _notificationService.NotifyByMailAsync("email title", body,  toMails);
        return Ok();
    }
}

发送附件示例

public class SomeController : ControllerBase
{
    private readonly INotificationService _notificationService;
    public SomeController(INotificationService notificationService)
    {
        _notificationService = notificationService;
    }

    public async Task<IActionResult> SendEmail()
    {
        var toMails = new []{};
        var ccMails = new []{};
        var contents = new string[]
        {
             "1",
             "2",
             "3"
        };
        var file = GetFileByteArray(); //file content
       using (Stream stream = new MemoryStream(file))
       {
           var att = new Attachment(stream, $"yourfile.xlsx");
           await _notificationService.NotifyByMailAsync($"your email title","email body content",
              toMails,
               att,
              ccMails);
       }

        return Ok();
    }
}