最近工作原因需要維護ASP.NET 1.1 的程序,本來用C# 2.0 System.Net.Mail namespace 發送郵件用得好好得,但ASP.NET 1.1 裡面的System.Web.Mail 死活問題就是多,於是選擇其它策略,封裝了郵件發送的接口,再以其它方式來實現郵件發送,於是就有了下面這些文字。
定義抽象介面以封裝所有實作:
using System;
using System.Web.Mail;
namespace YywMail
{
public abstract class MySmtpMail
{
Fields#region Fields
private string _defaultCharset = "GB2312";
private int _defaultSmtpPort = 25;
#endregion
Properties#region Properties
protected string DefaultCharset
{
get { return this._defaultCharset; }
}
protected int DefaultSmtpPort
{
get { return this._defaultSmtpPort;}
}
#endregion
Methods#region Methods
/**//// <summary>
/// 取得預設實例
/// </summary>
/// <returns></returns>
public static MySmtpMail GetDefaultInstance()
{
// 此處可透過外部設定檔定義具體實作類型,再
// 透過Activator.CreateInstance() 取得類型實例
}
/**//// <summary>
/// 做一些初始化的工作
/// </summary>
public abstract void Open();
/**//// <summary>
/// 銷毀對象
/// </summary>
public abstract void Close();
/**//// <summary>
/// 傳送郵件
/// </summary>
/// <param name="message"></param>
/// <param name="smtpServer"></param>
/// <param name="serverUsername"></param>
/// <param name="serverPassword"></param>
/// <returns></returns>
public bool Send(MailMessage message, string smtpServer, string serverUsername, string serverPassword)
{
return Send(message, smtpServer, serverUsername, serverPassword, this._defaultSmtpPort);
}
public abstract bool Send(MailMessage message, string smtpServer, string serverUsername, string serverPassword, int smtpPort);
public static string[] GetTo(MailMessage message)
{
if (message == null)
throw new ArgumentNullException("message");
if (Globals.IsNullorEmpty(message.To))
return null;
return message.To.Split(';');
}
public static string[] GetCc(MailMessage message)
{
if (message == null)
throw new ArgumentNullException("message");
if (Globals.IsNullorEmpty(message.Cc))
return null;
return message.Cc.Split(';');
}
public static string[] GetBcc(MailMessage message)
{
if (message == null)
throw new ArgumentNullException("message");
if (Globals.IsNullorEmpty(message.Bcc))
return null;
return message.Bcc.Split(';');
}
#endregion
}
}
註: 依照常理,使用前先Open() 一下,使用後也別忘了Close()
實作方案一(Jmail 元件):
在.NET 中使用Jmail 需要如下設定:
1、安裝jmail;
2、找到jmail.dll;
3.註冊該元件Jmail.dll,作法是將jmail.dll檔案拷貝到system32目錄下,再執行指令「regsvr32 jmail.dll」(不含引號),卸載可執行「regsvr32 /u jmail.dll」;
4.執行Program FilesMicrosoft Visual Studio .NETFrameworkSDKBinildasm.exe(可使用Visual Studio .Net 2003 指令提示),
格式如下:tlbimp c:Program FilesDimacw3JMail4jmail.dll /out:MyJmail.dll /namespace:MyJmail
產生MyJmail.dll後,將它引用至專案中。
下載元件
接下來就是實作類別的編寫了:
using System;
using System.Web.Mail;
namespace YywMail
{
public class JMailSmtpMail : MySmtpMail
{
Fields#region Fields
MyJmail.Message jmail = null;
#endregion
Methods#region Methods
public override void Open()
{
jmail = new MyJmail.Message();
}
public override bool Send(MailMessage message, string smtpServer, string serverUsername, string serverPassword, int smtpPort)
{
if (jmail == null)
throw new Exception("smtp is Closed!");
if (message == null)
throw new ArgumentNullException("message");
DateTime t = DateTime.Now;
//Silent屬性:如果設定為true,JMail不會拋出例外錯誤. JMail. Send( () 會根據操作結果傳回true或false
jmail.Silent = false;
//jmail建立的日誌,前提loging屬性設定為true
jmail.Logging = true;
//字元集,預設為"US-ASCII"
jmail.Charset = base.DefaultCharset;
//信件的contentype. 預設是"text/plain") : 字串如果你以HTML格式發送郵件, 改為"text/html"即可。
if (message.BodyFormat == MailFormat.Html)
jmail.ContentType = "text/html";
jmail.Priority = GetJmailPriority(message.Priority);
//新增收件者
string[] toArray = MySmtpMail.GetTo(message);
if (toArray != null && toArray.Length > 0)
{
bool isAddedRecipient = false;
for (int i = 0; i < toArray.Length; i++)
{
if (Globals.IsNullorEmpty(toArray[i]))
continue;
if (!isAddedRecipient)
{
jmail.AddRecipient(toArray[i], String.Empty, String.Empty);
isAddedRecipient = true;
}
else
{
jmail.AddRecipientCC(toArray[i], String.Empty, String.Empty);
}
}
}
string[] ccArray = MySmtpMail.GetCc(message);
if (ccArray != null)
{
foreach (string cc in ccArray)
{
if (!Globals.IsNullorEmpty(cc))
jmail.AddRecipientCC(cc, String.Empty, String.Empty);
}
}
string[] bccArray = MySmtpMail.GetBcc(message);
if (ccArray != null)
{
foreach (string bcc in bccArray)
{
if (!Globals.IsNullorEmpty(bcc))
jmail.AddRecipientBCC(bcc, String.Empty);
}
}
jmail.From = message.From;
//寄件者郵件使用者名稱
jmail.MailServerUserName = serverUsername;
//寄件者郵件密碼
jmail.MailServerPassWord = serverPassword;
//設定郵件標題
jmail.Subject = message.Subject;
//郵件添加附件,(多重附件的話,可以再加一條jmail.AddAttachment( "c:\test.jpg",true,null);)就可以搞定了。 [註]:加了附件,講把上面的jmail.ContentType="text/html";刪掉。否則會在郵件裡出現亂碼。
//jmail.AddAttachment("c:\test.jpg", true, null);
//郵件內容
jmail.Body = message.Body;
if (message.BodyFormat == MailFormat.Html)
jmail.Body += "<br><br>";
else
jmail.Body += "rnrn";
jmail.Body += DateTime.Now.ToString();
smtpServer = String.Format("{0}:{1}", smtpServer, smtpPort);
//jmail傳送的方法
bool result = jmail.Send(smtpServer, false);
return result;
}
public override void Close()
{
jmail.Close();
}
private static byte GetJmailPriority( System.Web.Mail.MailPriority priority)
{
// 郵件等級,1為加急,3為普通,5為低級
if (priority == System.Web.Mail.MailPriority.High)
return 1;
if (priority == System.Web.Mail.MailPriority.Low)
return 5;
return 3;
}
#endregion
}
}
實作方案二(OpenSmtp.Net 元件):
對於還沒接觸過OpenSmtp.Net 的朋友可以先Google 下,這裡不再做概念介紹,同時它還有一個孿生兄弟OpenPop.Net,至於OpenSmtp.Net 我們可以在http://sourceforge.net/projects/opensmtp-net/下載到,目前最新版本是1.11。
接下來開始進入主題:
using System;
using System.Web.Mail;
using OpenSmtp.Mail;
namespace YywMail
{
public class OpenSmtpMail : MySmtpMail
{
Files#region Files
OpenSmtp.Mail.MailMessage msg = null;
Smtp smtp = null;
#endregion
Methods#region Methods
public override void Open()
{
msg = new OpenSmtp.Mail.MailMessage();
smtp = new Smtp();
}
public override bool Send(System.Web.Mail.MailMessage message, string smtpServer, string serverUsername, string serverPassword, int smtpPort)
{
if (msg == null || smtp == null)
throw new Exception("smtp is Closed!");
if (message == null)
throw new ArgumentNullException("message");
SmtpConfig.VerifyAddresses = false;
EmailAddress from = new EmailAddress(message.From, message.From);
msg.Charset = base.DefaultCharset;
msg.From = from;
msg.Priority = GetOpenSmtpPriority(message.Priority);
//新增收件人
string[] toArray = MySmtpMail.GetTo(message);
if (toArray != null)
{
foreach (string to in toArray)
{
if (!Globals.IsNullorEmpty(to))
msg.AddRecipient(to, AddressType.To);
}
}
string[] ccArray = MySmtpMail.GetCc(message);
if (ccArray != null)
{
foreach (string cc in ccArray)
{
if (!Globals.IsNullorEmpty(cc))
msg.AddRecipient(cc, AddressType.Cc);
}
}
string[] bccArray = MySmtpMail.GetBcc(message);
if (ccArray != null)
{
foreach (string bcc in bccArray)
{
if (!Globals.IsNullorEmpty(bcc))
msg.AddRecipient(bcc, AddressType.Bcc);
}
}
msg.Subject = message.Subject;
if (message.BodyFormat == System.Web.Mail.MailFormat.Html)
{
msg.HtmlBody = message.Body + "<br><br>" + DateTime.Now.ToString();
}
else
{
msg.Body = message.Body + "rnrn" + DateTime.Now.ToString();;
}
string str1 = msg.HtmlBody;
string str2 = msg.Body;
smtp.Host = smtpServer;
smtp.Username = serverUsername;
smtp.Password = serverPassword;
smtp.Port = smtpPort;
smtp.SendMail(msg);
return true;
}
public override void Close()
{
msg = null;
smtp = null;
}
private static string GetOpenSmtpPriority( System.Web.Mail.MailPriority priority)
{
// 郵件等級,1為加急,3為普通,5為低級
if (priority == System.Web.Mail.MailPriority.High)
return OpenSmtp.Mail.MailPriority.High;
if (priority == System.Web.Mail.MailPriority.Low)
return OpenSmtp.Mail.MailPriority.Low;
return OpenSmtp.Mail.MailPriority.Normal;
}
#endregion
}
}
實現方案三:
(上面兩種實現方案已經足夠滿足目前的需求,有必要的話再繼續擴展)