如何使用MailKit获取非文本非附件内容?

问题描述

我们有一个系统,可以通过发送到OutLook365地址的电子邮件接收数据,还有一个POP3 / IMAP客户端,可以读取这些电子邮件并处理内容

我们正在.NET中工作,并且正在使用MailKit来检索电子邮件

我们正在做的事情的症结所在:

MailKit.Net.Pop3.Pop3Client client = constructClient();

for (var i = 0; i < client?.Count ?? 0; i++)
{
    MimeMessage message = client.GetMessage(i);

    var attachments = new List<OurAttachmentObject>();

    foreach (MimeEntity mimeEntity in message.Attachments)
    {
        attachments.Add(constructOurAttachmentObj(mimeEntity);
    }

    var messageMessageId = message.MessageId;
    var messageHtmlBody = message.HtmlBody;
    var messageTextBody = message.TextBody;

    doSomething(messageMessageId,messageHtmlBody,messageTextBody,attachments);
}

这就是问题-我们有一位客户的电子邮件结尾为空:

  • MimeMessage.HtmlBody为空,并且
  • MimeMessage.TextBody为空,并且
  • MimeMessage.Attachments为空。

我们的代码将处理附件。或TextBody或HtmlBody。但我们希望其中至少有一个

奇怪的是,这只会在他们向我们发送电子邮件时发生。当我们在Outlook中复制电子邮件时,可以再次发送它,它可以正常工作。当我们发送内容相同的电子邮件时,它会起作用。只有当他们发送电子邮件时,我们才会遇到此问题。

他们发送的内容

Received: from [...]
From:  [...]
To:  [...]
Date:  [...]
Subject:  [...]
Message-ID:  [...]
X-Mailer: [...]
Content-Type: Text/XML; name=theirfilename.xml; charset=ISO-8859-1
Content-transfer-encoding: 8bit
[...]
MIME-Version: 1.0

<?xml version="1.0"?>
<TheirXmlElement>
  [...]
</TheirXmlElement>

.

是的,电子邮件的正文是XML。

当我们在Outlook365中查看它时,XML会显示为附件,而当我们在Outlook中复制电子邮件时,它会以附件的形式出现:

Received: [...]
From: [...]
To: [...]
Subject: [...]
Thread-Topic: [...]
Thread-Index: [...]
[...]
Content-Type: multipart/mixed;
  boundary="_002_20201109124249401C297454xxxxx_"
MIME-Version: 1.0

--_002_20201109124249401C297454xxxxx_--
Content-Type: text/plain; charset="us-ascii"


--_002_20201109124249401C297454xxxxx_--
Content-Type: text/xml; name="theirfilename.xml"
Content-Description: theirfilename.xml
Content-disposition: attachment;
  filename="theirfilename.xml"; size=11788;
  creation-date="Mon,09 Nov 2020 19:42:56 GMT";
  modification-date="Mon,09 Nov 2020 19:42:56 GMT"
Content-ID: <F4B1CA23B7E98F49BCD9AC9B82024AF1@namprd17.prod.outlook.com>
Content-transfer-encoding: base64

PD94bWwgdmVyc2lvbj0ims4wIj8+DQo8TmV3RGF0YVNldD4NCiAgPGRlbGl2ZXJ5Pg0KICAgIDxj
[...]
M24NCiAgICA8L3ByaW50YWJsZV90ZXh0Pg0KICA8L3RpY2tldHM+DQo8L05ld0RhdGFTZXQ+DQoN
Cg==

--_002_20201109124249401C297454xxxxx_--
.

我们的代码可以很好地处理附件。

当我们通过将XML内容粘贴到普通电子邮件中进行测试时,收到的信息是:

Received: [...]
From: [...]
To: [...]
Subject: [...]
Thread-Topic: [...]
Thread-Index: [...]
[...]
Content-Type: text/plain; charset="us-ascii"
MIME-Version: 1.0

<?xml version="1.0"?>
<TheirXmlElement>
  [...]
</TheirXmlElement>

.

显示在MimeMessage.TextBody中,我们的代码也可以很好地处理

问题似乎是因为Content-Type是Text / XML,所以正文没有被放置在MimeMessage.TextBody中,但是也没有被视为附件。尽管OutLook会在复制消息时完全做到这一点。

我在调试时发现的是,当我们收到他们的票证之一时,其中MimeMessage.TextBody为null,MimeMessage.HtmlBody为null,MimeMessage.Attachments为空,我可以检索到电子邮件地址:

messageTextBody = message.Body.ToString();

但是那让我担心。 MimeMessage.Body是一个MimeEntity,我不希望.ToString()一直在工作。

如果不是文本,html或附件,MimeKit如何期望客户提取电子邮件的正文?

解决方法

TextBodyHtmlBodyAttachments属性仅在方便普通消息结构时使用。

您需要做的就是遍历MIME消息正文的树结构。

这一切都在常见问题解答中说明:https://github.com/jstedfast/MailKit/blob/master/FAQ.md#q-how-can-i-get-the-main-body-of-a-message

在您的特定情况下,您可能会退回至此:

var body = message.BodyParts.OfType<TextPart>().FirstOrDefault();
var text = body.Text;

P.S。您绝对应该使用message.Body.ToString()