<develop>:(ShopERP 端)<无> 增加 发送邮件的公共类库。

parent 51afee1b
......@@ -16,7 +16,7 @@ namespace CoreCms.Net.Model.ViewModels.Email
public bool EnableSsl { get; set; } = true;
public string FromAddress { get; set; } = string.Empty;
public int Timeout { get; set; } = 10000; // 10 seconds
public bool UseDefaultCredentials { get; set; } = true;
public bool UseDefaultCredentials { get; set; } = false;//禁止使用系统凭据
}
/// <summary>
......@@ -31,13 +31,13 @@ namespace CoreCms.Net.Model.ViewModels.Email
public class MailMessageModel
{
public List<string> ToAddresses { get; set; } = new List<string>();
public List<string>? CcAddresses { get; set; }
public List<string>? BccAddresses { get; set; }
public string? Subject { get; set; }
public string? Body { get; set; }
public bool IsBodyHtml { get; set; } = true;
public List<MailAttachment>? Attachments { get; set; }
public List<string> ToAddresses { get; set; } = new List<string>();//收件人
public List<string>? CcAddresses { get; set; }//抄送人
public List<string>? BccAddresses { get; set; }//密送人
public string? Subject { get; set; }//邮件主体
public string? Body { get; set; }//邮件正文
public bool IsBodyHtml { get; set; } = true;//是否为 html
public List<MailAttachment>? Attachments { get; set; }//附件
public Encoding? Encoding { get; set; } = Encoding.UTF8;
}
......
......@@ -6,6 +6,7 @@
<ItemGroup>
<PackageReference Include="Consul" Version="1.7.14.7" />
<PackageReference Include="MailKit" Version="4.13.0" />
<PackageReference Include="Microsoft.AspNetCore.Http.Abstractions" Version="2.2.0" />
<PackageReference Include="Microsoft.Extensions.Hosting.Abstractions" Version="8.0.0" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
......
using CoreCms.Net.Model.ViewModels.Email;
using Microsoft.Extensions.Logging;
using MimeKit;
using MimeKit.Text;
using System;
using System.Collections.Generic;
using System.IO;
......@@ -9,6 +11,7 @@ using System.Net.Mail;
using System.Net.Mime;
using System.Text;
using System.Threading.Tasks;
using ContentDisposition = MimeKit.ContentDisposition;
namespace CoreCms.Net.Utility.Helper
{
......@@ -36,85 +39,113 @@ namespace CoreCms.Net.Utility.Helper
throw new ArgumentNullException(nameof(_config.Password));
}
public async Task SendEmailAsync(MailMessageModel message)
#region 异步发送 EMail 信息
/// <summary>
/// 异步发送 EMail 信息
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
public async Task SendWithMailKitAsync(MailMessageModel model)
{
if (message == null)
throw new ArgumentNullException(nameof(message));
var message = new MimeMessage();
if (!message.ToAddresses.Any())
throw new InvalidOperationException("No recipients specified");
// 设置发件人
message.From.Add(new MailboxAddress("Sender", _config.FromAddress));
using var smtpClient = CreateSmtpClient();
using var mailMessage = CreateMailMessage(message);
// 添加收件人
AddRecipients(message.To, model.ToAddresses);
try
// 添加抄送
if (model.CcAddresses?.Count > 0)
{
await smtpClient.SendMailAsync(mailMessage);
_logger?.LogInformation($"Email sent to {string.Join(", ", message.ToAddresses)}");
AddRecipients(message.Cc, model.CcAddresses);
}
catch (SmtpException ex)
{
_logger?.LogError(ex, $"SMTP error sending email: {ex.Message}");
}
catch (Exception ex)
// 添加密送
if (model.BccAddresses?.Count > 0)
{
_logger?.LogError(ex, $"Error sending email: {ex.Message}");
AddRecipients(message.Bcc, model.BccAddresses);
}
}
private SmtpClient CreateSmtpClient()
{
return new SmtpClient(_config.SmtpServer, _config.SmtpPort)
{
EnableSsl = _config.EnableSsl,
Credentials = new NetworkCredential(_config.UserName, _config.Password),
DeliveryMethod = SmtpDeliveryMethod.Network,
Timeout = _config.Timeout,
UseDefaultCredentials = _config.UseDefaultCredentials
};
}
// 设置主题
message.Subject = model.Subject ?? "[No Subject]";
private MailMessage CreateMailMessage(MailMessageModel model)
{
var fromAddress = string.IsNullOrWhiteSpace(_config.FromAddress)
? _config.UserName
: _config.FromAddress;
// 创建多部分邮件
var multipart = new Multipart("mixed");
var mail = new MailMessage
// 创建正文部分
var textPart = new TextPart(model.IsBodyHtml ? TextFormat.Html : TextFormat.Plain)
{
From = new MailAddress(fromAddress),
Subject = model.Subject ?? "[No Subject]",
Body = model.Body ?? string.Empty,
IsBodyHtml = model.IsBodyHtml,
BodyEncoding = model.Encoding ?? Encoding.UTF8,
SubjectEncoding = model.Encoding ?? Encoding.UTF8
Text = model.Body ?? string.Empty
};
multipart.Add(textPart);
// 添加附件
AddAttachments(multipart, model.Attachments);
message.Body = multipart;
// Add recipients
model.ToAddresses.ForEach(to => mail.To.Add(to));
model.CcAddresses?.ForEach(cc => mail.CC.Add(cc));
model.BccAddresses?.ForEach(bcc => mail.Bcc.Add(bcc));
using var client = new MailKit.Net.Smtp.SmtpClient();
// Add attachments
if (model.Attachments != null)
// 阿里邮箱的特殊设置
client.ServerCertificateValidationCallback = (s, c, h, e) => true;
client.Connect(_config.SmtpServer, _config.SmtpPort, MailKit.Security.SecureSocketOptions.SslOnConnect);
client.Authenticate(_config.UserName, _config.Password);
await client.SendAsync(message);
client.Disconnect(true);
}
#endregion
#region 添加收件人
/// <summary>
/// 添加收件人
/// </summary>
/// <param name="list"></param>
/// <param name="addresses"></param>
private void AddRecipients(InternetAddressList list, IEnumerable<string> addresses)
{
foreach (var address in addresses)
{
foreach (var attachment in model.Attachments)
if (!string.IsNullOrWhiteSpace(address))
{
if (attachment.FileData == null || string.IsNullOrWhiteSpace(attachment.FileName))
continue;
var stream = new MemoryStream(attachment.FileData);
mail.Attachments.Add(new Attachment(
stream,
attachment.FileName,
attachment.MediaType ?? MediaTypeNames.Application.Octet
));
list.Add(MailboxAddress.Parse(address.Trim()));
}
}
}
#endregion
#region 添加附件列表
/// <summary>
/// 添加附件列表
/// </summary>
/// <param name="multipart"></param>
/// <param name="attachments"></param>
private void AddAttachments(Multipart multipart, IEnumerable<MailAttachment> attachments)
{
if (attachments == null) return;
return mail;
}
foreach (var attachment in attachments)
{
if (attachment?.FileData == null || string.IsNullOrWhiteSpace(attachment.FileName))
continue;
var mimeType = string.IsNullOrWhiteSpace(attachment.MediaType)
? MimeTypes.GetMimeType(attachment.FileName)
: attachment.MediaType;
var part = new MimePart(mimeType)
{
Content = new MimeContent(new MemoryStream(attachment.FileData)),
ContentDisposition = new ContentDisposition(ContentDisposition.Attachment),
ContentTransferEncoding = ContentEncoding.Base64,
FileName = attachment.FileName
};
multipart.Add(part);
}
}
#endregion
}
}
......@@ -369,7 +369,7 @@ namespace CoreCms.Net.Web.Admin.Controllers
IsBodyHtml = true
};
await _emailSender.SendEmailAsync(message);
await _emailSender.SendWithMailKitAsync(message);
}
#endregion
......
......@@ -10,8 +10,7 @@
"Port": 465,
"Username": "erpservice@geekbuy.com",
"Password": "co69W7xEZ6qjBo01",
"FromAddress": "erpservice@geekbuy.com",
"DisplayName": "My Application"
"FromAddress": "erpservice@geekbuy.com"
},
//定时任务管理面板的账户密码
"HangFire": {
......
......@@ -5,6 +5,7 @@ using CoreCms.Net.Utility.Helper;
using Microsoft.AspNetCore.Mvc;
using System;
using System.Collections.Generic;
using System.Net;
using System.Threading.Tasks;
namespace CoreCms.Net.Web.WebApi.Controllers
......@@ -75,7 +76,11 @@ namespace CoreCms.Net.Web.WebApi.Controllers
IsBodyHtml = true
};
await _emailSender.SendEmailAsync(message);
// 在应用启动代码前添加
System.Net.ServicePointManager.SecurityProtocol =
SecurityProtocolType.Tls12 | SecurityProtocolType.Tls13;
await _emailSender.SendWithMailKitAsync(message);
return jm;
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment