MailKit开源地址:https://github.com/jstedfast/MailKit
using System; using System.IO; using MailKit.Net.Smtp; using MimeKit; using MimeKit.Text; namespace commom { public class EmailHelper { //Nuget包管理添加Mailkit /// <summary> /// 服务邮箱 /// </summary> private string _STEPNAME = "smtp.qq.com"; /// <summary> /// 服务邮箱端口 /// </summary> private int _STEPPORT = 587; /// <summary> /// 发送方邮箱 /// </summary> private string _USEREMAIL; /// <summary> /// 发送方邮箱Smtp授权码 /// </summary> private string _PASSWORD; /// <summary> /// 发送方邮箱归属人,昵称 /// </summary> private string _EMAILBLONGER; private string email; private string emailBlonger; private string smtp; /// <summary> /// 邮箱配置 /// </summary> /// <param name="email"></param> /// <param name="smtp"></param> public EmailHelper(string email, string smtp) { this._USEREMAIL = email; this._PASSWORD = smtp; } public EmailHelper(string email, string emailBlonger, string smtp) { this._USEREMAIL = email; this._PASSWORD = smtp; this._EMAILBLONGER = emailBlonger; } /// <summary> /// 邮箱发送类 /// </summary> /// <param name="toEmaill">发送方邮箱</param> /// <param name="toEmailBlonger">发送方名称</param> /// <param name="subject">邮件标题</param> /// <param name="text">发送的文字内容</param> /// <param name="html">发送的html内容</param> /// <param name="path">发送的附件,找不到的就自动过滤</param> /// <returns></returns> public string SendEmail(string toEmaill, string toEmailBlonger, string subject, string text, string html, string path) { try { MimeMessage message = new MimeMessage(); //发送方 message.From.Add(new MailboxAddress(this._EMAILBLONGER, this._USEREMAIL)); //接受方 message.To.Add(new MailboxAddress(toEmailBlonger, toEmaill)); //标题 message.Subject = subject; //创建附件 var multipart = new Multipart("mixed"); //文字内容 if (!string.IsNullOrEmpty(text)) { var plain = new TextPart(TextFormat.Plain) { Text = text }; multipart.Add(plain); } //html内容 if (!string.IsNullOrEmpty(html)) { var Html = new TextPart(TextFormat.Html) { Text = html }; multipart.Add(Html); } if (!string.IsNullOrEmpty(path)) { var pathList = path.Split(';'); foreach (var p in pathList) { try { if (!string.IsNullOrEmpty(p.Trim())) { var attimg = new MimePart() {//"image", "png"方法里带参数的话 ContentObject = new ContentObject(File.OpenRead(p), ContentEncoding.Default), ContentDisposition = new ContentDisposition(ContentDisposition.Attachment), ContentTransferEncoding = ContentEncoding.Base64, FileName = Path.GetFileName(path) }; multipart.Add(attimg); } } catch (FileNotFoundException ex) { //找不到文件就不提交附件了 } } } //赋值邮件内容 message.Body = multipart; //开始发送 using (var client = new SmtpClient()) { client.Connect(this._STEPNAME, this._STEPPORT, false); client.Authenticate(this._USEREMAIL, this._PASSWORD); client.Send(message); client.Disconnect(true); } return "邮件发送成功"; } catch (Exception) { return "邮箱发送失败"; } } /// <summary> /// 邮箱发送类,不用输入用户昵称的 /// </summary> /// <param name="toEmaill">发送方邮箱</param> /// <param name="toEmailBlonger">发送方名称</param> /// <param name="subject">邮件标题</param> /// <param name="text">发送的文字内容</param> /// <param name="html">发送的html内容</param> /// <param name="path">发送的附件,多附件用;隔开</param> /// <returns></returns> public void SendEmail(string toEmaill, string subject, string text, string html, string path) { try { MimeMessage message = new MimeMessage(); //发送方 message.From.Add(new MailboxAddress(this._USEREMAIL)); //接受方 message.To.Add(new MailboxAddress(toEmaill)); //标题 message.Subject = subject; //创建附件 var multipart = new Multipart("mixed"); //文字内容 if (!string.IsNullOrEmpty(text)) { var plain = new TextPart(TextFormat.Plain) { Text = text }; multipart.Add(plain); } //html内容 if (!string.IsNullOrEmpty(html)) { var Html = new TextPart(TextFormat.Html) { Text = html }; multipart.Add(Html); } if (!string.IsNullOrEmpty(path)) {//修改为多附件, var pathList = path.Split(';'); foreach (var p in pathList) { try { if (!string.IsNullOrEmpty(p.Trim())) { var attimg = new MimePart() {//"image", "png"方法里带参数的话 ContentObject = new ContentObject(File.OpenRead(p), ContentEncoding.Default), ContentDisposition = new ContentDisposition(ContentDisposition.Attachment), ContentTransferEncoding = ContentEncoding.Base64, FileName = Path.GetFileName(path) }; multipart.Add(attimg); } } catch (FileNotFoundException ex) { //找不到文件就不提交附件了 } } } //赋值邮件内容 message.Body = multipart; //开始发送 using (var client = new SmtpClient()) { client.Connect(this._STEPNAME, this._STEPPORT, false); client.Authenticate(this._USEREMAIL, this._PASSWORD); client.Send(message); client.Disconnect(true); } // return "邮件发送成功"; } catch (Exception ex) { // return "邮箱发送失败"; } } } /// <summary> /// 测试调用方法 /// </summary> public class Test{ private email=new EmailHelper("发送的邮箱","Smtp授权码"); public void SendEmail() { email.SendEmail("对方的邮箱", "对方邮箱名称也可以是邮箱","标题", "内容", "<b>这是html标记的文本</b>", "附加地址") } } }
附件问题处理
List<FileStream> list = new List<FileStream>(attachments.Count()); foreach (var path in attachments) { if (!File.Exists(path)) { throw new FileNotFoundException("文件未找到", path); } var fileName = Path.GetFileName(path); var fileType = MimeTypes.GetMimeType(path); var contentTypeArr = fileType.Split('/'); var contentType = new ContentType(contentTypeArr[0], contentTypeArr[1]); MimePart attachment = null; var fs = new FileStream(path, FileMode.Open); list.Add(fs); attachment = new MimePart(contentType) { Content = new MimeContent(fs), ContentDisposition = new ContentDisposition(ContentDisposition.Attachment), ContentTransferEncoding = ContentEncoding.Base64, }; var charset = "GB18030"; attachment.ContentType.Parameters.Add(charset, "name", fileName); attachment.ContentDisposition.Parameters.Add(charset, "filename", fileName); foreach (var param in attachment.ContentDisposition.Parameters) param.EncodingMethod = ParameterEncodingMethod.Rfc2047; foreach (var param in attachment.ContentType.Parameters) param.EncodingMethod = ParameterEncodingMethod.Rfc2047; collection.Add(attachment); } await SendEmail(body, subject, isHtml, to, cc, collection); foreach (var fs in list) { fs.Dispose();//手动释放 }
解决文件名不能使用中文
原因是字符编码的问题
MimePart attachment = null; var fs = new FileStream(path, FileMode.Open); list.Add(fs); attachment = new MimePart(contentType) { Content = new MimeContent(fs), ContentDisposition = new ContentDisposition(ContentDisposition.Attachment), ContentTransferEncoding = ContentEncoding.Base64, }; var charset = "GB18030"; attachment.ContentType.Parameters.Add(charset, "name", fileName); attachment.ContentDisposition.Parameters.Add(charset, "filename", fileName);
解决附件名字中文乱码主要依靠最后三行代码,将name和filename的字符集指定为GB18030即可。
解决文件名不能超过41字符
var attachment = bodyBuilder.Attachments.Add (.....); foreach (var param in attachment.ContentDisposition.Parameters) param.EncodingMethod = ParameterEncodingMethod.Rfc2047; foreach (var param in attachment.ContentType.Parameters) param.EncodingMethod = ParameterEncodingMethod.Rfc2047;
别忘了释放文件流
记录2
string mailAccount = "abc@126.com"; string mainPassword = "ABVCDEFGDSDF"; var client = new MailKit.Net.Smtp.SmtpClient(); client.Connect("smtp.126.com", 25, SecureSocketOptions.None); client.AuthenticationMechanisms.Remove("XOAUTH2"); client.Authenticate(mailAccount, mainPassword); var message = new MimeMessage(); message.From.Add(new MailboxAddress("testNameFrom", "abc@126.com")); message.To.Add(new MailboxAddress("testNameTo", "abcd@163.com")); message.Subject = "测试发送邮件的标题"; var html = new TextPart("html") { Text = @"p您好,张三:br p附件里是详细内容,请查收!br p-- 管家王小明br" }; var alternative = new Multipart("alternative"); alternative.Add(html); string pngPath = @"C:UserswjxDesktoplogo.png"; var attachmentPng = new MimePart("image", "png") { Content = new MimeContent(File.OpenRead(pngPath), ContentEncoding.Default), ContentDisposition = new ContentDisposition(ContentDisposition.Attachment), ContentTransferEncoding = ContentEncoding.Base64, FileName = Path.GetFileName(pngPath) }; string zipPath = @"C:UserswjxDesktop中国百度的logo.zip"; var attachmentZip = new MimePart("application", "zip") { Content = new MimeContent(File.OpenRead(zipPath), ContentEncoding.Default), ContentDisposition = new ContentDisposition(ContentDisposition.Attachment), ContentTransferEncoding = ContentEncoding.Base64, FileName = Path.GetFileName(zipPath) }; var multipart = new Multipart("mixed"); multipart.Add(alternative); multipart.Add(attachmentPng); multipart.Add(attachmentZip); message.Body = multipart; client.Send(message); client.Disconnect(true);