我给自己发了一封测试邮件,邮件正文中有一张图片。此图像不是附件,只是粘贴到电子邮件正文中。
我正在使用 MailKit 阅读这封收到的电子邮件,但找不到如何访问该图像。
我正在使用:
MimeMessage message = client.Inbox.GetMessage(uid);
如果我使用 message.ToString(),我可以看到它在那里:
...
Content-Disposition: inline; filename="image001.png"; size=4570;
creation-date="Mon, 16 Sep 2019 09:21:07 GMT";
modification-date="Mon, 16 Sep 2019 09:21:07 GMT"
Content-ID: <image001.png@01D56A4B.7CD234E0>
Content-Transfer-Encoding: base64
iVBORw0KGgoAAAANSUhEUgAAAJUAAAAlCAY...
我假设 base64 编码的行是实际图像,但我该如何获取它?
编辑
这是我的测试代码:
static void Main(string[] args)
{
ImapClient client = new ImapClient();
client.Connect("...
client.Authenticate("...
client.Inbox.Open(FolderAccess.ReadWrite);
IList<UniqueId> uids = client.Inbox.Search(SearchQuery.All);
foreach (UniqueId uid in uids)
{
MimeMessage message = client.Inbox.GetMessage(uid);
IList<IMessageSummary> info = client.Inbox.Fetch(new[] { uid }, MessageSummaryItems.All);
foreach (MimeEntity me in message.Attachments)
HandleMimeEntity(me, 1);
}
client.Disconnect(true);
}
static void HandleMimeEntity(MimeEntity entity)
{
int i, j;
Multipart multipart = entity as Multipart;
if (multipart != null)
{
Console.WriteLine("multipart");
for (i = 0; i < multipart.Count; i++)
{
Console.WriteLine(i + " - " + multipart[i].ContentType.MimeType + " (" + multipart[i].IsAttachment + ")");
HandleMimeEntity(multipart[i]);
}
return;
}
MessagePart rfc822 = entity as MessagePart;
if (rfc822 != null)
{
MimeMessage message = rfc822.Message;
Console.WriteLine("mimemessage - " + message.Subject);
HandleMimeEntity(message.Body, lvl + 1);
return;
}
MimePart part = (MimePart)entity;
Console.WriteLine("mimepart - " + part.FileName);
// do something with the MimePart, such as save content to disk
}
请您参考如下方法:
我真的,真的,真的推荐阅读 FAQ和/或 README了解 MIME 的结构,以便对此类问题的回答变得显而易见,但与此同时......
让我们从理解 MIME 是一个树结构开始,这意味着有一个根节点(可能是也可能不是叶节点),可以有分支节点(例如。multipart/mixed、multipart/alternative、multipart/related 等),还有叶节点(例如 text/plain、text/html, image/jpeg, application/octet-stream 等)。
MIME 结构的根节点是MimeMessage.Body属性(property)。
如果消息仅包含一个 text/plain MIME 实体,则 MimeMessage.Body 节点将 text/普通 MIME 实体。
在您的情况下,听起来您至少有一个 text/html 实体和一个 image/png 实体。
由于对消息的结构一无所知,我们可以得出结论,MimeMessage.Body 不是 text/html 实体,也不是 image/png 实体,因为您只能有 1 个根节点,并且 text/* 和 image/* 部分是叶节点实体,而不是分支节点实体。
这意味着 MimeMessage.Body 将是一个 multipart/*,由 Multipart 表示(或其子类)。
由于很明显您的情况下的 MimeMessage.Body 是一个 Multipart,我们可以将其转换为:
var multipart = (Multipart) message.Body;
一旦我们有了multipart,我们就可以遍历它的 child :
foreach (var child in multipart) {
// ...
}
此时我们需要弄清楚 child 是否是另一个Multipart,一个MimePart (将代表文本或图像数据)或嵌入消息(又名 MessagePart )。
您可以使用 as 转换来快速推断出它是什么。
然后您只需继续遍历 MIME 实体树,直到找到您正在寻找的内容,这可能需要使用上述方法进行一些递归。
MimeKit 有一些替代方法可以做到这一点,但是:
这是使用 BodyParts 属性快速解决问题的方法:
var myImage = message.BodyParts.OfType<MimePart> ().FirstOrDefault (x => x.IsMimeType ("image", "png"));
