郵件處理類

using System;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Web;
using System.Web.SessionState;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;
using System.Text;
using System.IO;
using System.Net;
using System.Net.Sockets;

namespace Seaskyer.Mail
{
    
/// <summary>
    
/// 支持SMTP服務器認證的郵件發送類
    
/// </summary>
    public class ESmtpMail
    {
        
/// <summary>
        
/// 構造函數
        
/// </summary>
        public ESmtpMail()
        {
            
//
            
// TODO: 在此處添加構造函數邏輯
            
//
        }

        
/// <summary>
        
/// 析構函數(自動執行)
        
/// </summary>
        ~ESmtpMail()
        {
            ns.Close();
            tc.Close();
        }

        
        
/// <summary>
        
/// 設定語言代碼,默認設定爲GB2312,如不需要可設置爲""
        
/// </summary>
        public string Charset="GB2312";

        
/// <summary>
        
/// 發件人地址
        
/// </summary>
        public string From="";

        
/// <summary>
        
/// 發件人姓名
        
/// </summary>
        public string FromName="";

        
/// <summary>
        
/// 回覆郵件地址
        
/// </summary>
        public string ReplyTo="";

        
/// <summary>
        
/// 郵件服務器域名
        
/// </summary>    
        private string mailserver="";

        
/// <summary>
        
/// 郵件服務器端口號
        
/// </summary>    
        private int mailserverport=25;

        
/// <summary>
        
/// 是否需要SMTP驗證
        
/// </summary>        
        private bool ESmtp=false;

        
/// <summary>
        
/// SMTP認證時使用的用戶名
        
/// </summary>
        private string username="";

        
/// <summary>
        
/// SMTP認證時使用的密碼
        
/// </summary>
        private string password="";

        
/// <summary>
        
/// 郵件主題
        
/// </summary>        
        public string Subject="";
        
        
/// <summary>
        
/// 是否Html郵件
        
/// </summary>        
        public bool Html=false;

        
/// <summary>
        
/// 郵件正文
        
/// </summary>        
        public string Body="";

        
/// <summary>
        
/// 收件人列表
        
/// </summary>
        private Hashtable Recipient=new Hashtable();

        
/// <summary>
        
/// 密送收件人列表
        
/// </summary>
        private Hashtable RecipientBCC=new Hashtable();

        
/// <summary>
        
/// 郵件發送優先級,可設置爲"High","Normal","Low"或"1","3","5"
        
/// </summary>
        private string priority="Normal";

        
/// <summary>
        
/// 錯誤消息反饋
        
/// </summary>
        private string errmsg;

        
/// <summary>
        
/// 服務器交互記錄
        
/// </summary>
        private string logs="";

        
private string enter=" ";
        
/// <summary>
        
/// TcpClient對象,用於連接服務器
        
/// </summary>    
        private TcpClient tc;

        
/// <summary>
        
/// NetworkStream對象
        
/// </summary>    
        private NetworkStream ns;

        
/// <summary>
        
/// SMTP錯誤代碼哈希表
        
/// </summary>
        private Hashtable ErrCodeHT = new Hashtable();

        
/// <summary>
        
/// SMTP正確代碼哈希表
        
/// </summary>
        private Hashtable RightCodeHT = new Hashtable();

        
/// <summary>
        
/// 收件人姓名
        
/// </summary>    
        public string RecipientName="";


        
private int RecipientNum=0;//收件人數量
        private int RecipientBCCNum=0;//密件收件人數量

