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(@"\r\n", "<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
}