基于MailKit的发送邮件辅助类
·
MailKit是Net下免费开源的邮箱类库,其github地址为:https://github.com/jstedfast/MailKit
一般情况下,MailKit都工作的很好,但可能是姿势不对,在发送附件时,只要附件名为中文名,接收方接收到的附件名必然是乱码或者tcmime.xx.xx.xx.bin 这种完全不明觉厉的东东(具体会乱码还是显示tcmime跟文件名长度有关),作为对于邮件协议不明觉厉,仅仅只是想要发封邮件的使用方,对此完全措手无策,幸好万能的互联网已经有了这个问题的解决方案,所以此处对发送邮件及附件这个过程进行了封装并予以记录
using MailKit.Net.Smtp;
using MimeKit;
using MimeKit.Text;
/// <summary>
/// 基于MailKit的邮件帮助类
/// </summary>
public static class EMailHelper
{
/// <summary>
/// 邮件服务器Host
/// </summary>
public static string Host { get; set; }
/// <summary>
/// 邮件服务器Port
/// </summary>
public static int Port { get; set; }
/// <summary>
/// 邮件服务器是否是ssl
/// </summary>
public static bool UseSsl { get; set; }
/// <summary>
/// 发送邮件的账号友善名称
/// </summary>
public static string UserName { get; set; }
/// <summary>
/// 发送邮件的账号地址
/// </summary>
public static string UserAddress { get; set; }
/// <summary>
/// 发现邮件所需的账号密码
/// </summary>
public static string Password { get; set; }
/// <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 static async Task SendEMailAsync(string subject, string content, IEnumerable<MailboxAddress> toAddress, TextFormat textFormat = TextFormat.Text, IEnumerable<AttachmentInfo> attachments = null, bool dispose = true)
{
await SendEMailAsync(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 static async Task SendEMailAsync(string subject, string content, MailboxAddress fromAddress, IEnumerable<MailboxAddress> toAddress, TextFormat textFormat = TextFormat.Text, IEnumerable<AttachmentInfo> attachments = null, bool dispose = true)
{
await SendEMailAsync(subject, content, new MailboxAddress[] { fromAddress }, 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 static async Task SendEMailAsync(string subject, string content, IEnumerable<MailboxAddress> fromAddress, IEnumerable<MailboxAddress> toAddress, TextFormat textFormat = TextFormat.Text, IEnumerable<AttachmentInfo> attachments = null, bool dispose = true)
{
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())
{
//创建连接
await client.ConnectAsync(Host, Port, UseSsl).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();
}
}
}
}
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();
}
}
}
对于附件,此处定义了 AttachmentInfo 来作为附件的载体类,其支持两种方式进行附件上传:byte[]以及Stream,具体的使用例子如下
EMailHelper.Host = "smtp.exmail.qq.com";
EMailHelper.Port = 465;
EMailHelper.UseSsl = true;
EMailHelper.UserName = "你要展示的发送方名称";
EMailHelper.Password = "你的邮箱密码";
EMailHelper.UserAddress = "你的邮箱地址";
var subject = "测试多个附件邮件";
var content = "Just a test!";
var attachs = new List<AttachmentInfo>();
//从指定文件夹内读取要发送的附件
foreach (var file in Directory.GetFiles("EMailAttach"))
{
var att = new AttachmentInfo
{
FileName = Path.GetFileName(file),
//Data = File.ReadAllBytes(file)
Stream = File.OpenRead(file),//Data和Stream两种方式任意用一种即可
ContentTransferEncoding = ContentEncoding.Base64
};
attachs.Add(att);
}
await EMailHelper.SendEMailAsync(subject, content, new MailboxAddress[] {
new MailboxAddress("接收方邮箱地址")
}, attachments: attachs);
最后,如果要支持抄送和密送,那么只需要修改下上面的封装代码,支持Cc以及Bcc即可
更多推荐
已为社区贡献5条内容
所有评论(0)