Files
zszq-trs/Framework/YLErp.MailKit/MailSender.cs

328 lines
13 KiB
C#
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using MailKit.Net.Smtp;
using MailKit.Security;
using MimeKit;
using Newtonsoft.Json;
using System.IO.Compression;
namespace YLErp.MailKit
{
public static class MailSender
{
/// <summary>
/// 发送邮件
/// </summary>
public static void Send(SmtpConfig smtpConfig, MailSendingOption option, Action<string, string> log = null)
{
if (smtpConfig == null)
{
throw new ArgumentNullException(nameof(smtpConfig));
}
if (string.IsNullOrWhiteSpace(smtpConfig.Server))
{
throw new ArgumentException("未设置SMTP Server");
}
if (string.IsNullOrWhiteSpace(smtpConfig.UserName))
{
throw new ArgumentException("未设置SMTP UserName");
}
if (option == null)
{
throw new ArgumentNullException(nameof(option));
}
if (option.MailTo == null || option.MailTo.Length < 1)
{
throw new ArgumentException("未设置收件人");
}
if (string.IsNullOrWhiteSpace(option.Subject))
{
throw new ArgumentException("未设置邮件主题");
}
var from = option.From.TrimToNull() ?? smtpConfig.From.TrimToNull() ?? smtpConfig.UserName.TrimToNull() ?? throw new ArgumentNullException("未设置发件人");
var separator = new[] { ',', ';', '', '' };
var message = new MimeMessage();
message.From.Add(new MailboxAddress(string.Empty, from));
foreach (var mailTo in option.MailTo)
{
message.To.Add(new MailboxAddress(string.Empty, mailTo));
}
message.Subject = option.Subject;
if (!string.IsNullOrWhiteSpace(option.CC))
{
var addrArr = option.CC.Split(separator, StringSplitOptions.RemoveEmptyEntries)
.Select(n => new MailboxAddress(string.Empty, n.Trim()));
message.Cc.AddRange(addrArr);
}
if (!string.IsNullOrWhiteSpace(option.BCC))
{
var addrArr = option.BCC.Split(separator, StringSplitOptions.RemoveEmptyEntries)
.Select(n => new MailboxAddress(string.Empty, n.Trim()));
message.Bcc.AddRange(addrArr);
}
if (option.AdditionalHeaders != null)
{
}
if (!string.IsNullOrWhiteSpace(option.HeaderEncoding))
{
message.Headers.Add(HeaderId.Encoding, option.HeaderEncoding.Trim());
}
if (!string.IsNullOrWhiteSpace(option.Priority) &&
Enum.TryParse(option.Priority.Trim(), out MessagePriority prri))
{
message.Priority = prri;
}
if (!string.IsNullOrWhiteSpace(option.ReplyTo))
{
message.ReplyTo.Add(new MailboxAddress(string.Empty, option.ReplyTo.Trim()));
}
var builder = new BodyBuilder();
if (option.IsBodyHtml)
{
builder.HtmlBody = option.Body;
}
else
{
builder.TextBody = option.Body;
}
if (option.FilesToAttach != null && option.FilesToAttach.Any(n => !string.IsNullOrWhiteSpace(n)))
{
var attaches = option.FilesToAttach.Where(n => !string.IsNullOrWhiteSpace(n)).ToArray();
for (var i = 0; i < attaches.Length; i++)
{
var attach = attaches[i];
var attachPath = attach;
if (attach.Contains("/")&& OperatingSystem.IsWindows())
{
attachPath = attach.Replace("/", "\\");
}
var attachments = builder.Attachments.Add(attachPath);
if (log != null)
{
var name = "邮件附件" + (i + 1);
log.Invoke(name, "源地址:" + attach);
log.Invoke(name, "解析地址:" + attachPath);
log.Invoke(name, "文件名称:" + attachments.ContentDisposition.FileName);
}
}
if (smtpConfig.ZipAttach)
{
using var zipStream = new MemoryStream();
using (var archive = new ZipArchive(zipStream, ZipArchiveMode.Update))
{
foreach (var attach in attaches)
{
var fileInfo = new FileInfo(attach);
var entry = archive.CreateEntry(fileInfo.Name);
using var stream = entry.Open();
var bytes = File.ReadAllBytes(fileInfo.FullName);
stream.Write(bytes, 0, bytes.Length);
}
}
builder.Attachments.Add(option.Subject + ".zip", zipStream.ToArray());
log?.Invoke("邮件附件ZIP", "Subject:" + option.Subject);
}
}
message.Body = builder.ToMessageBody();
if (!string.IsNullOrWhiteSpace(option.ContentEncoding))
{
message.Body.Headers.Add(HeaderId.Encoding, option.ContentEncoding.Trim());
}
//以outlook名义发送邮件,不会被当作垃圾邮件
message.Headers.Add("X-Priority", "3");
message.Headers.Add("X-MSMail-Priority", "Normal");
message.Headers.Add("X-Mailer", "Microsoft Outlook Express 6.00.2900.2869");
message.Headers.Add("X-MimeOLE", "Produced By Microsoft MimeOLE V6.00.2900.2869");
message.Headers.Add("ReturnReceipt", "1");
if (smtpConfig.Receipt)
{
message.Headers.Add("Disposition-Notification-To", from);
}
using var client = new SmtpClient();
// For demo-purposes, accept all SSL certificates (in case the server supports STARTTLS)
client.ServerCertificateValidationCallback = (s, c, h, e) => true;
var userName = smtpConfig.UserName;
var secureSocketOptions = SecureSocketOptions.None;
//当做exchange邮件服务器处理
if (smtpConfig.Port == 587)
{
client.SslProtocols = System.Security.Authentication.SslProtocols.Tls;
if (smtpConfig.EnableSsl)
{
secureSocketOptions = SecureSocketOptions.StartTls;
}
var index = userName.IndexOf('@');
if (index > 0)
{
userName = userName.Substring(0, index);
}
}
else if (smtpConfig.EnableSsl)
{
secureSocketOptions = SecureSocketOptions.SslOnConnect;
}
client.Connect(smtpConfig.Server, smtpConfig.Port, secureSocketOptions);
// Note: since we don't have an OAuth2 token, disable the XOAUTH2 authentication mechanism.
client.AuthenticationMechanisms.Remove("XOAUTH2");
if (!string.IsNullOrWhiteSpace(smtpConfig.Password))
{
client.Authenticate(userName, smtpConfig.Password);
}
client.Send(message);
client.Disconnect(true);
}
public static string SendApi(MailSendingOption option, Action<string, string> log = null)
{
if (option == null)
{
throw new ArgumentNullException(nameof(option));
}
if (option.MailTo == null || option.MailTo.Length < 1)
{
throw new ArgumentException("未设置收件人");
}
if (string.IsNullOrWhiteSpace(option.Subject))
{
throw new ArgumentException("未设置邮件主题");
}
var baseUrl = Environment.GetEnvironmentVariable("BondOmsInterface_BaseUrl");
var emailPath = "/general/email/send";
if (string.IsNullOrEmpty(baseUrl))
{
throw new ArgumentException("未设置邮件接口地址");
}
// 创建一个HttpClient实例
using (var httpClient = new HttpClient())
{
httpClient.Timeout = TimeSpan.FromMinutes(3); // 根据需要调整
var content = new MultipartFormDataContent();
// 添加收件人
content.Add(new StringContent(string.Join(",", option.MailTo)), "to");
// 添加主题
content.Add(new StringContent(option.Subject), "subject");
// 添加邮件正文
content.Add(new StringContent(option.Body), "text");
// 添加邮件正文
content.Add(new StringContent(option.IsBodyHtml.ToString()), "isHtmlContent");
if (!string.IsNullOrWhiteSpace(option.CC))
{
content.Add(new StringContent(string.Join(",", option.CC)), "cc");
}
if (!string.IsNullOrWhiteSpace(option.BCC))
{
content.Add(new StringContent(string.Join(",", option.BCC)), "bcc");
}
// 将文件添加到请求体中
if (option.FilesToAttach != null && option.FilesToAttach.Any(n => !string.IsNullOrWhiteSpace(n)))
{
var attaches = option.FilesToAttach.Where(n => !string.IsNullOrWhiteSpace(n)).ToArray();
for (var i = 0; i < attaches.Length; i++)
{
var attach = attaches[i];
var attachPath = attach;
if (attach.Contains("/") && OperatingSystem.IsWindows())
{
attachPath = attach.Replace("/", "\\");
}
var fileInfo= new FileInfo(attachPath);
// 添加附件
var attachmentContent = new ByteArrayContent(File.ReadAllBytes(attachPath));
content.Add(attachmentContent, "files", fileInfo.Name);
if (log != null)
{
var name = "邮件附件" + (i + 1);
log.Invoke(name, "源地址:" + attach);
log.Invoke(name, "解析地址:" + attachPath);
log.Invoke(name, "文件名称:" + fileInfo.Name);
}
}
}
if (log != null) {
log.Invoke("邮件发送接口", "BaseUrl:" + baseUrl);
log.Invoke("邮件发送接口", "EmailPath:" + emailPath);
}
// 发送POST请求
var response = httpClient.PostAsync($"{baseUrl}{emailPath}", content).Result;
// 检查响应状态码
if (response.IsSuccessStatusCode)
{
// 解析响应内容并返回结果
var result = response.Content.ReadAsStringAsync().Result;
if (log != null)
{
log.Invoke("邮件发送接口", "响应内容:" + result);
}
if (string.IsNullOrEmpty(result))
{
throw new ArgumentException("发送邮件失败");
}
var trsRespone = JsonConvert.DeserializeObject<TrsRespone>(result);
if (!trsRespone.success)
{
throw new ArgumentException("发送邮件失败:"+ trsRespone.message);
}
return trsRespone.data.ToString();
}
else
{
if (log != null)
{
log.Invoke("邮件发送接口", "响应状态码:" + response.StatusCode);
log.Invoke("邮件发送接口", "响应内容:" + response.Content.ReadAsStringAsync().Result);
}
// 处理错误情况
}
}
return "";
}
/// <summary>
///
/// </summary>
static string TrimToNull(this string str)
{
return string.IsNullOrWhiteSpace(str) ? null : str.Trim();
}
}
}