2017-09-04 73 views
2

我有一個腳本,通過HTML表格爲所有img標記(使用HtmlAgilityPack)循環。它轉換任何具有Base64格式值的src屬性,並將它們作爲鏈接資源添加到MailMessage對象(包裹在電子郵件中)。下面嵌入的圖像顯示爲壞

的是我的測試代碼:

mailMessage.Body = GetFormattedEntries(279); // this loads the HTML table from the DB - using ID 279 as my test 

AlternateView avHtml = AlternateView.CreateAlternateViewFromString(mailMessage.Body, null, MediaTypeNames.Text.Html); 

HtmlAgilityPack.HtmlDocument htmlDocument = new HtmlAgilityPack.HtmlDocument(); 
htmlDocument.LoadHtml(mailMessage.Body); 
var images = htmlDocument.DocumentNode.Descendants("img").ToList(); 


foreach (var image in images) 
{ 
    var src = image.Attributes["src"].Value; 
    var regex = new Regex(@"data:(?<mime>[\w/\-\.]+);(?<encoding>\w+),(?<data>.*)", RegexOptions.Compiled); 
    var match = regex.Match(src); 
    var mime = match.Groups["mime"].Value; 
    var encoding = match.Groups["encoding"].Value; 
    var data = match.Groups["data"].Value; 

    byte[] bytes = Convert.FromBase64String(data); 
    System.IO.MemoryStream embeddedMs = new System.IO.MemoryStream(bytes, 0, bytes.Length); 
    LinkedResource pic1 = new LinkedResource(embeddedMs, new System.Net.Mime.ContentType(mime)); 
    pic1.TransferEncoding = TransferEncoding.Base64; 
    pic1.ContentId = Guid.NewGuid().ToString(); 
    avHtml.LinkedResources.Add(pic1); 
    var newNode = image.CloneNode(true); 
    newNode.Attributes["src"].Value = string.Format("cid:{0}", pic1.ContentId); 
    image.ParentNode.ReplaceChild(newNode, image); 
} 


mailMessage.IsBodyHtml = true; 
mailMessage.Body = htmlDocument.DocumentNode.OuterHtml; 

mailMessage.AlternateViews.Add(avHtml); 

當客戶端收到的電子郵件中,HTML呈現,但被嵌入的圖像顯示爲一個破碎的圖像。 Base64圖像沒有損壞或格式不正確,因爲我已經通過將Base64保存到完全打開的本地文件進行測試。

我正在測試的電子郵件客戶端將顯示嵌入式圖像。這已啓用。

我也通過加載本地文件進行測試,將其轉換爲Base64圖像並使用類似的腳本來發送。這是完美的。

+0

你試過[轉換](https://codebeautify.org/base64-to-image-converter)輸出base64編碼?如果這有效,那麼電子郵件客戶端可能因爲安全原因而阻塞圖像,並且可能應該添加[作爲附件](https://stackoverflow.com/questions/4312687/how-to-embed-images-in-email ) –

+0

確保您的客戶端默認支持顯示嵌入式圖像。 https://stackoverflow.com/questions/16242489/send-a-base64-image-in-html-email – Navyseal

+0

謝謝大家,我剛剛更新了我的問題,概述了客戶端可以顯示嵌入式圖像 –

回答

0

我發現這個問題的其他人正在努力解決這個問題。創建替代視圖的順序是關鍵,因爲我在創建AlternativeView之前使用新的CID更新主體。這裏是我現在的作品更新來源:

mailMessage.Body = GetFormattedEntries(279); 
var picList = new List<LinkedResource>(); 


HtmlAgilityPack.HtmlDocument htmlDocument = new HtmlAgilityPack.HtmlDocument(); 
htmlDocument.LoadHtml(mailMessage.Body); 
var images = htmlDocument.DocumentNode.Descendants("img").ToList(); 

foreach (var image in images) 
{ 

    var src = image.Attributes["src"].Value; 
    var regex = new Regex(@"data:(?<mime>[\w/\-\.]+);(?<encoding>\w+),(?<data>.*)", RegexOptions.Compiled); 
    var match = regex.Match(src); 
    var mime = match.Groups["mime"].Value; 
    var encoding = match.Groups["encoding"].Value; 
    var data = match.Groups["data"].Value; 

    byte[] bytes = Convert.FromBase64String(data); 
    System.IO.MemoryStream embeddedMs = new System.IO.MemoryStream(bytes, 0, bytes.Length); 
    LinkedResource pic1 = new LinkedResource(embeddedMs, new System.Net.Mime.ContentType(mime)); 
    pic1.TransferEncoding = TransferEncoding.Base64; 
    pic1.ContentId = Guid.NewGuid().ToString(); 
    picList.Add(pic1); 
    var newNode = image.CloneNode(true); 
    newNode.Attributes.Remove(newNode.Attributes["class"]); 
    newNode.Attributes["src"].Value = string.Format("cid:{0}", pic1.ContentId); 
    image.ParentNode.ReplaceChild(newNode, image); 
} 


mailMessage.IsBodyHtml = true; 
mailMessage.Body = htmlDocument.DocumentNode.OuterHtml; 

AlternateView avHtml = AlternateView.CreateAlternateViewFromString(mailMessage.Body, null, MediaTypeNames.Text.Html); 

foreach (var pic in picList) 
    avHtml.LinkedResources.Add(pic); 


mailMessage.AlternateViews.Add(avHtml); 

mailMessage.SendMail();