/// <summary>
/// ** 描述:邮件发送
/// ** 创始时间:2020/9/18
/// ** 修改时间:-
/// ** 作者:child
/// </summary>
public class MailKitSmtp
{
/// <summary>
/// 邮件服务器Host
/// </summary>
public string Host { get; set; }
/// <summary>
/// 邮件服务器Port
/// </summary>
public int Port { get; set; }
/// <summary>
/// 邮件服务器是否是ssl
/// </summary>
public bool UseSsl { get; set; } = true;
/// <summary>
/// 发送邮件的账号友善名称
/// </summary>
public string UserName { get; set; }
/// <summary>
/// 发送邮件的账号地址
/// </summary>
public string UserAddress { get; set; }
/// <summary>
/// 发现邮件所需的账号密码
/// </summary>
public string Password { get; set; }
/// <summary>
/// 构造函数
/// </summary>
/// <param name="host"></param>
/// <param name="username">邮件账号</param>
/// <param name="password">密码</param>
public MailKitSmtp(string host, int port, string username, string userAddress, string password)
{
this.Host = host;
this.Port = port;
this.UserAddress = userAddress;
this.UserName = username;
this.Password = password;
}
/// <summary>
/// 构造函数
/// </summary>
/// <param name="host"></param>
/// <param name="username">邮件账号</param>
/// <param name="password">密码</param>
public MailKitSmtp(string host, string username, string userAddress, string password, bool isSSL)
{
this.Host = host;
this.UserAddress = userAddress;
this.UserName = username;
this.Password = password;
this.UseSsl = isSSL;
}
/// <summary>
/// 发送电子邮件,默认发送方为<see cref="UserAddress"/>
/// </summary>
/// <param name="subject">邮件主题</param>
/// <param name="content">邮件内容主题</param>
/// <param name="toAddress">接收方信息</param>
/// <param name="textFormat">内容主题模式,默认TextFormat.Text</param>
/// <param name="attachments">附件</param>
/// <param name="dispose">是否自动释放附件所用Stream</param>
/// <returns></returns>
public async Task<bool> SendEMailAsync(string subject, string content, IEnumerable<MailboxAddress> toAddress, TextFormat textFormat = TextFormat.Text, IEnumerable<AttachmentInfo> attachments = null, bool dispose = true, bool isProxy = false)
{
if (!isProxy)
{
return await SendEMailAsync(subject, content, new MailboxAddress[] { new MailboxAddress(UserName, UserAddress) }, toAddress, textFormat, attachments, dispose).ConfigureAwait(false);
}
else
{
return await SendEMailAsyncProxy(subject, content, new MailboxAddress[] { new MailboxAddress(UserName, UserAddress) }, toAddress, textFormat, attachments, dispose).ConfigureAwait(false);
}
}
/// <summary>
/// 发送电子邮件
/// </summary>
/// <param name="subject">邮件主题</param>
/// <param name="content">邮件内容主题</param>
/// <param name="fromAddress">发送方信息</param>
/// <param name="toAddress">接收方信息</param>
/// <param name="textFormat">内容主题模式,默认TextFormat.Text</param>
/// <param name="attachments">附件</param>
/// <param name="dispose">是否自动释放附件所用Stream</param>
/// <returns></returns>
public async Task<bool> SendEMailAsync(string subject, string content, MailboxAddress fromAddress, IEnumerable<MailboxAddress> toAddress, TextFormat textFormat = TextFormat.Text, IEnumerable<AttachmentInfo> attachments = null, bool dispose = true, bool isProxy = false)
{
if (!isProxy)
{
return await SendEMailAsync(subject, content, new MailboxAddress[] { fromAddress }, toAddress, textFormat, attachments, dispose).ConfigureAwait(false);
}
else
{
return await SendEMailAsyncProxy(subject, content, new MailboxAddress[] { new MailboxAddress(UserName, UserAddress) }, toAddress, textFormat, attachments, dispose).ConfigureAwait(false);
}
}
/// <summary>
/// 发送电子邮件
/// </summary>
/// <param name="subject">邮件主题</param>
/// <param name="content">邮件内容主题</param>
/// <param name="fromAddress">发送方信息</param>
/// <param name="toAddress">接收方信息</param>
/// <param name="textFormat">内容主题模式,默认TextFormat.Text</param>
/// <param name="attachments">附件</param>
/// <param name="dispose">是否自动释放附件所用Stream</param>
/// <returns></returns>
private async Task<bool> SendEMailAsyncProxy(string subject, string content, IEnumerable<MailboxAddress> fromAddress, IEnumerable<MailboxAddress> toAddress, TextFormat textFormat = TextFormat.Text, IEnumerable<AttachmentInfo> attachments = null, bool dispose = true)
{
try
{
var message = new MimeMessage();
message.From.AddRange(fromAddress);
message.To.AddRange(toAddress);
message.Subject = subject;
var body = new TextPart(textFormat)
{
Text = content
};
MimeEntity entity = body;
if (attachments != null)
{
var mult = new Multipart("mixed")
{
body
};
foreach (var att in attachments)
{
if (att.Stream != null)
{
var attachment = string.IsNullOrWhiteSpace(att.ContentType) ? new MimePart() : new MimePart(att.ContentType);
attachment.Content = new MimeContent(att.Stream);
attachment.ContentDisposition = new ContentDisposition(ContentDisposition.Attachment);
attachment.ContentTransferEncoding = att.ContentTransferEncoding;
attachment.FileName = ConvertHeaderToBase64(att.FileName, Encoding.UTF8);//解决附件中文名问题
mult.Add(attachment);
}
}
entity = mult;
}
message.Body = entity;
message.Date = DateTime.Now;
var emailProxyHost = ConfigExtensions.GetAppSettings("emailProxyHost");
var emailProxyPort = ConfigExtensions.GetAppSettings("emailProxyPort").ToInt(0);
var emailProxyType = ConfigExtensions.GetAppSettings("emailProxyType").ToInt(1);
var TokenSource = new CancellationTokenSource(ConfigExtensions.GetAppSettings("emailProxyTime").ToInt(0));//30s超时
Socket socket = null;
if (emailProxyType == 1)
{
var httpProxy = new Socks5Client(emailProxyHost, emailProxyPort);
socket = await httpProxy.ConnectAsync(Host, Port, TokenSource.Token);
}
else
{
var httpProxy = new HttpProxyClient(emailProxyHost, emailProxyPort);
socket = await httpProxy.ConnectAsync(Host, Port, TokenSource.Token);
}
using var client = new SmtpClient();
//创建连接
await client.ConnectAsync(socket, Host, Port).ConfigureAwait(false);
await client.AuthenticateAsync(UserAddress, Password).ConfigureAwait(false);
await client.SendAsync(message).ConfigureAwait(false);
await client.DisconnectAsync(true).ConfigureAwait(false);
if (dispose && attachments != null)
{
foreach (var att in attachments)
{
att.Dispose();
}
}
return true;
}
catch (Exception ex)
{
NLogHelp.ErrorLog("MailKitSmtp邮件发送代理错误", ex);
return false;
}
}
/// <summary>
/// 发送电子邮件
/// </summary>
/// <param name="subject">邮件主题</param>
/// <param name="content">邮件内容主题</param>
/// <param name="fromAddress">发送方信息</param>
/// <param name="toAddress">接收方信息</param>
/// <param name="textFormat">内容主题模式,默认TextFormat.Text</param>
/// <param name="attachments">附件</param>
/// <param name="dispose">是否自动释放附件所用Stream</param>
/// <returns></returns>
private async Task<bool> SendEMailAsync(string subject, string content, IEnumerable<MailboxAddress> fromAddress, IEnumerable<MailboxAddress> toAddress, TextFormat textFormat = TextFormat.Text, IEnumerable<AttachmentInfo> attachments = null, bool dispose = true)
{
try
{
var message = new MimeMessage();
message.From.AddRange(fromAddress);
message.To.AddRange(toAddress);
message.Subject = subject;
var body = new TextPart(textFormat)
{
Text = content
};
MimeEntity entity = body;
if (attachments != null)
{
var mult = new Multipart("mixed")
{
body
};
foreach (var att in attachments)
{
if (att.Stream != null)
{
var attachment = string.IsNullOrWhiteSpace(att.ContentType) ? new MimePart() : new MimePart(att.ContentType);
attachment.Content = new MimeContent(att.Stream);
attachment.ContentDisposition = new ContentDisposition(ContentDisposition.Attachment);
attachment.ContentTransferEncoding = att.ContentTransferEncoding;
attachment.FileName = ConvertHeaderToBase64(att.FileName, Encoding.UTF8);//解决附件中文名问题
mult.Add(attachment);
}
}
entity = mult;
}
message.Body = entity;
message.Date = DateTime.Now;
using var client = new SmtpClient();
//创建连接
client.SslProtocols = SslProtocols.Ssl3 | SslProtocols.Tls | SslProtocols.Tls11 | SslProtocols.Tls12 | SslProtocols.Tls13;
client.CheckCertificateRevocation = false;
client.ServerCertificateValidationCallback = (s, c, h, e) => true;
await client.ConnectAsync(Host, Port, SecureSocketOptions.Auto).ConfigureAwait(false);
await client.AuthenticateAsync(UserAddress, Password).ConfigureAwait(false);
await client.SendAsync(message).ConfigureAwait(false);
await client.DisconnectAsync(true).ConfigureAwait(false);
if (dispose && attachments != null)
{
foreach (var att in attachments)
{
att.Dispose();
}
}
return true;
}
catch (Exception ex)
{
NLogHelp.ErrorLog("MailKitSmtp邮件发送错误", ex);
return false;
}
}
private static string ConvertToBase64(string inputStr, Encoding encoding)
{
return Convert.ToBase64String(encoding.GetBytes(inputStr));
}
private static string ConvertHeaderToBase64(string inputStr, Encoding encoding)
{//https://www.cnblogs.com/qingspace/p/3732677.html
var encode = !string.IsNullOrEmpty(inputStr) && inputStr.Any(c => c > 127);
if (encode)
{
return "=?" + encoding.WebName + "?B?" + ConvertToBase64(inputStr, encoding) + "?=";
}
return inputStr;
}
}
/// <summary>
/// 附件信息
/// </summary>
public class AttachmentInfo : IDisposable
{
/// <summary>
/// 附件类型,比如application/pdf
/// </summary>
public string ContentType { get; set; }
/// <summary>
/// 文件名称
/// </summary>
public string FileName { get; set; }
/// <summary>
/// 文件传输编码方式,默认ContentEncoding.Default
/// </summary>
public ContentEncoding ContentTransferEncoding { get; set; } = ContentEncoding.Default;
/// <summary>
/// 文件数组
/// </summary>
public byte[] Data { get; set; }
private Stream stream;
/// <summary>
/// 文件数据流,获取数据时优先采用此部分
/// </summary>
public Stream Stream
{
get
{
if (this.stream == null && this.Data != null)
{
stream = new MemoryStream(this.Data);
}
return this.stream;
}
set { this.stream = value; }
}
/// <summary>
/// 释放Stream
/// </summary>
public void Dispose()
{
if (this.stream != null)
{
this.stream.Dispose();
}
}
}
c#---发送邮件(代理)
最新推荐文章于 2024-06-12 08:01:19 发布