namespace 99999 { /// <summary> /// Common interfaces to connect mail server to process e-mail. /// </summary> public static class MailClient { /// <summary> /// Process mail queue in database. Call by web service just for schedule process. /// </summary> /// <param name="processId"></param> public static void ProcessQueue( string processId ) { try { //Lock and fetch all mail items in queue. StringBuilder sqlText = new StringBuilder() .AppendFormat("UPDATE dbmail_send_task SET MailFrom = '{0}' WHERE Status=0 AND MailFrom IS NULL ", processId) .AppendFormat("SELECT * FROM dbmail_send_task WHERE Status=0 AND MailFrom ='{0}'", processId); System.Diagnostics.Debug.WriteLine(sqlText.ToString()); DataTable dt = Database.SqlHelper.RunQuery(sqlText.ToString()); string mailServer = AppSettings.MailServer; if (string.IsNullOrEmpty(mailServer)) { return; } foreach (DataRow dr in dt.Rows) { int taskId = Convert.ToInt32(dr["TaskID"]); System.Diagnostics.Debug.WriteLine(string.Format("Send item:{0}", taskId)); try { //Send mail item using smtp. System.Net.Mail.MailMessage mail = new System.Net.Mail.MailMessage(); mail.Subject = Convert.ToString(dr["Title"]); mail.Body = Convert.ToString(dr["Body"]); //using reply to instead of mail from because of no mail from fields on UI. string replyTo = Convert.ToString(dr["ReplyTo"]); if (!string.IsNullOrEmpty(replyTo)) { mail.Sender = new System.Net.Mail.MailAddress(replyTo); mail.From = new System.Net.Mail.MailAddress(replyTo); } else { mail.Sender = new System.Net.Mail.MailAddress(AppSettings.MailDefaultSender); mail.From = new System.Net.Mail.MailAddress(AppSettings.MailDefaultSender); } string mailTo = Convert.ToString(dr["MailTo"]); foreach(string sTemp in mailTo.Split(';')) { if (!string.IsNullOrEmpty(sTemp)) { mail.To.Add(sTemp); } } string mailCc = Convert.ToString(dr["MailCc"]); foreach (string sTemp in mailCc.Split(';')) { if (!string.IsNullOrEmpty(sTemp)) { mail.CC.Add(sTemp); } } string mailBcc = Convert.ToString(dr["MailBcc"]); foreach (string sTemp in mailBcc.Split(';')) { if (!string.IsNullOrEmpty(sTemp)) { mail.Bcc.Add(sTemp); } } string attachment = Convert.ToString(dr["Attachments"]); foreach (string sTemp in attachment.Split(';')) { if (!string.IsNullOrEmpty(sTemp)) { mail.Attachments.Add(new System.Net.Mail.Attachment(sTemp)); } } mail.IsBodyHtml = true; mail.DeliveryNotificationOptions = System.Net.Mail.DeliveryNotificationOptions.OnFailure; System.Net.Mail.SmtpClient smtp = new System.Net.Mail.SmtpClient(mailServer); smtp.SendCompleted += new System.Net.Mail.SendCompletedEventHandler(smtp_SendCompleted); smtp.SendAsync(mail, taskId); } catch (Exception ex) { Logging.LogWriter.Write(ex); string sqlText1 = string.Format("UPDATE dbmail_send_task SET [Status]=-1, Remark=N'{0}', SendTime=GETDATE(), MailFrom='ERROR' WHERE TaskID={1} ",ex.Message,taskId); System.Diagnostics.Debug.WriteLine(sqlText1.ToString()); Database.SqlHelper.RunCommand(sqlText1); } } } catch (Exception ex) { Logging.LogWriter.Write(ex); } } /// <summary> /// Process failed mail queue in database. Call by web service just for schedule process. /// </summary> /// <param name="processId"></param> public static void ResendFailedMails(string processId) { try { //Lock and fetch all mail items in queue. StringBuilder sqlText = new StringBuilder() .AppendFormat("UPDATE dbmail_send_task SET MailFrom = '{0}' WHERE Status=-1 AND MailFrom<>'{0}' AND MailFrom<>'ERROR' ", processId) .AppendFormat("SELECT * FROM dbmail_send_task WHERE Status=-1 AND MailFrom='{0}' AND MailFrom<>'ERROR' ", processId); System.Diagnostics.Debug.WriteLine(sqlText.ToString()); DataTable dt = Database.SqlHelper.RunQuery(sqlText.ToString()); string mailServer = AppSettings.MailServer; if (string.IsNullOrEmpty(mailServer)) { return; } foreach (DataRow dr in dt.Rows) { int taskId = Convert.ToInt32(dr["TaskID"]); System.Diagnostics.Debug.WriteLine(string.Format("Resend item:{0}",taskId)); try { //Send mail item using smtp. System.Net.Mail.MailMessage mail = new System.Net.Mail.MailMessage(); mail.Subject = Convert.ToString(dr["Title"]); mail.Body = Convert.ToString(dr["Body"]); //using reply to instead of mail from because of no mail from fields on UI. string replyTo = Convert.ToString(dr["ReplyTo"]); if (!string.IsNullOrEmpty(replyTo)) { mail.Sender = new System.Net.Mail.MailAddress(replyTo); mail.From = new System.Net.Mail.MailAddress(replyTo); } else { mail.Sender = new System.Net.Mail.MailAddress(AppSettings.MailDefaultSender); mail.From = new System.Net.Mail.MailAddress(AppSettings.MailDefaultSender); } string mailTo = Convert.ToString(dr["MailTo"]); foreach (string sTemp in mailTo.Split(';')) { if (!string.IsNullOrEmpty(sTemp)) { mail.To.Add(sTemp); } } string mailCc = Convert.ToString(dr["MailCc"]); foreach (string sTemp in mailCc.Split(';')) { if (!string.IsNullOrEmpty(sTemp)) { mail.CC.Add(sTemp); } } string mailBcc = Convert.ToString(dr["MailBcc"]); foreach (string sTemp in mailBcc.Split(';')) { if (!string.IsNullOrEmpty(sTemp)) { mail.Bcc.Add(sTemp); } } string attachment = Convert.ToString(dr["Attachments"]); foreach (string sTemp in attachment.Split(';')) { if (!string.IsNullOrEmpty(sTemp)) { mail.Attachments.Add(new System.Net.Mail.Attachment(sTemp)); } } mail.IsBodyHtml = true; mail.DeliveryNotificationOptions = System.Net.Mail.DeliveryNotificationOptions.OnFailure; System.Net.Mail.SmtpClient smtp = new System.Net.Mail.SmtpClient(mailServer); smtp.SendCompleted += new System.Net.Mail.SendCompletedEventHandler(smtp_SendCompleted); smtp.SendAsync(mail, taskId); } catch (Exception ex) { Logging.LogWriter.Write(ex); string sqlText1 = string.Format("UPDATE dbmail_send_task SET [Status]=-1, Remark=N'{0}', MailFrom='ERROR', SendTime=GETDATE(), MailFrom='ERROR' WHERE TaskID={1} ", ex.Message, taskId); System.Diagnostics.Debug.WriteLine(sqlText1.ToString()); Database.SqlHelper.RunCommand(sqlText1); } } } catch (Exception ex) { Logging.LogWriter.Write(ex); } } static void smtp_SendCompleted(object sender, System.ComponentModel.AsyncCompletedEventArgs e) { try { int taskId = Convert.ToInt32(e.UserState); if (e.Error != null) { string sqlText = string.Format("UPDATE dbmail_send_task SET [Status]=-1, Remark=N'{0}',SendTime=GETDATE(), MailFrom='ERROR' WHERE TaskID={1} ", e.Error.Message, taskId); System.Diagnostics.Debug.WriteLine(sqlText.ToString()); Database.SqlHelper.RunCommand(sqlText); } else { string sqlText = string.Format("UPDATE dbmail_send_task SET [Status]=1, SendTime=GETDATE(), Remark=NULL WHERE TaskID={0} ", taskId); System.Diagnostics.Debug.WriteLine(sqlText.ToString()); Database.SqlHelper.RunCommand(sqlText); } } catch (Exception ex) { Logging.LogWriter.Write(ex); } } /// <summary> /// Send out a mail, write log file but no warning returned if any exception /// </summary> /// <param name="mailAddress">Include To, CC, BCC mail address</param> /// <param name="mailContent"></param> /// <returns></returns> public static bool SendMessage(MailAddress mailAddress, MailEntity mailContent) { string profile = Configuration.AppSettings.MailUserDeliveryProfile; if (string.IsNullOrEmpty(profile)) { throw new ArgumentNullException("MailUserDeliveryProfile", "Value of configuration item is required."); } if (string.IsNullOrEmpty(mailAddress.To)) { throw new ArgumentNullException("MailAddress.To", "Value of MailTo is required."); } string sqlText = "sp_HtmlMail_Send @profile=@P0,@mailto=@P1,@mailcc=@P2,@mailbcc=@P3,@replyto=@P4,@title=@P5,@body=@P6,@attachments=@P7,@UserAccountID=@P8,@Remark=@P9"; IDataParameter P0 = new SqlParameter("@P0", SqlDbType.VarChar); P0.Value = profile; IDataParameter P1 = new SqlParameter("@P1", SqlDbType.VarChar); P1.Value = mailAddress.To; IDataParameter P2 = new SqlParameter("@P2", SqlDbType.VarChar); P2.Value = mailAddress.Cc; IDataParameter P3 = new SqlParameter("@P3", SqlDbType.VarChar); P3.Value = mailAddress.Bcc; IDataParameter P4 = new SqlParameter("@P4", SqlDbType.VarChar); P4.Value = mailAddress.ReplyTo; IDataParameter P5 = new SqlParameter("@P5", SqlDbType.NVarChar); P5.Value = mailContent.Subject; IDataParameter P6 = new SqlParameter("@P6", SqlDbType.NVarChar); P6.Value = CleanHtml(mailContent.Body); IDataParameter P7 = new SqlParameter("@P7", SqlDbType.NVarChar); P7.Value = mailContent.Attachments; IDataParameter P8 = new SqlParameter("@P8", SqlDbType.Int); if (mailAddress.SendBy > 0) { P8.Value = mailAddress.SendBy; } else { P8.Value = Security.UserAuthentication.GetCurrentOperator(); } IDataParameter P9 = new SqlParameter("@P9", SqlDbType.NVarChar); P9.Value = mailContent.Remark; int result = Database.SqlHelper.RunCommand(sqlText, P0, P1, P2, P3, P4, P5, P6, P7, P8, P9); if (result > 0) { return true; } else { return false; } } /// <summary> /// Clean up html text /// </summary> /// <param name="input"></param> /// <returns></returns> private static string CleanHtml(string input) { string output = string.Empty; output = input.Replace(@" ", "<br>"); return output; } ///// <summary> ///// Encode input string to Unicode ///// </summary> ///// <param name="input"></param> ///// <returns></returns> //private static string UTF8Str(string input) //{ // byte[] bs = System.Text.Encoding.Default.GetBytes(input); // string output = System.Text.Encoding.GetEncoding("UTF-8").GetString(bs); // return output; //} //private static string ANSIStr(string input) //{ // byte[] bs = System.Text.Encoding.Default.GetBytes(input); // string output = System.Text.Encoding.ASCII.GetString(bs); // return output; //} ///// <summary> ///// Convert ununicode string to unicode string. ///// </summary> ///// <param name="str"></param> ///// <returns></returns> //private static string ConvertToUnicodeString(string str) //{ // StringBuilder outStr = new StringBuilder(); // if (!string.IsNullOrEmpty(str)) // { // for (int i = 0; i < str.Length; i++) // { // if (str[i] > 0xff) // { // outStr.AppendFormat("&#{0}", ((int)str[i]).ToString()); // } // else // { // outStr.Append(str[i]); // } // } // } // return outStr.ToString(); //} } #region Mail Entity /// <summary> /// Build mail entity, include subject,body, attachments and options. /// </summary> public class MailEntity { /// <summary> /// Build a mail entity with template id, you may use -1 if no template id. /// </summary> /// <param name="templateId">template id, you may use -1 if no template id.</param> public MailEntity(int templateId) { if (templateId == -1) { return; } else { //Load mail template from database according to special template id string sqlText = string.Format("select * from tb_MailTemplate where ID={0}", templateId); DataTable dt = Database.SqlHelper.RunQuery(sqlText); if (dt != null && dt.Rows.Count > 0) { object o = dt.Rows[0]["Content"]; if (o != null) { _body = o.ToString(); } object title = dt.Rows[0]["Title"]; if (title != null) { _subject = title.ToString(); } } } } private string _subject = ""; /// <summary> /// Mail title /// </summary> public string Subject { get { return _subject; } set { _subject = value; } } private string _body = ""; /// <summary> /// Mail body, html string /// </summary> public string Body { get { return _body; } set { _body = value; } } private string _attachments = ""; /// <summary> /// Mail attachments, split by "|" if multiple files /// </summary> public string Attachments { get { return _attachments; } } private string _attachmentFilePath = ""; public string AttachmentFilePath { get { return _attachmentFilePath; } } private string _remark = ""; /// <summary> /// Remark /// </summary> public string Remark { get { return _remark; } set { _remark = value; } } /// <summary> /// Merge field into template /// </summary> /// <param name="fieldName"></param> /// <param name="fieldValue"></param> public void MergeField(string fieldName, string fieldValue) { if (!string.IsNullOrEmpty(_body)) { _body = _body.Replace(fieldName, fieldValue); _subject = _subject.Replace(fieldName, fieldValue); } } /// <summary> /// Add file as attachment /// </summary> /// <param name="fileName"></param> public void AttachFile(string fileName) { if (string.IsNullOrEmpty(_attachments)) { _attachments = fileName; } else { _attachments += "|" + fileName; } } } #endregion #region Mail Address /// <summary> /// Build mail address entity, include To, Cc, Bcc /// </summary> [Serializable] public class MailAddress { private string _to = ""; /// <summary> /// Address of mail to /// </summary> public string To { get { return _to.TrimStart(';'); } } private string _cc = ""; /// <summary> /// Address of mail cc /// </summary> public string Cc { get { return _cc.TrimStart(';'); } set { _cc = value; } } private string _bcc = ""; /// <summary> /// Address of mail bcc /// </summary> public string Bcc { get { return _bcc.TrimStart(';'); } } private string _replyTo = ""; /// <summary> /// Address of mail receiver reply to /// </summary> public string ReplyTo { get { return _replyTo; } set { _replyTo = value; } } private int _sendBy = 0; /// <summary> /// Address of mail send by /// </summary> public int SendBy { get { return _sendBy; } set { _sendBy = value; } } /// <summary> /// Address of mail sender /// </summary> public string From { get { return Configuration.AppSettings.MailDeliveryFrom; } } /// <summary> /// Add new address to recipients, copy recipients or blind recipients /// </summary> /// <param name="address"></param> /// <param name="addressType"></param> public void Add(string address, MailAddressType addressType) { switch (addressType) { case MailAddressType.To: { _to = _to + ";" + address; break; } case MailAddressType.Cc: { _cc = _cc + ";" + address; break; } case MailAddressType.Bcc: { _bcc = _bcc + ";" + address; break; } default: break; } } /// <summary> /// Add new address to recipients, copy recipients or blind recipients /// </summary> /// <param name="address"></param> /// <param name="addressType"></param> public void Add(string toAddress, string ccAddress, string bccAddress) { if (!string.IsNullOrEmpty(toAddress)) { _to = _to + ";" + toAddress; } if (!string.IsNullOrEmpty(ccAddress)) { _cc = _cc + ";" + ccAddress; } if (!string.IsNullOrEmpty(bccAddress)) { _bcc = _bcc + ";" + bccAddress; } } } #endregion #region Mail Address Type /// <summary> /// Mail address type, include To, Cc, Bcc /// </summary> public enum MailAddressType { To, Cc, Bcc } #endregion }