.NET CORE 下通过 SmtpClient 发送邮件

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

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

接口及实现:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
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

1
2
3
4
5
6
7
8
9
10
{
"MailNotification": {
"SMTP": "email server host address",
"Notify": [ "1@1.com", "2@2.com"],
"EmailWhiteList": [
"user1",
"user2",
]
}
}

使用示例:

在 IOC 中进行注入

1
2
3
4
5
 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")));
}

基础使用示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
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();
}
}

发送附件示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
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();
}
}