        # region 
"Property"

        
/// <summary>
        
/// 郵件服務器域名和驗證信息
        
/// 形如:"user:[email protected]:25",也可省略次要信息。如"user:[email protected]"或"www.server.com"
        
/// </summary>    
        public string MailDomain
        {
            
set
            {
                
string maidomain=value.Trim();
                
int tempint;

                
if(maidomain!="")
                {
                    tempint
=maidomain.IndexOf("@");
                    
if(tempint!=-1)
                    {
                        
string up=maidomain.Substring(0,tempint);
                        MailServerUserName
=up.Substring(0,up.IndexOf(":"));
                        MailServerPassWord
=up.Substring(up.IndexOf(":")+1,up.Length-up.IndexOf(":")-1);
                        maidomain
=maidomain.Substring(tempint+1,maidomain.Length-tempint-1);
                    }

                    tempint
=maidomain.IndexOf(":");
                    
if(tempint!=-1)
                    {
                        mailserver
=maidomain.Substring(0,tempint);
                        mailserverport
=System.Convert.ToInt32(maidomain.Substring(tempint+1,maidomain.Length-tempint-1));
                    }
                    
else
                    {
                        mailserver
=maidomain;

                    }

                    
                }

            }
        }

        
/// <summary>
        
/// 郵件服務器端口號
        
/// </summary>    
        public int MailDomainPort
        {
            
set
            {
                mailserverport
=value;
            }
        }

        
/// <summary>
        
/// SMTP認證時使用的用戶名
        
/// </summary>
        public string MailServerUserName
        {
            
set
            {
                
if(value.Trim()!="")
                {
                    username
=value.Trim();
                    ESmtp
=true;
                }
                
else
                {
                    username
="";
                    ESmtp
=false;
                }
            }
        }

        
/// <summary>
        
/// SMTP認證時使用的密碼
        
/// </summary>
        public string MailServerPassWord
        {
            
set
            {
                password
=value;
            }
        }    

        
/// <summary>
        
/// 郵件發送優先級,可設置爲"High","Normal","Low"或"1","3","5"
        
/// </summary>
        public string Priority
        {
            
set
            {
                
switch(value.ToLower())
                {
                    
case "high":
                        priority
="High";
                        
break;

                    
case "1":
                        priority
="High";
                        
break;

                    
case "normal":
                        priority
="Normal";
                        
break;

                    
case "3":
                        priority
="Normal";
                        
break;

                    
case "low":
                        priority
="Low";
                        
break;

                    
case "5":
                        priority
="Low";
                        
break;

                    
default:
                        priority
="Normal";
                        
break;
                }
            }
        }

        
/// <summary>
        
/// 錯誤消息反饋
        
/// </summary>        
        public string ErrorMessage
        {
            
get
            {
                
return errmsg;
            }
        }

        
/// <summary>
        
/// 服務器交互記錄。
        
/// </summary>
        public string Logs
        {
            
get
            {
                
return logs;
            }
        }
        

