当我给自己发电子邮件时,示例mhtml文件(例如,从这里)的图像在Outlook中显示良好。但是,当我将Word文档转换为mht(Web档案)格式时,图像不会显示。如果我在浏览器中打开文件,图像显示良好,或者如果我附加mht文件并双击附件。但如果文件被内联在电子邮件中,那么我会得到红色的X框,上面写着"右键单击此处下载图片",如果我选择下载图片,那么"文件无法显示…"。。。可能已经移动了…"。
你知道为什么Word文档中转换为MHTML的图像不喜欢在电子邮件中内联显示吗?
MHTML文档是一个由多部分组成的MIME文档。文档的第一部分是HTML,并具有指向其他部分中图像的链接。问题是链接在内联电子邮件中不起作用,即使它们在浏览器中起作用。查看一些示例,您可以看到链接必须以"cid:"为前缀,并且"cid:"之后的部分必须在相应MIME部分的标头中具有Content-ID。
链接可以像"cid:image002.gif"一样简单,相应MIME部分中的内容ID为:
Content-ID: <image002.gif>
如果所有链接都以这种方式固定,则带有图像的html将在Outlook中内联显示。
如上所述,您使用内容ID将附件链接到电子邮件HTML正文中的图像标记。以下是打开MHT文件、调整链接和通过电子邮件发送结果的完整程序。
我有一个客户正在使用Word自动化服务将收到的电子邮件转换为MHT文件并发送电子邮件。问题是Outlook不太关心原始MHT,也没有内联图像。这是我的POC解决方案。我使用了MimeKit和MailKit(http://www.mimekit.net/)在代码中,Bouncy Castle C#API(http://www.bouncycastle.org/csharp/)以覆盖MailKit中的依赖项,以及开发人员的Antix SMTP服务器(http://antix.co.uk/Projects/SMTP-Server-For-Developers)在本地服务器上运行,以接收用于测试dev中代码的SMTP流量。下面是打开现有MHT文件并通过电子邮件发送嵌入图像的POC代码。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Threading.Tasks;
using MimeKit;
using MailKit;
using MimeKit.Utils;
namespace ConsoleApplication3
{
class Program
{
static void Main(string[] args)
{
MimeMessage messageMimeKit = MimeMessage.Load(@"c:test.mht");
var images = messageMimeKit.BodyParts.Where(x => x.ContentLocation.LocalPath.EndsWith("png"));
var bodyString = messageMimeKit.HtmlBody;
var builder = new BodyBuilder();
foreach (var item in images)
{
item.ContentId = MimeUtils.GenerateMessageId();
bodyString = bodyString.Replace(GetImageName(item), "cid:" + item.ContentId.ToString());
builder.LinkedResources.Add(item);
}
builder.HtmlBody = bodyString;
messageMimeKit.Body = builder.ToMessageBody();
messageMimeKit.From.Add(new MailboxAddress("from address", "NoReply_SharePoint2013Dev@smithmier.com"));
messageMimeKit.To.Add(new MailboxAddress("to address", "larry@smithmier.com"));
messageMimeKit.Subject = "Another subject line";
using (var client = new MailKit.Net.Smtp.SmtpClient())
{
client.Connect("localhost");
client.Send(messageMimeKit);
client.Disconnect(true);
}
}
private static string GetImageName(MimeEntity item)
{
return item.ContentLocation.Segments[item.ContentLocation.Segments.Count() - 2] +
item.ContentLocation.Segments[item.ContentLocation.Segments.Count() - 1];
}
}
}