MailKit:如何从MimeMessage本地下载所有附件

2 c# imap mailkit mimekit

我在网上查看了其他示例,但我无法弄清楚如何从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
                }
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

jst*_*ast 8

这些都在"如何保存附件?" 的常见问题解答中进行了解释.部分.

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

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);
                }
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

几点说明:

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