335 lines
9.2 KiB
C#
335 lines
9.2 KiB
C#
using IRaCIS.Core.Domain.Share;
|
|
using MailKit;
|
|
using MailKit.Security;
|
|
using MimeKit;
|
|
using Org.BouncyCastle.Tls;
|
|
|
|
|
|
namespace IRaCIS.Core.Application.Helper;
|
|
|
|
public static class SendEmailHelper
|
|
{
|
|
|
|
public static async Task<string> SendEmailAsync(MimeMessage messageToSend, SystemEmailSendConfig _systemEmailConfig, EventHandler<MessageSentEventArgs>? messageSentSuccess = null)
|
|
{
|
|
string result = string.Empty;
|
|
result = messageToSend.MessageId;
|
|
|
|
//没有收件人 那么不发送
|
|
if (messageToSend.To.Count == 0)
|
|
{
|
|
return string.Empty;
|
|
}
|
|
|
|
try
|
|
{
|
|
using (var smtp = new MailKit.Net.Smtp.SmtpClient())
|
|
{
|
|
if (messageSentSuccess != null)
|
|
{
|
|
smtp.MessageSent += messageSentSuccess;
|
|
}
|
|
|
|
|
|
smtp.ServerCertificateValidationCallback = (s, c, h, e) => true;
|
|
|
|
//await smtp.ConnectAsync("smtp.qq.com", 465, SecureSocketOptions.SslOnConnect);
|
|
|
|
//await smtp.AuthenticateAsync("zhou941003@qq.com", "sqfhlpfdvnexbcab");
|
|
|
|
await smtp.ConnectAsync(_systemEmailConfig.Host, _systemEmailConfig.Port, SecureSocketOptions.Auto);
|
|
|
|
await smtp.AuthenticateAsync(_systemEmailConfig.FromEmail, _systemEmailConfig.AuthorizationCode);
|
|
|
|
|
|
await smtp.SendAsync(messageToSend);
|
|
|
|
await smtp.DisconnectAsync(true);
|
|
|
|
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
|
|
//---邮件发送失败,您进行的操作未能成功,请检查邮箱或联系维护人员
|
|
throw new Exception(I18n.T("SendEmail_SendFail"), new Exception(ex.Message));
|
|
}
|
|
|
|
return result;
|
|
|
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// 发送项目邮件
|
|
/// </summary>
|
|
/// <param name="messageToSend"></param>
|
|
/// <param name="trial"></param>
|
|
/// <param name="messageSentSuccess"></param>
|
|
/// <returns></returns>
|
|
/// <exception cref="Exception"></exception>
|
|
public static async Task<string> SendTrialEmailAsync(MimeMessage messageToSend, Trial trial, EventHandler<MessageSentEventArgs>? messageSentSuccess = null)
|
|
{
|
|
|
|
// 项目的需要重设 发件地址与邮件地址
|
|
var fromAddress = messageToSend.From.Mailboxes.FirstOrDefault();
|
|
if (fromAddress != null)
|
|
{
|
|
messageToSend.From.Clear();
|
|
messageToSend.From.Add(new MailboxAddress(trial.EmailFromName, trial.EmailFromEmail));
|
|
}
|
|
|
|
|
|
string result = string.Empty;
|
|
result = messageToSend.MessageId;
|
|
|
|
|
|
//没有收件人 那么不发送
|
|
if (messageToSend.To.Count == 0)
|
|
{
|
|
return string.Empty;
|
|
}
|
|
|
|
// 替换邮件标题
|
|
if (!string.IsNullOrEmpty(messageToSend.Subject))
|
|
{
|
|
foreach (var item in trial.TrialObjectNameList)
|
|
{
|
|
// 把标题里的占位符替换成真实名称
|
|
messageToSend.Subject = messageToSend.Subject.Replace(item.Name, item.TrialName);
|
|
}
|
|
}
|
|
|
|
// 构建替换字典
|
|
var replacements = new Dictionary<string, string>();
|
|
foreach (var item in trial.TrialObjectNameList)
|
|
{
|
|
replacements[item.Name] = item.TrialName;
|
|
}
|
|
|
|
// 安全替换 HTML
|
|
ReplaceHtmlContent(messageToSend.Body, replacements);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
try
|
|
{
|
|
using (var smtp = new MailKit.Net.Smtp.SmtpClient())
|
|
{
|
|
if (messageSentSuccess != null)
|
|
{
|
|
smtp.MessageSent += messageSentSuccess;
|
|
}
|
|
|
|
|
|
smtp.ServerCertificateValidationCallback = (s, c, h, e) => true;
|
|
|
|
//await smtp.ConnectAsync("smtp.qq.com", 465, SecureSocketOptions.SslOnConnect);
|
|
|
|
//await smtp.AuthenticateAsync("zhou941003@qq.com", "sqfhlpfdvnexbcab");
|
|
|
|
|
|
//await smtp.ConnectAsync(_systemEmailConfig.Host, _systemEmailConfig.Port, SecureSocketOptions.Auto);
|
|
|
|
//await smtp.AuthenticateAsync(_systemEmailConfig.FromEmail, _systemEmailConfig.AuthorizationCode);
|
|
|
|
|
|
await smtp.ConnectAsync(trial.EmailSMTPServerAddress, trial.EmailSMTPServerPort, SecureSocketOptions.Auto);
|
|
|
|
await smtp.AuthenticateAsync(trial.EmailFromEmail, trial.EmailAuthorizationCode);
|
|
|
|
|
|
await smtp.SendAsync(messageToSend);
|
|
|
|
await smtp.DisconnectAsync(true);
|
|
|
|
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
|
|
//---邮件发送失败,您进行的操作未能成功,请检查邮箱或联系维护人员
|
|
throw new Exception(I18n.T("SendEmail_SendFail"), new Exception(ex.Message));
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
|
|
|
|
// 遍历邮件体,找到 HTML 部分并替换
|
|
public static void ReplaceHtmlContent(MimeEntity entity, Dictionary<string, string> replacements)
|
|
{
|
|
if (entity is Multipart multipart)
|
|
{
|
|
foreach (var part in multipart)
|
|
{
|
|
ReplaceHtmlContent(part, replacements);
|
|
}
|
|
}
|
|
else if (entity is TextPart textPart && textPart.IsHtml)
|
|
{
|
|
// 只有这里才是真正的 HTML
|
|
foreach (var kv in replacements)
|
|
{
|
|
textPart.Text = textPart.Text.Replace(kv.Key, kv.Value);
|
|
}
|
|
}
|
|
}
|
|
public static async Task<bool> TestEmailConfigAsync(SystemEmailSendConfig _systemEmailConfig)
|
|
{
|
|
using (var cts = new CancellationTokenSource(TimeSpan.FromSeconds(5)))
|
|
{
|
|
using (var client = new MailKit.Net.Smtp.SmtpClient())
|
|
{
|
|
|
|
await client.ConnectAsync(_systemEmailConfig.Host, _systemEmailConfig.Port, SecureSocketOptions.Auto, cts.Token);
|
|
|
|
await client.AuthenticateAsync(_systemEmailConfig.FromEmail, _systemEmailConfig.AuthorizationCode, cts.Token);
|
|
|
|
await client.DisconnectAsync(true);
|
|
}
|
|
}
|
|
|
|
|
|
return true;
|
|
}
|
|
|
|
public static async Task SendEmailAsync(SMTPEmailConfig sMTPEmailConfig, Trial? trial, EventHandler<MessageSentEventArgs>? messageSentSuccess = null)
|
|
{
|
|
var messageToSend = new MimeMessage();
|
|
|
|
//主题
|
|
messageToSend.Subject = sMTPEmailConfig.TopicDescription;
|
|
|
|
//发件地址
|
|
messageToSend.From.Add(sMTPEmailConfig.FromEmailAddress);
|
|
|
|
//收件地址
|
|
|
|
if (sMTPEmailConfig.ToMailAddressList.Count == 0)
|
|
{
|
|
return;
|
|
//---没有收件人
|
|
//throw new ArgumentException(I18n.T("SendEmail_NoRecipient"));
|
|
}
|
|
else
|
|
{
|
|
foreach (var item in sMTPEmailConfig.ToMailAddressList)
|
|
{
|
|
messageToSend.To.Add(item);
|
|
}
|
|
//抄送
|
|
foreach (var copyToMailAddress in sMTPEmailConfig.CopyToMailAddressList)
|
|
{
|
|
messageToSend.Cc.Add(copyToMailAddress);
|
|
}
|
|
}
|
|
|
|
var builder = new BodyBuilder();
|
|
|
|
//html body
|
|
|
|
builder.HtmlBody = sMTPEmailConfig.HtmlBodyStr;
|
|
|
|
|
|
//附件
|
|
|
|
foreach (var item in sMTPEmailConfig.EmailAttachMentConfigList)
|
|
{
|
|
//builder.Attachments.Add(item.FileName, item.FileData);
|
|
|
|
var attachment = builder.Attachments.Add(item.FileName, item.FileStream);
|
|
|
|
//解决附件名过长 奇怪的名字
|
|
foreach (var param in attachment.ContentDisposition.Parameters)
|
|
param.EncodingMethod = ParameterEncodingMethod.Rfc2047;
|
|
foreach (var param in attachment.ContentType.Parameters)
|
|
param.EncodingMethod = ParameterEncodingMethod.Rfc2047;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
messageToSend.Body = builder.ToMessageBody();
|
|
|
|
using (var smtp = new MailKit.Net.Smtp.SmtpClient())
|
|
{
|
|
if (messageSentSuccess != null)
|
|
{
|
|
smtp.MessageSent += messageSentSuccess;
|
|
}
|
|
|
|
|
|
smtp.ServerCertificateValidationCallback = (s, c, h, e) => true;
|
|
|
|
await smtp.ConnectAsync(sMTPEmailConfig.Host, sMTPEmailConfig.Port, SecureSocketOptions.Auto);
|
|
|
|
await smtp.AuthenticateAsync(trial.EmailFromEmail, trial.EmailAuthorizationCode);
|
|
|
|
await smtp.SendAsync(messageToSend);
|
|
|
|
await smtp.DisconnectAsync(true);
|
|
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public class SMTPEmailConfig
|
|
{
|
|
public int Port { get; set; }
|
|
|
|
public string Host { get; set; }
|
|
|
|
|
|
public string UserName { get; set; }
|
|
|
|
public string AuthorizationCode { get; set; }
|
|
|
|
|
|
//邮件HtmlBody
|
|
|
|
public string HtmlBodyStr { get; set; } = string.Empty;
|
|
|
|
|
|
//发
|
|
public MailboxAddress FromEmailAddress { get; set; }
|
|
|
|
//收
|
|
public List<MailboxAddress> ToMailAddressList { get; set; } = new List<MailboxAddress>();
|
|
|
|
//抄送
|
|
public List<MailboxAddress> CopyToMailAddressList { get; set; } = new List<MailboxAddress>();
|
|
|
|
//邮件主题
|
|
public string TopicDescription { get; set; } = string.Empty;
|
|
|
|
//邮件附件
|
|
public List<EmailAttachMentConfig> EmailAttachMentConfigList { get; set; } = new List<EmailAttachMentConfig>() { };
|
|
|
|
}
|
|
|
|
|
|
public class EmailAttachMentConfig
|
|
{
|
|
public string FileName { get; set; }
|
|
|
|
public Stream FileStream { get; set; }
|
|
|
|
|
|
public byte[] FileData { get; set; }
|
|
}
|