I have a script that loops through a HTML table for all img tags (using HtmlAgilityPack). It converts any src attributes that have a value that is of a Base64 format, and adds them as a linked resource to a MailMessage object (wrapped within an email).
The below is my test code:
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);
When the email is received at the client, the HTML renders, however the embedded images show as a broken image. The Base64 images are not corrupted or malformed as I have tested by saving the Base64 to a local file, which opens perfectly.
The email client I am testing on will show embedded images. This has been enabled.
I have also tested by loading a local file, converting it to a Base64 image and using a similar script to the below to send. That works perfectly.