        # endregion


        
        
/// <summary>
        
/// SMTP迴應代碼哈希表
        
/// </summary>
        private void SMTPCodeAdd()
        {
            ErrCodeHT.Add(
"500","郵箱地址錯誤");
            ErrCodeHT.Add(
"501","參數格式錯誤");
            ErrCodeHT.Add(
"502","命令不可實現");
            ErrCodeHT.Add(
"503","服務器需要SMTP驗證");
            ErrCodeHT.Add(
"504","命令參數不可實現");
            ErrCodeHT.Add(
"421","服務未就緒,關閉傳輸信道");
            ErrCodeHT.Add(
"450","要求的郵件操作未完成,郵箱不可用(例如,郵箱忙)");
            ErrCodeHT.Add(
"550","要求的郵件操作未完成,郵箱不可用(例如,郵箱未找到,或不可訪問)");
            ErrCodeHT.Add(
"451","放棄要求的操作;處理過程中出錯");
            ErrCodeHT.Add(
"551","用戶非本地,請嘗試<forward-path>");
            ErrCodeHT.Add(
"452","系統存儲不足,要求的操作未執行");
            ErrCodeHT.Add(
"552","過量的存儲分配,要求的操作未執行");
            ErrCodeHT.Add(
"553","郵箱名不可用,要求的操作未執行(例如郵箱格式錯誤)");
            ErrCodeHT.Add(
"432","需要一個密碼轉換");
            ErrCodeHT.Add(
"534","認證機制過於簡單");
            ErrCodeHT.Add(
"538","當前請求的認證機制需要加密");
            ErrCodeHT.Add(
"454","臨時認證失敗");
            ErrCodeHT.Add(
"530","需要認證");

            RightCodeHT.Add(
"220","服務就緒");
            RightCodeHT.Add(
"250","要求的郵件操作完成");
            RightCodeHT.Add(
"251","用戶非本地,將轉發向<forward-path>");
            RightCodeHT.Add(
"354","開始郵件輸入,以<CRLF>.<CRLF>結束");
            RightCodeHT.Add(
"221","服務關閉傳輸信道");
            RightCodeHT.Add(
"334","服務器響應驗證Base64字符串");
            RightCodeHT.Add(
"235","驗證成功");
        }


        
/// <summary>
        
/// 將字符串編碼爲Base64字符串
        
/// </summary>
        
/// <param name="estr">要編碼的字符串</param>
        private string Base64Encode(string estr)
        {
            
byte[] barray;
            barray
=Encoding.Default.GetBytes(estr);
            
return Convert.ToBase64String(barray);
        }


        
/// <summary>
        
/// 將Base64字符串解碼爲普通字符串
        
/// </summary>
        
/// <param name="dstr">要解碼的字符串</param>
        private string Base64Decode(string dstr)
        {
            
byte[] barray;
            barray
=Convert.FromBase64String(dstr);
            
return Encoding.Default.GetString(barray);
        }


        
/// <summary>
        
/// 添加一個收件人
        
/// </summary>    
        
/// <param name="str">收件人地址</param>
        public bool AddRecipient(string str)
        {
            str
=str.Trim();
            
if(str==null||str==""||str.IndexOf("@")==-1)
                
return true;
            
if(RecipientNum<10)
            {
                Recipient.Add(RecipientNum,str);
                RecipientNum
++;
                
return true;
            }
            
else
            {
                errmsg
+="收件人過多";
                
return false;
            }
        }


        
/// <summary>
        
/// 添加一組收件人(不超過10個),參數爲字符串數組
        
/// </summary>
        
/// <param name="str">保存有收件人地址的字符串數組(不超過10個)</param>    
        public bool AddRecipient(string[] str)
        {
            
for(int i=0;i<str.Length;i++)
            {
                
if(!AddRecipient(str[i]))
                {
                    
return false;
                }
            }
            
return true;
        }


        
/// <summary>
        
/// 添加一個密件收件人
        
/// </summary>
        
/// <param name="str">收件人地址</param>
        public bool AddRecipientBCC(string str)
        {
            
if(str==null||str.Trim()=="")
                
return true;
            
if(RecipientBCCNum<10)
            {
                RecipientBCC.Add(RecipientBCCNum,str);
                RecipientBCCNum
++;
                
return true;
            }
            
else
            {
                errmsg
+="收件人過多";
                
return false;
            }
        }


        
/// <summary>
        
/// 添加一組密件收件人(不超過10個),參數爲字符串數組
        
/// </summary>    
        
/// <param name="str">保存有收件人地址的字符串數組(不超過10個)</param>
        public bool AddRecipientBCC(string[] str)
        {
            
for(int i=0;i<str.Length;i++)
            {
                
if(!AddRecipientBCC(str[i]))
                {
                    
return false;
                }
            }
            
return true;
        }


        
/// <summary>
        
/// 發送SMTP命令
        
/// </summary>    
        private bool SendCommand(string Command)
        {
            
byte[]  WriteBuffer;
            
if(Command==null||Command.Trim()=="")
            {
                
return true;
            }
            logs
+=Command;
            WriteBuffer 
= Encoding.Default.GetBytes(Command);
            
try
            {
                ns.Write(WriteBuffer,
0,WriteBuffer.Length);
            }
            
catch
            {
                errmsg
="網絡連接錯誤";
                
return false;
            }
            
return true;
        }

        
/// <summary>
        
/// 接收SMTP服務器迴應
        
/// </summary>
        private string RecvResponse()
        {
            
int StreamSize;
            
string ReturnValue = "";
            
byte[]  ReadBuffer = new byte[1024] ;
            
try
            {
                StreamSize
=ns.Read(ReadBuffer,0,ReadBuffer.Length);
            }
            
catch
            {
                errmsg
="網絡連接錯誤";
                
return "false";
            }

            
if (StreamSize==0)
            {
                
return ReturnValue ;
            }
            
else
            {
                ReturnValue 
= Encoding.Default.GetString(ReadBuffer).Substring(0,StreamSize);
                logs
+=ReturnValue;
                
return  ReturnValue;
            }
        }


        
/// <summary>
        
/// 與服務器交互,發送一條命令並接收回應。
        
/// </summary>
        
/// <param name="Command">一個要發送的命令</param>
        
/// <param name="errstr">如果錯誤,要反饋的信息</param>
        private bool Dialog(string Command,string errstr)
        {
            
if(Command==null||Command.Trim()=="")
            {
                
return true;
            }
            
if(SendCommand(Command))
            {
                
string RR=RecvResponse();
                
if(RR=="false")
                {
                    
return false;
                }
                
string RRCode=RR.Substring(0,3);
                
if(RightCodeHT[RRCode]!=null)
                {
                    
return true;
                }
                
else
                {
                    
if(ErrCodeHT[RRCode]!=null)
                    {
                        errmsg
+=(RRCode+ErrCodeHT[RRCode].ToString());
                        errmsg
+=enter;
                    }
                    
else
                    {
                        errmsg
+=RR;
                    }
                    errmsg
+=errstr;
                    
return false;
                }
            }
            
else
            {
                
return false;
            }

        }


        
/// <summary>
        
/// 與服務器交互,發送一組命令並接收回應。
        
/// </summary>
        private bool Dialog(string[] Command,string errstr)
        {
            
for(int i=0;i<Command.Length;i++)
            {
                
if(!Dialog(Command[i],""))
                {
                    errmsg
+=enter;
                    errmsg
+=errstr;
                    
return false;
                }
            }

            
return true;
        }



        
private bool SendEmail()
        {
            
//連接網絡
            try
            {
                tc
=new TcpClient(mailserver,mailserverport);
            }
            
catch(Exception e)
            {
                errmsg
=e.ToString();
                
return false;
            }

            ns 
= tc.GetStream();
            SMTPCodeAdd();

            
//驗證網絡連接是否正確
            if(RightCodeHT[RecvResponse().Substring(0,3)]==null)
            {
                errmsg
="網絡連接失敗";
                
return false;
            }


            
string[] SendBuffer;
            
string SendBufferstr;

            
//進行SMTP驗證
            if(ESmtp)
            {
                SendBuffer
=new String[4];
                SendBuffer[
0]="EHLO " + mailserver + enter;
                SendBuffer[
1]="AUTH LOGIN" + enter;
                SendBuffer[
2]=Base64Encode(username) + enter;
                SendBuffer[
3]=Base64Encode(password) + enter;
                
if(!Dialog(SendBuffer,"SMTP服務器驗證失敗,請覈對用戶名和密碼。"))
                    
return false;
            }
            
else
            {
                SendBufferstr
="HELO " + mailserver + enter;
                
if(!Dialog(SendBufferstr,""))
                    
return false;
            }

            
//
            SendBufferstr="MAIL FROM:<" + From + ">" + enter;
            
if(!Dialog(SendBufferstr,"發件人地址錯誤,或不能爲空"))
                
return false;

            
//
            SendBuffer=new string[10];
            
for(int i=0;i<Recipient.Count;i++)
            {

                SendBuffer[i]
="RCPT TO:<" + Recipient[i].ToString() +">" + enter;

            }
            
if(!Dialog(SendBuffer,"收件人地址有誤"))
                
return false;

            SendBuffer
=new string[10];
            
for(int i=0;i<RecipientBCC.Count;i++)
            {

                SendBuffer[i]
="RCPT TO:<" + RecipientBCC[i].ToString() +">" + enter;

            }
            
if(!Dialog(SendBuffer,"密件收件人地址有誤"))
                
return false;

            SendBufferstr
="DATA" + enter;
            
if(!Dialog(SendBufferstr,""))
                
return false;

            SendBufferstr
="From:" + FromName + "<" + From +">" +enter;

            
if(ReplyTo.Trim()!="")
            {
                SendBufferstr 
+= "Reply-To: " + ReplyTo + enter;
            }

            SendBufferstr 
+= "To:" + RecipientName + "<" + Recipient[0+">" +enter;
            SendBufferstr 
+= "CC:";
            
for(int i=1;i<Recipient.Count;i++)
            {
                SendBufferstr 
+= Recipient[i].ToString() + "<" + Recipient[i].ToString() +">,";
            }
            SendBufferstr 
+= enter;


            
if(Charset=="")
            {
                SendBufferstr 
+= "Subject:" + Subject + enter;
            }
            
else
            {
                SendBufferstr 
+= "Subject:" + "=?" + Charset.ToUpper() + "?B?" + Base64Encode(Subject) +"?=" +enter;
            }

            SendBufferstr 
+= "X-Priority:" + priority + enter;
            SendBufferstr 
+= "X-MSMail-Priority:" + priority + enter;
            SendBufferstr 
+= "Importance:" + priority + enter;
            SendBufferstr 
+= "X-Mailer: Huolx.Pubclass" + enter;
            SendBufferstr 
+= "MIME-Version: 1.0" + enter;

            
if(Html)
            {
                SendBufferstr 
+= "Content-Type: text/html;" + enter;
            }
            
else
            {
                SendBufferstr 
+= "Content-Type: text/plain;" + enter;
            }

            
if(Charset=="")
            {
                SendBufferstr 
+= "    charset="iso-8859-1"" + enter;
            }
            
else
            {
                SendBufferstr 
+= "    charset="" + Charset.ToLower() + """ + enter;
            }

            SendBufferstr 
+= "Content-Transfer-Encoding: base64" + enter;

            SendBufferstr 
+=  enter + enter;
            SendBufferstr 
+=  Base64Encode(Body) + enter;
            SendBufferstr 
+= enter + "." + enter;

            
if(!Dialog(SendBufferstr,"錯誤信件信息"))
                
return false;


            SendBufferstr
="QUIT" + enter;
            
if(!Dialog(SendBufferstr,"斷開連接時錯誤"))
                
return false;


            ns.Close();
            tc.Close();
            
return true;
        }


        
/// <summary>
        
/// 發送郵件方法,所有參數均通過屬性設置。
        
/// </summary>
        
/// <example>
        
/// <code>
        
/// <![CDATA[
        /// using System;
        
/// using System.Data;
        
/// using Seaskyer.Mail;
        
/// 
        
/// public class SendMail
        
/// {
        
///        public bool SendTest()
        
///        {
        
///            ESmtpMail ESM = new ESmtpMail();
        
///            
        
///            ESM.RecipientName = "test";//設定收件人姓名
        
///            ESM.AddRecipient("[email protected]");//設定收件人地址(必須填寫)。
        
///            ESM.AddRecipient("[email protected]");//再次使用AddRecipient就是抄送了,也可以直接傳入一個字符串數組,設定一組收件人。
        
///            
        
///            ESM.From        = "[email protected]";//設定發件人地址(必須填寫)
        
///            ESM.FromName    = "怒容.Net";//設定發件人姓名
        
///            ESM.ReplyTo        = "[email protected]";//設定回覆郵件地址.
        
///            
        
///            ESM.Priority    = "Normal";//設定優先級,不過我實驗着好像沒啥用
        
///            ESM.Html        = true;//設定正文是否HTML格式。
        
///            ESM.Subject        = tbSubject.Text;//設定郵件主題
        
///            ESM.Body        = tbBody.Text;//設定郵件正文
        
///            ESM.MailDomain    = "smtp.163.com";
        
///            ESM.MailServerUserName="test";//設定SMTP驗證的用戶名
        
///            ESM.MailServerPassWord="test";//設定SMTP驗證的密碼
        
///            
        
///            return ESM.Send();
        
///        }
        
/// }
        
/// ]]>
        
/// </code>
        
/// </example>
        public bool Send()
        {
            
if(Recipient.Count == 0)
            {
                errmsg 
= "收件人列表不能爲空";
                
return false;
            }


            
if(RecipientName == "")
                RecipientName 
= Recipient[0].ToString();

            
if(mailserver.Trim() == "")
            {
                errmsg 
= "必須指定SMTP服務器";
                
return false;
            }

            
return SendEmail();
            
        }


        
/// <summary>
        
/// 發送郵件方法
        
/// </summary>
        
/// <param name="smtpserver">smtp服務器信息,如"username:[email protected]:25",也可去掉部分次要信息,如"www.smtpserver.com"</param>
        public bool Send(string smtpserver)
        {
            
            MailDomain 
= smtpserver;
            
return Send();
        }


        
/// <summary>
        
/// 發送郵件方法
        
/// </summary>
        
/// <param name="smtpserver">smtp服務器信息,如"username:[email protected]:25",也可去掉部分次要信息,如"www.smtpserver.com"</param>
        
/// <param name="from">發件人mail地址</param>
        
/// <param name="fromname">發件人姓名</param>
        
/// <param name="replyto">回覆郵件地址</param>
        
/// <param name="to">收件人地址</param>
        
/// <param name="toname">收件人姓名</param>
        
/// <param name="html">是否HTML郵件</param>
        
/// <param name="subject">郵件主題</param>
        
/// <param name="body">郵件正文</param>
        
/// <remarks>11</remarks>
        
/// <returns>bool</returns>
        public bool Send(    string    smtpserver,
                            
string    from,
                            
string    fromname,
                            
string    replyto,
                            
string    to,
                            
string    toname,
                            
bool    html,
                            
string    subject,
                            
string    body )
        {
            MailDomain
=smtpserver;
            From
=from;
            FromName
=fromname;
            ReplyTo
=replyto;
            AddRecipient(to);
            RecipientName
=toname;
            Html
=html;
            Subject
=subject;
            Body
=body;
            
return Send();
        }
    }
}
 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章