【问题标题】:MailKit: How to download all attachments locally from a MimeMessageMailKit:如何从 MimeMessage 本地下载所有附件
【发布时间】:2017-04-10 19:00:48
【问题描述】:

我在网上查看了其他示例,但我无法弄清楚如何从 MimeMessage 对象下载和存储所有附件。 我确实查看了 WriteTo(),但我无法让它工作。 也想知道附件是否会按照原文件名保存,并在邮件中输入。 这是我目前所拥有的:

using (var client = new ImapClient())
{
    client.Connect(Constant.GoogleImapHost, Constant.ImapPort, SecureSocketOptions.SslOnConnect);
    client.AuthenticationMechanisms.Remove(Constant.GoogleOAuth);
    client.Authenticate(Constant.GoogleUserName, Constant.GenericPassword);

    if (client.IsConnected == true)
    {
        FolderAccess inboxAccess = client.Inbox.Open(FolderAccess.ReadWrite);
        IMailFolder inboxFolder = client.GetFolder(Constant.InboxFolder);
        IList<UniqueId> uids = client.Inbox.Search(SearchQuery.All);

        if (inboxFolder != null & inboxFolder.Unread > 0)
        {
            foreach (UniqueId msgId in uids)
            {
                MimeMessage message = inboxFolder.GetMessage(msgId);

                foreach (MimeEntity attachment in message.Attachments)
                {
                    //need to save all the attachments locally
                }
            }
        }
    }
}

【问题讨论】:

  • 您需要对文件名进行一些清理。检查欺骗,删除坏字符...

标签: c# imap mailkit mimekit


【解决方案1】:

这一切都在“如何保存附件?”中的FAQ 中进行了解释。部分。

这是您在问题中发布的代码的固定版本:

using (var client = new ImapClient ()) {
    client.Connect (Constant.GoogleImapHost, Constant.ImapPort, SecureSocketOptions.SslOnConnect);
    client.AuthenticationMechanisms.Remove (Constant.GoogleOAuth);
    client.Authenticate (Constant.GoogleUserName, Constant.GenericPassword);

    client.Inbox.Open (FolderAccess.ReadWrite);
    IList<UniqueId> uids = client.Inbox.Search (SearchQuery.All);

    foreach (UniqueId uid in uids) {
        MimeMessage message = client.Inbox.GetMessage (uid);

        foreach (MimeEntity attachment in message.Attachments) {
            var fileName = attachment.ContentDisposition?.FileName ?? attachment.ContentType.Name;

            using (var stream = File.Create (fileName)) {
                if (attachment is MessagePart) {
                    var rfc822 = (MessagePart) attachment;

                    rfc822.Message.WriteTo (stream);
                } else {
                    var part = (MimePart) attachment;

                    part.Content.DecodeTo (stream);
                }
            }
        }
    }
}

几点说明:

  1. 认证后无需检查client.IsConnected。如果它没有连接,它会在Authenticate() 方法中抛出异常。如果它没有成功,它也会在Connect() 方法中引发异常。如果您实际上只调用了Connect() 2 行,则无需检查IsConnected 状态。
  2. 如果您甚至没有在任何地方使用它,为什么还要检查inboxFolder.Unread?如果您只想下载未读邮件,请将搜索更改为 SearchQuery.NotSeen,这将只为您提供未读邮件 UID。
  3. 我删除了您的 IMailFolder inboxFolder = client.GetFolder(Constant.InboxFolder); 逻辑,因为您不需要它。如果您打算使用 client.Inbox 进行搜索,则不要使用不同的文件夹对象迭代结果。

【讨论】:

  • 这对 TnefPart (winmail.dat) 不起作用。参考:github.com/jstedfast/MimeKit/issues/234
  • 肯定会的。上面的代码将保存 winmail.dat 附件就好了。该错误报告与保存 winmail.dat 附件无关。
  • 只是向其他想要处理电子邮件附件的读者指出,他们也应该处理 winmail.dat tnef 结构。如果您不知道这一点,您可能会丢弃 winmail.dat,而重要文件可能驻留在其中。顺便说一句,感谢伟大的图书馆!
  • 只是想发表评论并说声谢谢,仍然感谢您一直以来。你的图书馆和辛勤工作真是太棒了!我希望我能给你更多的支持和感谢!
  • 我认为这是提出此问题的最佳地点 - 如果我们仅使用 BodyStructure 而不是 MimeMessage 获取 IMessageSummary,那么 Attachments 属性是否包含 @987654337 @ 你能打电话给ExtractAttachments() 吗?询问是因为我们有一个巨大的邮件消息,我们不想下载它,而是只获取它的 TNEF 部分并提取它。 (以及您的答案完全涵盖的其他非 TNEF 附件)
猜你喜欢
  • 2019-11-01
  • 2015-01-23
  • 2016-07-10
  • 2016-10-06
  • 2010-09-25
  • 2021-12-05
  • 2013-12-14
  • 2017-02-01
  • 1970-01-01
相关资源
最近更新 更多