前幾天學生問怎樣用C#發送電子郵件,網上文章很多,隨手找了一篇,給學生,讓他自己去看下。結果,搞了一天沒有搞定,只好來仔細看一下。用C#發送電子郵件,網上介紹的很多文章都是使用SmtpClient,也有System.Web.Mail ,但是,System.Web.Mail 已經是不推薦使用的了。以下是在網上常見的一種發送電子郵件的代碼:
1 MailMessage MyEmilMessage=new MailMessage();
2 string attachFile; //用於構造附件的字符串變量
3
4 MyEmailMessage.From="[email protected]";
5 MyEmailMessage.To="[email protected];[email protected]";
6 MyEmailMessage.Subject="郵件發送的一個簡單例子";
7 MyEmailMessage.body="貓王呼叫耗子,收到請回答!!!";
8 MyEmailMessage.BodyFormat=MailFormat.Text;
9 MyEmailMessage.Priority=MailPriority.High;
10
11 //構造添加附件
12 attachFile=@"D:\test\test.txt";
13 MailAttachment mailAttach=new MailAttachment(attachFile);
14 MyEmailMessage.Attachments.Add(mailAttach);
15
16 //發送電子郵件
17 SmtpMail.SmtpServer="發送電子郵件的SMTP地址或者IP";// 指定smtp服務器
18 SmtpMail.Send(MyEmailMessage);//發送電子郵件
19
這些代碼基本上都沒有任何錯誤,編譯也都會通過,但是,如果使用這種方式發送,基本上可以保證,你的電子郵件發送不成功。然後,這裡是缺少身份驗證,而且比較麻煩就是這個身份驗證。下面是我給學生寫的一個示例:
1 string mailContent="郵件內容"; 2 3 MailMessage msg = new System.Net.Mail.MailMessage(); 4 msg.To.Add("******@gmail.com"); //收件人 5 6 //發件人信息 7 msg.From = new MailAddress("*****@gmail.com", "發送人姓名", System.Text.Encoding.UTF8); 8 msg.Subject = "這是測試郵件"; //郵件標題 9 msg.SubjectEncoding = System.Text.Encoding.UTF8; //標題編碼 10 msg.Body = mailContent; //郵件主體 11 msg.BodyEncoding = System.Text.Encoding.UTF8; 12 msg.IsBodyHtml = true; //是否HTML 13 msg.Priority = MailPriority.High; //優先級 14 15 SmtpClient client = new SmtpClient(); 16 //設置GMail郵箱和密碼 17 client.Credentials = new System.Net.NetworkCredential("帳號@gmail.com", "密碼"); 18 client.Port = 587; 19 client.Host = "smtp.gmail.com"; 20 client.EnableSsl = true; 21 object userState = msg; 22 try 23 { 24 client.Send(msg); 25 MessageBox.Show("發送成功"); 26 } 27 catch (Exception ex) 28 { 29 MessageBox.Show(ex.Message, "發送郵件出錯"); 30 } 31
這裡的重點是郵箱身份驗證那個地方,一定不能寫錯,否則,郵件發送不出去。到這裡,似乎是大功告成了,但是,你會發現,相同的程序,在某些機器上可以發送成功,在某些機器上發送總是失敗,是系統的原因?似乎不是,因為相同的系統,也是有的發送成功,有的發送失敗。那是,框架的原因?似乎也不是。
這裡就有一個很令人迷惑的現象出現,同樣的系統,同樣的框架,還是有的能發送成功,有的發送失敗。失敗的具體原因說是郵件標頭編碼有錯誤。那麼,我們去掉Subject,不寫,用默認的可以嗎?也是一樣的。這個問題很見鬼,於是使用EtherPeek進行抓包,發現了一個有趣的現象,這裡有一個很重要的包:
這裡要注意的是紅色劃線的地方,“EHLO xqxPC”,我的機器名就是xqxPC,問題就在這裡啦,SmtpClient發送電子郵件的時候,需要發送一條EHLO指令到郵件服務器,參數是機器名,如果機器名使用中文,就發送不成功了。
簡單總結一下:
1、使用SmtpClient發送電子郵件是很簡單的,只要正確創建了MailMessage對象和SmtpClient就可以很容易的發送出去電子郵件。
2、如果電子郵件服務器需要身份驗證【似乎現在都需要身份驗證,除非自己配置的】,注意下面這句話:
smtpClient.Credentials = new System.Net.NetworkCredential("帳號@gmail.com", "密碼");
3、機器名不能使用中文。