最近有個地方用到正文帶圖片的郵件傳送功能,由於傳送郵件呼叫的是web service,要求正文必須是string,而接收方要能看到圖片,還不能單純的新增一個圖片地址連結,查閱了很多資料,基本上都是從頭寫郵件傳送類,以附件的形式上傳圖片然後替換這麼個思路,不適合我目前的需求。思考了很久:不管是圖片也好,文字也好還是其他的什麼檔案,在網路上傳輸肯定都是資料流,無非是到了目的地資料流每一段解析的方式不同而已,那麼能不能將郵件傳送資料看成是一個資料流,文字和圖片都在裡面呢?
使用OUTLOOK傳送了一個帶圖片的郵件,收到之後另存MHT分析其程式碼:
發現帶圖片img標籤的src屬性後面是一大堆字元<img alt="" src="data:image/png;base64, SkZJRgABAQEAZA…" />,那這個"亂碼"肯定就是圖片了!
再次查閱了一些資料得知郵件在網路上傳輸一般都要通過base 64編碼,然後直接賦給src
Data URI scheme是在RFC2397中定義的,目的是將一些小的資料,直接嵌入到網頁中,從而不用再從外部檔案載入。在上面的Data URI中,data表示取得資料的協定名稱,image/png 是資料型別名稱,base64 是資料的編碼方法,逗號後面就是這個image/png檔案base64編碼後的資料。 |
這就好辦了,先實現將圖片轉換為"字串"替換到那個位置不就OK了?
base 64編碼方法:
Bitmap bmp = new Bitmap(Imagefilename); MemoryStream ms = new MemoryStream(); String strbaser64 = Convert.ToBase64String(arr); |
Imagefilename是圖片路徑
strbaser64是編碼後的字串
然後寫HTML郵件正文:
<BODY style="MARGIN: 10px"><DIV><IMG src="data:image/png;base64, SkZJRgABAQEAZA…"> </IMG></DIV></BODY> |
將轉換成為字串的圖片放到這個位置:下圖是我在163信箱做的實驗(注意要切換到HTML原始碼試圖下)
點選傳送,然後過去收:
發現已經還原成為圖片了,初步實驗成功。
然後再試試使用程式碼傳送,簡單傳送程式碼如下:
System.Net.Mail.SmtpClient client = new System.Net.Mail.SmtpClient("smtp.163.com"); client.UseDefaultCredentials = true;//設定為傳送認證訊息 client.Credentials = new System.Net.NetworkCredential("使用者名稱", "密碼");//認證訊息 System.Net.Mail.MailMessage mess = new System.Net.Mail.MailMessage(); mess.From = new System.Net.Mail.MailAddress("shiyeping@163.com", "發信人的名稱"); mess.To.Add(new System.Net.Mail.MailAddress("shiyeping@163.com", "收信人的名稱")); mess.Subject = "主題"; mess.IsBodyHtml = true; mess.Body = "HTML格式的正文"; try { client.Send(mess); MessageBox.Show("傳送成功完成"); } catch (Exception ex) { MessageBox.Show(ex.Message); } |
正文用變數表示如下:
string mailBody = "<BODY style=\"MARGIN: 10px\"><DIV><IMG src=\"data:image/png;base64,/9j/4AAQSkZ….WRN6iXizpJL//Z\"> </IMG></DIV></BODY> "; |
*注意轉義
傳送成功之後再去郵箱就可以看到圖片已經正常顯示出來了:
同樣道理,如果要在郵件正文裡面加一個視訊?FLASH 動畫?聲音?…?
我沒試,如果你有興趣可以試試,我只是推理!
附測試程式碼下載:點選下載