新建項目,引用MailKit和MimeKit NuGet包
using CommonTool.MailKit; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace ProjectDemo.ConsoleApp { class Program { static void Main(string[] args) { try { var ccList = new List<string>(); ccList.Add("*****@qq.com"); var recipients = new List<string>(); recipients.Add("*****@qq.com"); var mailBodyEntity = new MailBodyEntity() { Body = "這是一個測試郵件body內容<a href='http://www.baidu.com'>123</a>", Cc = ccList, //MailBodyType = "html", MailFiles = new List<MailFile>() { new MailFile { MailFilePath = @"D:\文檔\File\20180807165402.png", MailFileSubType = "png", MailFileType = "image" }, new MailFile { MailFilePath = @"D:\文檔\File\TIM截圖20180807165402.png", MailFileSubType = "png", MailFileType = "image" } }, Recipients = recipients, Sender = "郵件的發件人", SenderAddress = "111111@qq.com", Subject = "測試郵件是否可以發送的標題", }; var sendServerConfiguration = new SendServerConfigurationEntity() { SenderPassword = "123456", SmtpPort = 465, IsSsl = true, MailEncoding = "utf-8", SenderAccount = "11111@qq.com", SmtpHost = "smtp.qq.com", }; var result=SeedMailHelper.SendMail(mailBodyEntity, sendServerConfiguration); ReceiveEmailHelper.ReceiveEmail(); ReceiveEmailHelper.DownloadBodyParts(); Console.WriteLine("成功!"); Console.ReadLine(); } catch (Exception ex) { Console.WriteLine(ex.ToString()); } } } }
發送郵件
using MailKit; using MailKit.Net.Smtp; using MailKit.Security; using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Text; using System.Threading.Tasks; namespace CommonTool.MailKit { /// <summary> /// 發送郵件 /// </summary> public static class SeedMailHelper { /// <summary> /// 發送郵件 /// </summary> /// <param name="mailBodyEntity">郵件基礎信息</param> /// <param name="sendServerConfiguration">發件人基礎信息</param> public static SendResultEntity SendMail(MailBodyEntity mailBodyEntity, SendServerConfigurationEntity sendServerConfiguration) { if (mailBodyEntity == null) { throw new ArgumentNullException(); } if (sendServerConfiguration == null) { throw new ArgumentNullException(); } var sendResultEntity = new SendResultEntity(); using (var client = new SmtpClient(new ProtocolLogger(MailMessage.CreateMailLog()))) { client.ServerCertificateValidationCallback = (s, c, h, e) => true; Connection(mailBodyEntity, sendServerConfiguration, client, sendResultEntity); if (sendResultEntity.ResultStatus == false) { return sendResultEntity; } SmtpClientBaseMessage(client); // Note: since we don't have an OAuth2 token, disable // the XOAUTH2 authentication mechanism. client.AuthenticationMechanisms.Remove("XOAUTH2"); Authenticate(mailBodyEntity, sendServerConfiguration, client, sendResultEntity); if (sendResultEntity.ResultStatus == false) { return sendResultEntity; } Send(mailBodyEntity, sendServerConfiguration, client, sendResultEntity); if (sendResultEntity.ResultStatus == false) { return sendResultEntity; } client.Disconnect(true); } return sendResultEntity; } /// <summary> /// 連接服務器 /// </summary> /// <param name="mailBodyEntity">郵件內容</param> /// <param name="sendServerConfiguration">發送配置</param> /// <param name="client">客戶端對象</param> /// <param name="sendResultEntity">發送結果</param> public static void Connection(MailBodyEntity mailBodyEntity, SendServerConfigurationEntity sendServerConfiguration, SmtpClient client, SendResultEntity sendResultEntity) { try { client.Connect(sendServerConfiguration.SmtpHost, sendServerConfiguration.SmtpPort); } catch (SmtpCommandException ex) { sendResultEntity.ResultInformation = $"嘗試連接時出錯:{0}" + ex.Message; sendResultEntity.ResultStatus = false; } catch (SmtpProtocolException ex) { sendResultEntity.ResultInformation = $"嘗試連接時的協議錯誤:{0}" + ex.Message; sendResultEntity.ResultStatus = false; } catch (Exception ex) { sendResultEntity.ResultInformation = $"服務器連接錯誤:{0}" + ex.Message; sendResultEntity.ResultStatus = false; } } /// <summary> /// 賬戶認證 /// </summary> /// <param name="mailBodyEntity">郵件內容</param> /// <param name="sendServerConfiguration">發送配置</param> /// <param name="client">客戶端對象</param> /// <param name="sendResultEntity">發送結果</param> public static void Authenticate(MailBodyEntity mailBodyEntity, SendServerConfigurationEntity sendServerConfiguration, SmtpClient client, SendResultEntity sendResultEntity) { try { client.Authenticate(sendServerConfiguration.SenderAccount, sendServerConfiguration.SenderPassword); } catch (AuthenticationException ex) { sendResultEntity.ResultInformation = $"無效的用戶名或密碼:{0}" + ex.Message; sendResultEntity.ResultStatus = false; } catch (SmtpCommandException ex) { sendResultEntity.ResultInformation = $"嘗試驗證錯誤:{0}" + ex.Message; sendResultEntity.ResultStatus = false; } catch (SmtpProtocolException ex) { sendResultEntity.ResultInformation = $"嘗試驗證時的協議錯誤:{0}" + ex.Message; sendResultEntity.ResultStatus = false; } catch (Exception ex) { sendResultEntity.ResultInformation = $"賬戶認證錯誤:{0}" + ex.Message; sendResultEntity.ResultStatus = false; } } /// <summary> /// 發送郵件 /// </summary> /// <param name="mailBodyEntity">郵件內容</param> /// <param name="sendServerConfiguration">發送配置</param> /// <param name="client">客戶端對象</param> /// <param name="sendResultEntity">發送結果</param> public static void Send(MailBodyEntity mailBodyEntity, SendServerConfigurationEntity sendServerConfiguration, SmtpClient client, SendResultEntity sendResultEntity) { try { client.Send(MailMessage.AssemblyMailMessage(mailBodyEntity)); } catch (SmtpCommandException ex) { switch (ex.ErrorCode) { case SmtpErrorCode.RecipientNotAccepted: sendResultEntity.ResultInformation = $"收件人未被接受:{ex.Message}"; break; case SmtpErrorCode.SenderNotAccepted: sendResultEntity.ResultInformation = $"發件人未被接受:{ex.Message}"; break; case SmtpErrorCode.MessageNotAccepted: sendResultEntity.ResultInformation = $"消息未被接受:{ex.Message}"; break; } sendResultEntity.ResultStatus = false; } catch (SmtpProtocolException ex) { sendResultEntity.ResultInformation = $"發送消息時的協議錯誤:{ex.Message}"; sendResultEntity.ResultStatus = false; } catch (Exception ex) { sendResultEntity.ResultInformation = $"郵件接收失敗:{ex.Message}"; sendResultEntity.ResultStatus = false; } } /// <summary> /// 獲取SMTP基礎信息 /// </summary> /// <param name="client">客戶端對象</param> /// <returns></returns> public static MailServerInformation SmtpClientBaseMessage(SmtpClient client) { var mailServerInformation = new MailServerInformation { Authentication = client.Capabilities.HasFlag(SmtpCapabilities.Authentication), BinaryMime = client.Capabilities.HasFlag(SmtpCapabilities.BinaryMime), Dsn = client.Capabilities.HasFlag(SmtpCapabilities.Dsn), EightBitMime = client.Capabilities.HasFlag(SmtpCapabilities.EightBitMime), Size = client.MaxSize }; return mailServerInformation; } } }
基礎類
using MimeKit; using MimeKit.Text; using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Text; using System.Threading.Tasks; namespace CommonTool.MailKit { /// <summary> /// 郵件信息 /// </summary> public static class MailMessage { /// <summary> /// 組裝郵件文本/附件郵件信息 /// </summary> /// <param name="mailBodyEntity">郵件消息實體</param> /// <returns></returns> public static MimeMessage AssemblyMailMessage(MailBodyEntity mailBodyEntity) { if (mailBodyEntity == null) { throw new ArgumentNullException(nameof(mailBodyEntity)); } var message = new MimeMessage(); //設置郵件基本信息 SetMailBaseMessage(message, mailBodyEntity); var multipart = new Multipart("mixed"); //插入文本消息 if (!string.IsNullOrEmpty(mailBodyEntity.Body)) { var alternative = new MultipartAlternative { AssemblyMailTextMessage(mailBodyEntity.Body, mailBodyEntity.MailBodyType) }; multipart.Add(alternative); } //插入附件 foreach (var mailFile in mailBodyEntity.MailFiles) { if (mailFile.MailFilePath != null && File.Exists(mailFile.MailFilePath)) { var mimePart = AssemblyMailAttachmentMessage(mailFile.MailFileType, mailFile.MailFileSubType, mailFile.MailFilePath); multipart.Add(mimePart); } } //組合郵件內容 message.Body = multipart; return message; } /// <summary> /// 設置郵件基礎信息 /// </summary> /// <param name="minMessag"></param> /// <param name="mailBodyEntity"></param> /// <returns></returns> public static MimeMessage SetMailBaseMessage(MimeMessage minMessag, MailBodyEntity mailBodyEntity) { if (minMessag == null) { throw new ArgumentNullException(); } if (mailBodyEntity == null) { throw new ArgumentNullException(); } //插入發件人 minMessag.From.Add(new MailboxAddress(mailBodyEntity.Sender, mailBodyEntity.SenderAddress)); //插入收件人 if(mailBodyEntity.Recipients.Any()) { foreach (var recipients in mailBodyEntity.Recipients) { minMessag.To.Add(new MailboxAddress(recipients)); } } //插入抄送人 if (mailBodyEntity.Cc!=null&&mailBodyEntity.Cc.Any()) { foreach (var cC in mailBodyEntity.Cc) { minMessag.Cc.Add(new MailboxAddress(cC)); } } //插入密送人 if (mailBodyEntity.Bcc != null && mailBodyEntity.Bcc.Any()) { foreach (var bcc in mailBodyEntity.Bcc) { minMessag.Bcc.Add(new MailboxAddress(bcc)); } } //插入主題 minMessag.Subject = mailBodyEntity.Subject; return minMessag; } /// <summary> /// 組裝郵件文本信息 /// </summary> /// <param name="mailBody">郵件內容</param> /// <param name="textPartType">郵件類型(plain,html,rtf,xml)</param> /// <returns></returns> public static TextPart AssemblyMailTextMessage(string mailBody, TextFormat textPartType) { if (string.IsNullOrEmpty(mailBody)) { throw new ArgumentNullException(); } //var textBody = new TextPart(textPartType) //{ // Text = mailBody, //}; //處理查看源文件有亂碼問題 var textBody = new TextPart(textPartType); textBody.SetText(Encoding.Default, mailBody); return textBody; } /// <summary> /// 組裝郵件附件信息 /// </summary> /// <param name="fileAttachmentType">附件類型(image,application)</param> /// <param name="fileAttachmentSubType">附件子類型 </param> /// <param name="fileAttachmentPath">附件路徑</param> /// <returns></returns> public static MimePart AssemblyMailAttachmentMessage(string fileAttachmentType, string fileAttachmentSubType, string fileAttachmentPath) { if (string.IsNullOrEmpty(fileAttachmentSubType)) { throw new ArgumentNullException(); } if (string.IsNullOrEmpty(fileAttachmentType)) { throw new ArgumentNullException(); } if (string.IsNullOrEmpty(fileAttachmentPath)) { throw new ArgumentNullException(); } var fileName = Path.GetFileName(fileAttachmentPath); var attachment = new MimePart(fileAttachmentType, fileAttachmentSubType) { Content = new MimeContent(File.OpenRead(fileAttachmentPath)), ContentDisposition = new ContentDisposition(ContentDisposition.Attachment), ContentTransferEncoding = ContentEncoding.Base64, //FileName = fileName, }; //qq郵箱附件文件名中文亂碼問題 //var charset = "GB18030"; attachment.ContentType.Parameters.Add(Encoding.Default, "name", fileName); attachment.ContentDisposition.Parameters.Add(Encoding.Default, "filename", fileName); //處理文件名過長 foreach (var param in attachment.ContentDisposition.Parameters) param.EncodingMethod = ParameterEncodingMethod.Rfc2047; foreach (var param in attachment.ContentType.Parameters) param.EncodingMethod = ParameterEncodingMethod.Rfc2047; return attachment; } /// <summary> /// 創建郵件日志文件 /// </summary> /// <returns></returns> public static string CreateMailLog() { var logPath = AppDomain.CurrentDomain.BaseDirectory + "/DocumentLog/" + Guid.NewGuid() + ".txt"; if (File.Exists(logPath)) return logPath; var fs = File.Create(logPath); fs.Close(); return logPath; } } }
實體
using MimeKit.Text; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace CommonTool.MailKit { /// <summary> /// 郵件內容實體 /// </summary> public class MailBodyEntity { ///// <summary> ///// 郵件文本內容 ///// </summary> //public string MailTextBody { get; set; } /// <summary> /// 郵件內容類型 /// </summary> public TextFormat MailBodyType { get; set; } = TextFormat.Html; /// <summary> /// 郵件附件集合 /// </summary> public List<MailFile> MailFiles { get; set; } /// <summary> /// 收件人 /// </summary> public List<string> Recipients { get; set; } /// <summary> /// 抄送 /// </summary> public List<string> Cc { get; set; } /// <summary> /// 密送 /// </summary> public List<string> Bcc { get; set; } /// <summary> /// 發件人 /// </summary> public string Sender { get; set; } /// <summary> /// 發件人地址 /// </summary> public string SenderAddress { get; set; } /// <summary> /// 郵件主題 /// </summary> public string Subject { get; set; } /// <summary> /// 郵件內容 /// </summary> public string Body { get; set; } } public class MailFile { /// <summary> /// 郵件附件文件類型 例如:圖片 MailFileType="image" /// </summary> public string MailFileType { get; set; } /// <summary> /// 郵件附件文件子類型 例如:圖片 MailFileSubType="png" /// </summary> public string MailFileSubType { get; set; } /// <summary> /// 郵件附件文件路徑 例如:圖片 MailFilePath=@"C:\Files\123.png" /// </summary> public string MailFilePath { get; set; } } /// <summary> /// 郵件服務器基礎信息 /// </summary> public class MailServerInformation { /// <summary> /// SMTP服務器支持SASL機制類型 /// </summary> public bool Authentication { get; set; } /// <summary> /// SMTP服務器對消息的大小 /// </summary> public uint Size { get; set; } /// <summary> /// SMTP服務器支持傳遞狀態通知 /// </summary> public bool Dsn { get; set; } /// <summary> /// SMTP服務器支持Content-Transfer-Encoding /// </summary> public bool EightBitMime { get; set; } /// <summary> /// SMTP服務器支持Content-Transfer-Encoding /// </summary> public bool BinaryMime { get; set; } /// <summary> /// SMTP服務器在消息頭中支持UTF-8 /// </summary> public string UTF8 { get; set; } } /// <summary> /// 郵件發送結果 /// </summary> public class SendResultEntity { /// <summary> /// 結果信息 /// </summary> public string ResultInformation { get; set; } = "發送成功!"; /// <summary> /// 結果狀態 /// </summary> public bool ResultStatus { get; set; } = true; } /// <summary> /// 郵件發送服務器配置 /// </summary> public class SendServerConfigurationEntity { /// <summary> /// 郵箱SMTP服務器地址 /// </summary> public string SmtpHost { get; set; } /// <summary> /// 郵箱SMTP服務器端口 /// </summary> public int SmtpPort { get; set; } /// <summary> /// 是否啟用IsSsl /// </summary> public bool IsSsl { get; set; } /// <summary> /// 郵件編碼 /// </summary> public string MailEncoding { get; set; } /// <summary> /// 郵箱賬號 /// </summary> public string SenderAccount { get; set; } /// <summary> /// 郵箱密碼 /// </summary> public string SenderPassword { get; set; } } }
接收
using MailKit; using MailKit.Net.Imap; using MailKit.Search; using MailKit.Security; using MimeKit; using System; using System.Collections.Generic; using System.Configuration; using System.Globalization; using System.IO; using System.Linq; using System.Text; using System.Threading.Tasks; namespace CommonTool.MailKit { /// <summary> /// 跟投郵件服務API /// </summary> public static class ReceiveEmailHelper { /// <summary> /// 設置發件人信息 /// </summary> /// <returns></returns> public static SendServerConfigurationEntity SetSendMessage() { var sendServerConfiguration = new SendServerConfigurationEntity { SmtpHost = ConfigurationManager.AppSettings["SmtpServer"], SmtpPort = int.Parse(ConfigurationManager.AppSettings["SmtpPort"]), IsSsl = Convert.ToBoolean(ConfigurationManager.AppSettings["IsSsl"]), MailEncoding = ConfigurationManager.AppSettings["MailEncoding"], SenderAccount = ConfigurationManager.AppSettings["SenderAccount"], SenderPassword = ConfigurationManager.AppSettings["SenderPassword"] }; return sendServerConfiguration; } /// <summary> /// 接收郵件 /// </summary> public static void ReceiveEmail() { var sendServerConfiguration = SetSendMessage(); if (sendServerConfiguration == null) { throw new ArgumentNullException(); } using (var client = new ImapClient(new ProtocolLogger(MailMessage.CreateMailLog()))) { client.Connect(sendServerConfiguration.SmtpHost, sendServerConfiguration.SmtpPort, SecureSocketOptions.SslOnConnect); client.Authenticate(sendServerConfiguration.SenderAccount, sendServerConfiguration.SenderPassword); client.Inbox.Open(FolderAccess.ReadOnly); var uids = client.Inbox.Search(SearchQuery.All); foreach (var uid in uids) { var message = client.Inbox.GetMessage(uid); message.WriteTo($"{uid}.eml"); } client.Disconnect(true); } } /// <summary> /// 下載郵件內容 /// </summary> public static void DownloadBodyParts() { var sendServerConfiguration = SetSendMessage(); using (var client = new ImapClient()) { client.Connect(sendServerConfiguration.SmtpHost, sendServerConfiguration.SmtpPort, SecureSocketOptions.SslOnConnect); client.Authenticate(sendServerConfiguration.SenderAccount, sendServerConfiguration.SenderPassword); client.Inbox.Open(FolderAccess.ReadOnly); // 搜索Subject標題包含“MimeKit”或“MailKit”的郵件 var query = SearchQuery.SubjectContains("MimeKit").Or(SearchQuery.SubjectContains("MailKit")); var uids = client.Inbox.Search(query); // 獲取搜索結果的摘要信息(我們需要UID和BODYSTRUCTURE每條消息,以便我們可以提取文本正文和附件) var items = client.Inbox.Fetch(uids, MessageSummaryItems.UniqueId | MessageSummaryItems.BodyStructure); foreach (var item in items) { // 確定一個目錄來保存內容 var directory = Path.Combine(AppDomain.CurrentDomain.BaseDirectory + "/MailBody", item.UniqueId.ToString()); Directory.CreateDirectory(directory); // IMessageSummary.TextBody是一個便利的屬性,可以為我們找到“文本/純文本”的正文部分 var bodyPart = item.TextBody; // 下載'text / plain'正文部分 var body = (TextPart)client.Inbox.GetBodyPart(item.UniqueId, bodyPart); // TextPart.Text是一個便利的屬性,它解碼內容並將結果轉換為我們的字符串 var text = body.Text; File.WriteAllText(Path.Combine(directory, "body.txt"), text); // 現在遍歷所有附件並將其保存到磁盤 foreach (var attachment in item.Attachments) { // 像我們對內容所做的那樣下載附件 var entity = client.Inbox.GetBodyPart(item.UniqueId, attachment); // 附件可以是message / rfc822部件或常規MIME部件 var messagePart = entity as MessagePart; if (messagePart != null) { var rfc822 = messagePart; var path = Path.Combine(directory, attachment.PartSpecifier + ".eml"); rfc822.Message.WriteTo(path); } else { var part = (MimePart)entity; // 注意:這可能是空的,但大多數會指定一個文件名 var fileName = part.FileName; var path = Path.Combine(directory, fileName); // decode and save the content to a file using (var stream = File.Create(path)) part.Content.DecodeTo(stream); } } } client.Disconnect(true); } } } }
https://blog.csdn.net/sd7o95o/article/details/79493045