Email.cs 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  1. using Masuit.Tools.Systems;
  2. using System;
  3. using System.Collections.Generic;
  4. using System.Linq;
  5. using System.Net.Mail;
  6. namespace Masuit.Tools.Models;
  7. public class Email : Disposable
  8. {
  9. /// <summary>
  10. /// 发件人用户名
  11. /// </summary>
  12. public EmailAddress Username { get; set; }
  13. /// <summary>
  14. /// 发件人邮箱密码
  15. /// </summary>
  16. public string Password { get; set; }
  17. /// <summary>
  18. /// 发送服务器端口号,默认25
  19. /// </summary>
  20. public int SmtpPort { get; set; } = 25;
  21. /// <summary>
  22. /// 发送服务器地址
  23. /// </summary>
  24. public string SmtpServer { get; set; }
  25. /// <summary>
  26. /// 邮件标题
  27. /// </summary>
  28. public string Subject { get; set; }
  29. /// <summary>
  30. /// 邮件正文
  31. /// </summary>
  32. public string Body { get; set; }
  33. /// <summary>
  34. /// 收件人,多个收件人用英文逗号隔开
  35. /// </summary>
  36. public string Tos { get; set; }
  37. public List<string> CC { get; set; } = new List<string>();
  38. public List<string> BCC { get; set; } = new List<string>();
  39. /// <summary>
  40. /// 是否启用SSL,默认已启用
  41. /// </summary>
  42. public bool EnableSsl { get; set; } = true;
  43. /// <summary>
  44. /// 附件
  45. /// </summary>
  46. public List<Attachment> Attachments { get; set; } = new List<Attachment>();
  47. private MailMessage _mailMessage;
  48. private MailMessage MailMessage => _mailMessage ?? GetClient();
  49. /// <summary>
  50. /// 邮件消息对象
  51. /// </summary>
  52. private MailMessage GetClient()
  53. {
  54. if (string.IsNullOrEmpty(Tos)) return null;
  55. _mailMessage = new MailMessage();
  56. //多个接收者
  57. foreach (var str in Tos.Split(','))
  58. {
  59. _mailMessage.To.Add(str);
  60. }
  61. foreach (var s in CC)
  62. {
  63. _mailMessage.CC.Add(s);
  64. }
  65. foreach (var s in BCC)
  66. {
  67. _mailMessage.Bcc.Add(s);
  68. }
  69. _mailMessage.From = new MailAddress(Username, Username);
  70. _mailMessage.Subject = Subject;
  71. _mailMessage.Body = Body;
  72. _mailMessage.IsBodyHtml = true;
  73. _mailMessage.BodyEncoding = System.Text.Encoding.UTF8;
  74. _mailMessage.SubjectEncoding = System.Text.Encoding.UTF8;
  75. _mailMessage.Priority = MailPriority.High;
  76. foreach (var item in Attachments.AsNotNull().Where(a => a is not null))
  77. {
  78. _mailMessage.Attachments.Add(item);
  79. }
  80. return _mailMessage;
  81. }
  82. private SmtpClient SmtpClient => new()
  83. {
  84. UseDefaultCredentials = false,
  85. EnableSsl = EnableSsl,
  86. Host = SmtpServer,
  87. Port = SmtpPort,
  88. Credentials = new System.Net.NetworkCredential(Username, Password),
  89. DeliveryMethod = SmtpDeliveryMethod.Network,
  90. };
  91. //回调方法
  92. private Action<string> _actionSendCompletedCallback;
  93. /// <summary>
  94. /// 使用异步发送邮件
  95. /// </summary>
  96. /// <param name="completedCallback">邮件发送后的回调方法</param>
  97. /// <returns></returns>
  98. public void SendAsync(Action<string> completedCallback)
  99. {
  100. if (MailMessage == null) return;
  101. //发送邮件回调方法
  102. _actionSendCompletedCallback = completedCallback;
  103. SmtpClient.SendCompleted += SendCompletedCallback;
  104. SmtpClient.SendAsync(MailMessage, "true"); //异步发送邮件,如果回调方法中参数不为"true"则表示发送失败
  105. }
  106. /// <summary>
  107. /// 使用同步发送邮件
  108. /// </summary>
  109. public void Send()
  110. {
  111. if (MailMessage == null) return;
  112. SmtpClient.Send(MailMessage); //异步发送邮件,如果回调方法中参数不为"true"则表示发送失败
  113. Dispose(true);
  114. }
  115. /// <summary>
  116. /// 异步操作完成后执行回调方法
  117. /// </summary>
  118. /// <param name="sender"></param>
  119. /// <param name="e"></param>
  120. private void SendCompletedCallback(object sender, System.ComponentModel.AsyncCompletedEventArgs e)
  121. {
  122. //同一组件下不需要回调方法,直接在此写入日志即可
  123. //写入日志
  124. if (_actionSendCompletedCallback == null) return;
  125. string message;
  126. if (e.Cancelled)
  127. {
  128. message = "异步操作取消";
  129. }
  130. else if (e.Error != null)
  131. {
  132. message = $"UserState:{(string)e.UserState},Message:{e.Error}";
  133. }
  134. else
  135. {
  136. message = (string)e.UserState;
  137. }
  138. //执行回调方法
  139. _actionSendCompletedCallback(message);
  140. Dispose(true);
  141. }
  142. /// <summary>
  143. /// 释放
  144. /// </summary>
  145. /// <param name="disposing"></param>
  146. public override void Dispose(bool disposing)
  147. {
  148. _mailMessage?.Dispose();
  149. SmtpClient?.Dispose();
  150. Attachments?.ForEach(a => a?.Dispose());
  151. }
  152. }