经常看到有很多朋友在网上找发送邮件的代码,也经常有很多朋友问各种邮件发送中出的问题,
因此把自己写的一个邮件发送类整理了一下,贴出来,给大家参考借鉴。虽然这个代码不算完整,
但贵在简练实用,便于阅读和修改扩展,里面还包含了写日志的简练方法,非常实用。
特色:
代码简洁短小,逻辑清晰,便于大家拓展修改。
支持群发,一封邮件指定多名接收人。
使用独立线程,不影响主程序运行。采用异步发送,最大程度降低系统消耗。
使用队列,对意外发送不成功邮件,可以重复发送,提高成功率。
支持回调,可以了解发送失败的详细错误信息,便于调试和修正。
支持错误日志,实时记录各种异常状况。
/*** 王海斌 2016-05-22 qq:443053303 版权所有,请勿传播 *** * * 邮件发送类 * * 特色: * 1:独立线程,不影响主程序运行 * 2:使用队列,对意外发送不成功邮件,可以重复发送,提高成功率 * 3:支持回调,可以了解发送失败的详细错误信息,便于调试和修正 * 4:错误日志,实时记录各种异常状况 * 5:支持群发 * 6:代码简洁,逻辑清晰,便于大家拓展修改 * * 注意: * 1:该代码从项目中删减而来,一些安全、校验、特别处理等等业务代码,都过滤了,大家自己添加 * 2:邮件回调方法里,可以探视多种发送邮件服务返回的消息,这里没写那么多,大家自己完善 * 3:只开放日志方法、添加待发送邮件、发送邮件三个方法。 * 4:日志方法和邮件发送方法,都可以独立使用 * 5:邮件队列采用List<>模拟,简洁实用,发邮件足够 * 6:该代码删减后未做测试,如有错漏,请与我联系 * *** 王海斌 2016-05-22 qq:443053303 版权所有,请勿传播 ***/ using System; using System.Collections.Generic; using System.ComponentModel; using System.Net; using System.Net.Mail; using System.Text; using System.Web; using System.Linq; using System.Threading; namespace Common { public class MyEmail { public string Subject { get; set; } public string Body { get; set; } public string Tos { get; set; } public string From { get; set; } public int id { get; set; } public int Status { get; set; }//0:未发送,1:发送中,2:已发送,3:发送失败 public int SendCnt { get; set; } public MyEmail() { Status = 0; SendCnt = 0; } } public static class EMailHelper { #region 邮件静态属性 private static string SmtpServer = "outlook.office365.com"; //邮件服务器 private static string From = "testSend@hotmail.com"; //默认发件箱 private static string Name = "Hotmail Tester"; //默认发件箱名字 private static string Password = "Test123"; //默认发件箱密码 private static int SmtpServerPort = 587; //邮件服务器端口 private static int Timeout = 60000; //超时时间 private static List<MyEmail> Mails = new List<MyEmail>(); //待发邮件列表 private static bool IsRun = false; //发邮件线程是否启动 #endregion #region 日志方法 private static object LockObj = new object(); private static string logPath = ConfigurationManager.AppSettings["LogPath"]; public static bool WriteLog(string str) { lock (LockObj) { string fileName = System.DateTime.Now.ToLongDateString() + ".log"; try { if (!Directory.Exists(logPath)) { Directory.CreateDirectory(logPath); } string nowTime = System.DateTime.Now.ToString(); StreamWriter sw = new StreamWriter(logPath + fileName, true); sw.Write("【" + nowTime + "】" + str + " "); sw.Flush(); sw.Close(); return true; } catch { return false; } } } #endregion public static void Add(VivaEmail mail) { mail.id = Mails.Count < 1 ? 1 : Mails.Max(p => p.id) + 1; Mails.Add(mail); if (!IsRun) { ThreadPool.QueueUserWorkItem(new WaitCallback(StartSend)); IsRun = true; } } public static string Send(email) { var errMsg = ""; try { var client = new SmtpClient(SmtpServer, SmtpServerPort); client.UseDefaultCredentials = true; client.Credentials = new NetworkCredential(From, Password); client.DeliveryMethod = SmtpDeliveryMethod.Network; client.EnableSsl = true; client.Timeout = Timeout; var mailMessage = new MailMessage(); mailMessage.From = new MailAddress(From, Name, Encoding.UTF8); foreach (var to in email.tos)//抄送和密送人写法类似,如有需要,自己添加 { if (!string.IsNullOrWhiteSpace(to)) { mailMessage.To.Add(to); } } mailMessage.Subject = email.Subject; mailMessage.SubjectEncoding = Encoding.UTF8; mailMessage.Body = email.Body; mailMessage.IsBodyHtml = true; mailMessage.BodyEncoding = Encoding.UTF8; mailMessage.IsBodyHtml = true; mailMessage.Priority = MailPriority.High; object userState = mailMessage; client.SendCompleted += new SendCompletedEventHandler(SendCompletedCallback); client.SendAsync(mailMessage, email); } catch (Exception ex) { return ex.Message; } return errMsg; } private static void SendCompletedCallback(object sender, AsyncCompletedEventArgs e) { var mail = e.UserState as MyEmail; if (e.Error != null) { Log.WriteLog("邮件【" + mail.To + ":" + mail.Subject + "】发送失败!" + " " + e.Error.Message); mail.Status = 3; } else { Mails.Remove(mail); } } private static void StartSend(object obj) { while (true) { var mail = Mails.FirstOrDefault(p => p.Status == 0 && p.SendCnt < 3); if (mail != null) { if (!string.IsNullOrWhiteSpace(mail.Tos)) { Send(mail); mail.SendCnt += 1; mail.Status = 1; } else { mail.Status = 3; } } Thread.Sleep(500); } } } }