【问题标题】:How to get nontext, non-attachment content with MailKit?如何使用 MailKit 获取非文本、非附件内容?
【发布时间】:2020-11-10 23:20:34
【问题描述】:

我们有一个系统,我们通过电子邮件接收发送到 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 为空,MimeMessage.HtmlBody 为空,MimeMessage.Attachments 为空,我可以检索到电子邮件:

messageTextBody = message.Body.ToString();

但这让我很担心。 MimeMessage.Body 是一个 MimeEntity,我不希望 .ToString() 一直在处理它。

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

【问题讨论】:

    标签: c# .net smtp mimekit


    【解决方案1】:

    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;
    

    附:你绝对应该不使用message.Body.ToString()。

    【讨论】:

    • 这行得通 - 除了包括尾随的“。”行,这会使结果无效 XML。因此,我将删除“”之后的所有内容。如果他们只是简单地对身体进行适当的 mime 包装会更容易。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-12-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多