经常看到有很多朋友在网上找发送邮件的代码,也经常有很多朋友问各种邮件发送中出的问题,
因此把自己写的一个邮件发送类整理了一下,贴出来,给大家参考借鉴。虽然这个代码不算完整,
但贵在简练实用,便于阅读和修改扩展,里面还包含了写日志的简练方法,非常实用。
特色:
代码简洁短小,逻辑清晰,便于大家拓展修改。
支持群发,一封邮件指定多名接收人。
使用独立线程,不影响主程序运行。采用异步发送,最大程度降低系统消耗。
使用队列,对意外发送不成功邮件,可以重复发送,提高成功率。
支持回调,可以了解发送失败的详细错误信息,便于调试和修正。
支持错误日志,实时记录各种异常状况。
/*** 王海斌 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);
}
}
}
}