将 .jpg 图像(base64 字符串表示)嵌入到电子邮件正文中 (System.Net.Mail)
Embedding .jpg image (base64 string representation) into email message body (System.Net.Mail)
我能够正确地将 jpg 图像转换为 base64String。但是我无法使用转换后的图像字符串和 LinkedResource 将其嵌入电子邮件正文中。该图像在电子邮件正文中显示为未找到图像图标。
任何帮助将不胜感激。
我已经按照 link 中的示例进行操作:
我正在使用 HtmlAgilityPack(nuget 包)通过以下代码定位 img 元素。
private string embedImageInMail(string html)
{
HtmlAgilityPack.HtmlDocument doc = new
HtmlAgilityPack.HtmlDocument();
doc.LoadHtml(html);
doc.DocumentNode.Descendants("img").Where(e =>
{
string src = e.GetAttributeValue("src", null) ?? "";
return !string.IsNullOrEmpty(src) && src.StartsWith("data:image");
})
.ToList()
.ForEach(x =>
{
string currentSrcValue = x.GetAttributeValue("src", null);
currentSrcValue = currentSrcValue.Split(',')[1]; //Base64 part of string
byte[] imageData = Convert.FromBase64String(currentSrcValue);
string contentId = Guid.NewGuid().ToString();
using (MemoryStream ms = new MemoryStream(imageData))
{
LinkedResource inline = new LinkedResource(ms, "image/jpeg");
inline.ContentId = contentId;
inline.TransferEncoding = System.Net.Mime.TransferEncoding.Base64;
x.SetAttributeValue("src", "cid:" + inline.ContentId);
}
});
return doc.DocumentNode.OuterHtml;
}
传递给函数的html参数包含一个img标签,其src等于图像的base64编码。
从此函数返回的内容将分配给电子邮件的 message.body。
已按照其他 post 中的解决方案解决。如果其他人正在尝试做同样的事情并且遇到了像我一样的麻烦,我将在下面 post 编写代码。
基本上我必须将 html 中的 LinkedResource(图像)保存到一个列表,然后遍历该列表并将所有图像添加到 foreach 循环之外的 AlternateView。
// Embeds image to properly show in Email. Image element to show in html will not work in Email body.
//
// XmlAgilityPack gets used here to parse html string.
List<LinkedResource> linkedResources = new List<LinkedResource>();
HtmlAgilityPack.HtmlDocument doc = new HtmlAgilityPack.HtmlDocument();
int increment = 0;
doc.LoadHtml(tempMsg);
doc.DocumentNode.Descendants("img").Where(z =>
{
string src = z.GetAttributeValue("src", null) ?? "";
return !string.IsNullOrEmpty(src) && src.StartsWith("data:image");
})
.ToList()
.ForEach(x =>
{
string currentSrcValue = x.GetAttributeValue("src", null);
currentSrcValue = currentSrcValue.Split(',')[1]; //Base64 part of string
byte[] imageData = Convert.FromBase64String(currentSrcValue);
string id = Guid.NewGuid().ToString();
increment++;
LinkedResource inlineImage = new LinkedResource(new MemoryStream(imageData), System.Net.Mime.MediaTypeNames.Image.Jpeg);
inlineImage.ContentType.Name = "img " + increment;
inlineImage.ContentId = id;
inlineImage.TransferEncoding = System.Net.Mime.TransferEncoding.Base64;
x.SetAttributeValue("src", "cid:" + inlineImage.ContentId);
linkedResources.Add(inlineImage);
});
// Append multiple images from template to email message.
//
// Write html to message.body
AlternateView altView = AlternateView.CreateAlternateViewFromString(doc.DocumentNode.OuterHtml, null, "text/html");
linkedResources.ForEach(x=>altView.LinkedResources.Add(x));
message.AlternateViews.Add(altView);
String[] attachments = txtAttachFiles.Text.Split(';');
foreach (String filename in attachments)
{
if (File.Exists(filename))
{
Attachment attachment = new Attachment(filename);
message.Attachments.Add(attachment);
}
}
// loop is set to 1 in the app.config file so technically this for loop is not needed, but will keep this loop just in case.
for (int loop = 0; loop < Convert.ToInt32(ConfigurationManager.AppSettings["loop"]); loop++)
{
SmtpClient smtp = new SmtpClient();
smtp.Host = ConfigurationManager.AppSettings["mailHost"];
smtp.Port = Int32.Parse(ConfigurationManager.AppSettings["mailPort"]);
smtp.UseDefaultCredentials = Convert.ToBoolean(ConfigurationManager.AppSettings["mailDefaultCredentials"]);
smtp.Send(message);
}
}
我能够正确地将 jpg 图像转换为 base64String。但是我无法使用转换后的图像字符串和 LinkedResource 将其嵌入电子邮件正文中。该图像在电子邮件正文中显示为未找到图像图标。 任何帮助将不胜感激。
我已经按照 link 中的示例进行操作:
我正在使用 HtmlAgilityPack(nuget 包)通过以下代码定位 img 元素。
private string embedImageInMail(string html)
{
HtmlAgilityPack.HtmlDocument doc = new
HtmlAgilityPack.HtmlDocument();
doc.LoadHtml(html);
doc.DocumentNode.Descendants("img").Where(e =>
{
string src = e.GetAttributeValue("src", null) ?? "";
return !string.IsNullOrEmpty(src) && src.StartsWith("data:image");
})
.ToList()
.ForEach(x =>
{
string currentSrcValue = x.GetAttributeValue("src", null);
currentSrcValue = currentSrcValue.Split(',')[1]; //Base64 part of string
byte[] imageData = Convert.FromBase64String(currentSrcValue);
string contentId = Guid.NewGuid().ToString();
using (MemoryStream ms = new MemoryStream(imageData))
{
LinkedResource inline = new LinkedResource(ms, "image/jpeg");
inline.ContentId = contentId;
inline.TransferEncoding = System.Net.Mime.TransferEncoding.Base64;
x.SetAttributeValue("src", "cid:" + inline.ContentId);
}
});
return doc.DocumentNode.OuterHtml;
}
传递给函数的html参数包含一个img标签,其src等于图像的base64编码。 从此函数返回的内容将分配给电子邮件的 message.body。
已按照其他 post 中的解决方案解决。如果其他人正在尝试做同样的事情并且遇到了像我一样的麻烦,我将在下面 post 编写代码。
基本上我必须将 html 中的 LinkedResource(图像)保存到一个列表,然后遍历该列表并将所有图像添加到 foreach 循环之外的 AlternateView。
// Embeds image to properly show in Email. Image element to show in html will not work in Email body.
//
// XmlAgilityPack gets used here to parse html string.
List<LinkedResource> linkedResources = new List<LinkedResource>();
HtmlAgilityPack.HtmlDocument doc = new HtmlAgilityPack.HtmlDocument();
int increment = 0;
doc.LoadHtml(tempMsg);
doc.DocumentNode.Descendants("img").Where(z =>
{
string src = z.GetAttributeValue("src", null) ?? "";
return !string.IsNullOrEmpty(src) && src.StartsWith("data:image");
})
.ToList()
.ForEach(x =>
{
string currentSrcValue = x.GetAttributeValue("src", null);
currentSrcValue = currentSrcValue.Split(',')[1]; //Base64 part of string
byte[] imageData = Convert.FromBase64String(currentSrcValue);
string id = Guid.NewGuid().ToString();
increment++;
LinkedResource inlineImage = new LinkedResource(new MemoryStream(imageData), System.Net.Mime.MediaTypeNames.Image.Jpeg);
inlineImage.ContentType.Name = "img " + increment;
inlineImage.ContentId = id;
inlineImage.TransferEncoding = System.Net.Mime.TransferEncoding.Base64;
x.SetAttributeValue("src", "cid:" + inlineImage.ContentId);
linkedResources.Add(inlineImage);
});
// Append multiple images from template to email message.
//
// Write html to message.body
AlternateView altView = AlternateView.CreateAlternateViewFromString(doc.DocumentNode.OuterHtml, null, "text/html");
linkedResources.ForEach(x=>altView.LinkedResources.Add(x));
message.AlternateViews.Add(altView);
String[] attachments = txtAttachFiles.Text.Split(';');
foreach (String filename in attachments)
{
if (File.Exists(filename))
{
Attachment attachment = new Attachment(filename);
message.Attachments.Add(attachment);
}
}
// loop is set to 1 in the app.config file so technically this for loop is not needed, but will keep this loop just in case.
for (int loop = 0; loop < Convert.ToInt32(ConfigurationManager.AppSettings["loop"]); loop++)
{
SmtpClient smtp = new SmtpClient();
smtp.Host = ConfigurationManager.AppSettings["mailHost"];
smtp.Port = Int32.Parse(ConfigurationManager.AppSettings["mailPort"]);
smtp.UseDefaultCredentials = Convert.ToBoolean(ConfigurationManager.AppSettings["mailDefaultCredentials"]);
smtp.Send(message);
}
}