问题描述
我们有一个系统,可以通过发送到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如何期望客户提取电子邮件的正文?
解决方法
TextBody
,HtmlBody
和Attachments
属性仅在方便普通消息结构时使用。
您需要做的就是遍历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()
。