菜鳥D在工作時,用戶提到要給系統添加一個定時發送郵件的功能,這個菜鳥D沒有寫過,只是知道基本原理是怎麼回事。根據我的想法:新開一個線程,線程中添加一個計時器,由計時器來完成定時的任務。至於發送郵件,寫個方法就OK了,畢竟網上封裝好的發送郵件功能都爛大街了。但是在實際工作的時候卻發生一些意外,比如線程什麼時候開啓?隨時用隨時開啓還是一啓動就開啓,毋庸置疑是後者嚒。有了思路一切都好辦了,在網上搜索一部分資料整理如下:
自動發送郵件,通常使用的幾種方法:
1.使用winform做UI時,可以在程序的load事件中,或者其他控件驅動事件中執行郵件發送任務。定時功能可以通過Windows的計劃任務,設置指定時間執行winform程序,執行完成之後自動關閉即可。
2.使用sqlserver數據庫發送郵件,使用sqlserver實現發送郵件的存儲過程,指定定時執行。(此方法未嘗試,具體過程下文詳細轉述)
3.使用web做UI時,可以在Global.asax全局文件裏做一些編程。事件Application_Start。自動定時執行可以交給計時器timer來執行。
接下來介紹一些需要注意的地方:
1.可以封裝一個郵件發送的操作類,便於移植及日後的使用。
2.在全局文件裏做定時執行的任務,個人建議使用線程和計時器,保證主線程的正常運行。(System.Timers.Timer; System.Threading.Timer;System.Web.UI.Timer 共有三種計時器,由於自動發送郵件在服務器端執行,此例中個人建議使用第一種,其他情況具體分析,可參見)
下面詳述方法2:
通過Sqlserver發送郵件:
一.啓用Database Mail XPs功能。查看Database Mail XPs功能是否打開,從返回結果來看,value爲0說明沒有打開,注意SQL Mail XPs是SQL Server早期版本提供的發送郵件功能,而現在用的是Database Mail XPs來實現發送郵件。
select name, value, description, is_dynamic, is_advanced from sys.configurations where name like '%mail%' /*name value description is_dynamic is_advanced
SQL Mail XPs 0 Enable or disable SQL Mail XPs 1 1
Database Mail XPs 0 Enable or disable Database Mail XPs 1 1*/ 啓動Database Mail XPs功能: sp_configure 'show advanced options',1 go reconfigure go sp_configure 'Database Mail XPs',1 go reconfigure go
二、配置數據庫郵件
1、點開管理目錄,右鍵“數據庫郵件”,選擇“配置數據庫郵件”選項;
2、彈出“數據庫郵件配置嚮導”,單擊下一步:
3、選擇“通過執行以下任務來安裝數據庫郵件”選項,單擊下一步:
4、輸入“配置文件名”,這裏我輸入的是:db_mail,然後單擊右側的“添加”按鈕:
5、輸入賬戶名、說明,按照你的實際情況,輸入:電子郵件地址、服務器名稱,用戶名和密碼,必須要輸入正確,否則就不能正確發送郵件。
6、填寫完成後,單擊下一步:
7、在“公共”選項打上勾,單擊下一步:
8、可以修改“配置系統參數”,比如賬戶重試次數,禁止的附件文件擴展名,單擊下一步:
9、單擊完成按鈕,顯示配置成功。
三、發送郵件
DECLARE @email_conetent VARCHAR(8000); --存放郵件正文
--計算有多少條記錄
SELECT @email_conetent = '你的數據庫,共有:'+ cast(COUNT(*) as varchar) + '個表!' FROM sys.tables; --發送郵件
EXEC msdb.dbo.sp_send_dbmail
@profile_name = 'db_mail', --配置文件名稱
@recipients = '[email protected]', --收件email地址
@subject = '你好', --郵件主題
@body = @email_conetent --郵件正文內容
四、查看數據庫郵件日誌。右鍵“數據庫郵件”,選擇“查看數據庫郵件日誌”:
下面簡述方法3:
protected void Application_Start(object sender, EventArgs e) //Global.asax { Timer t = new Timer(60000);//設計時間間隔,如果一個小時執行一次就改爲3600000 ,這裏一分鐘調用一次 t.Elapsed += new ElapsedEventHandler(t_Elapsed); t.AutoReset = true; //默認爲true,可省略 t.Enabled = true; } private void t_Elapsed(object sender, ElapsedEventArgs e) { //根據具體需要,添加具體功能 }
附:個人整理的郵件發送類
public class EmailHelper { #region 字段屬性 /// <summary> /// 發件箱服務器 /// </summary> public string SendServer { get; set; } /// <summary> /// 收件人郵箱,多人以“;”分割 /// </summary> public string ToMail { get; set; } /// <summary> /// 發件人郵箱 /// </summary> public string FromMail { get; set; } /// <summary> /// 發件人密碼 /// </summary> public string Pwd { get; set; } /// <summary> /// 郵件標題 /// </summary> public string Subject { get; set; } /// <summary> /// 郵件內容 /// </summary> public string EmailBody { get; set; } /// <summary> /// 發送郵件的端口,默認是25 /// </summary> private string prot = "25"; /// <summary> /// 是否使用socket加密傳輸 /// </summary> public bool SslEnable { get; set; } /// <summary> /// 是否對發件人郵箱進行密碼驗證 /// </summary> public bool PwdCheckEnable { get; set; } /// <summary> /// 發送郵件的端口,默認是25 /// </summary> public string Prot { get { return prot; } set { prot = value; } } /// <summary> /// 郵件 /// </summary> private MailMessage mailMessage; /// <summary> /// 發件服務器 /// </summary> private SmtpClient smtpClient; private string username; #endregion #region 構造方法 public EmailHelper() : this(null, null, null) { } public EmailHelper(string tomail, string frommail, string pwd) : this(tomail, frommail, pwd, null, null) { } public EmailHelper(string tomail, string frommail, string pwd, string subject = null, string emailbody = null) : this(tomail, frommail, pwd, subject, emailbody, true, true) { } /// <param name="tomail">收件箱地址,可以使用;隔開多個收件人地址</param> /// <param name="frommail">發件箱地址</param> /// <param name="subject">郵件主題</param> /// <param name="emailbody">郵件內容</param> /// <param name="pwd">發件箱密碼</param> /// <param name="sslEnable">是否ssl加密傳輸</param> /// <param name="pwdcheckEnable">是否驗證發件人郵箱密碼</param> public EmailHelper(string tomail, string frommail, string pwd, string subject, string emailbody, bool sslEnable = true, bool pwdcheckEnable = true) : this(SmtpClientComm.GetSmtp(frommail), tomail, frommail, pwd, subject, emailbody, sslEnable, pwdcheckEnable) { } /// <summary> /// 不常用的郵件服務器 /// </summary> /// <param name="stmpclient">不常用的郵件服務器</param> /// <param name="tomail">收件箱地址,可以使用;隔開多個收件人地址</param> /// <param name="frommail">發件箱地址</param> /// <param name="subject">郵件主題</param> /// <param name="emailbody">郵件內容</param> /// <param name="pwd">發件箱密碼</param> /// <param name="sslEnable">是否ssl加密傳輸</param> /// <param name="pwdcheckEnable">是否驗證發件人郵箱密碼</param> public EmailHelper(string stmpclient, string tomail, string frommail, string pwd, string subject, string emailbody, bool sslEnable = true, bool pwdcheckEnable = true) { ToMail = tomail; FromMail = frommail; Subject = subject; EmailBody = emailbody; Pwd = pwd; SslEnable = sslEnable; PwdCheckEnable = pwdcheckEnable; username = frommail.Substring(0, frommail.IndexOf("@")); SendServer = stmpclient; } #endregion #region 初始化 /// <summary> /// 初始化郵件服務器 /// </summary> private void InitSmtpClient() { smtpClient = new SmtpClient(); smtpClient.Host = SendServer; smtpClient.Port = Convert.ToInt32(Prot); smtpClient.UseDefaultCredentials = true; smtpClient.EnableSsl = SslEnable; smtpClient.Credentials = new NetworkCredential(username, Pwd); } /// <summary> /// 初始化郵件信息 /// </summary> private void InitMailMessage() { mailMessage = new MailMessage(); mailMessage.To.Add(ToMail); if (ToMail.Contains(";")) { mailMessage.To.Clear(); foreach (var item in ToMail.Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries)) { mailMessage.To.Add(item); } } mailMessage.From = new MailAddress(FromMail, username); mailMessage.Subject = Subject; mailMessage.SubjectEncoding = Encoding.UTF8; mailMessage.Body = EmailBody; mailMessage.IsBodyHtml = true; mailMessage.Priority = MailPriority.Normal; } #endregion /// <summary> /// 發送郵件 /// </summary> public void Send() { InitMailMessage(); InitSmtpClient(); try { if (mailMessage != null) { smtpClient.DeliveryMethod = SmtpDeliveryMethod.Network; smtpClient.Send(mailMessage); } } catch (Exception ex) { Console.WriteLine(ex.Message); } } /// <summary> /// 添加附件,多個附件使用“;”隔開 /// </summary> public void AddAttachments(string paths) { try { string[] path = paths.Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries); Attachment data; ContentDisposition disposition; for (int i = 0; i < path.Length; i++) { data = new Attachment(path[i], MediaTypeNames.Application.Octet); disposition = data.ContentDisposition; disposition.CreationDate = File.GetCreationTime(path[i]); disposition.ModificationDate = File.GetLastWriteTime(path[i]); disposition.ReadDate = File.GetLastAccessTime(path[i]); mailMessage.Attachments.Add(data); } } catch (Exception ex) { throw; } } } /// <summary> /// 常用的stmp服務器 /// </summary> public class SmtpClientComm { public const string Smtp163 = "smtp.163.com"; public const string Smtp126 = "smtp.126.com"; public const string SmtpQQ = "smtp.qq.com"; public const string Smtp188 = "smtp.188.com"; public const string SmtpYeah = "smtp.yeah.net"; public const string SmtpSina = "smtp.sina.com"; public const string SmtpSohu = "smtp.sohu.com"; public const string SmtpTom = "smtp.tom.com"; public const string SmtpGmail = "smtp.gmail.com"; public const string Smtp139 = "smtp.139.com"; /// <summary> /// 根據發件箱獲取郵件服務器 /// </summary> public static string GetSmtp(string FromMail) { string stmp = string.Empty; if (string.IsNullOrEmpty(FromMail)) { return ""; } switch (FromMail.Substring(FromMail.IndexOf("@", StringComparison.Ordinal) + 1).ToLower()) { case "126.com": stmp = Smtp126; break; case "163.com": stmp = Smtp163; break; case "qq.com": stmp = SmtpQQ; break; case "188.com": stmp = Smtp188; break; case "yeah.net": stmp = SmtpYeah; break; case "sina.com": stmp = SmtpSina; break; case "sohu.com": stmp = SmtpSohu; break; case "tom.com": stmp = SmtpTom; break; case "gmail.com": stmp = SmtpGmail; break; case "139.com": stmp = Smtp139; break; } if (string.IsNullOrEmpty(stmp)) { throw new Exception("未找到對應的郵件服務器"); } return stmp; } }
//郵件測試
EmailHelper em = new EmailHelper("smtp.163.com", "tomail", "frommail", "pwd", "測試", "這是一封測試郵件:http://www.baidu.com", true, false); em.Send();
-----------------------------------------------------------------------------------------
菜鳥D希望這些文字對您有所幫助。