MailKit: How to download all attachments locally from a MimeMessage

≡放荡痞女 提交于 2020-01-24 13:52:25

问题


I have looked at other examples online, but I am unable to figure out how to download and store ALL the attachments from a MimeMessage object. I did look into the WriteTo(), but I could not get it to work. Also wondering whether attachments will be saved according to the original file name, and type inside the email. Here is what I have so far:

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
                }
            }
        }
    }
}

回答1:


This is all explained in the FAQ in the "How do I save attachments?" section.

Here is a fixed version of the code you posted in your question:

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);
                }
            }
        }
    }
}

A few notes:

  1. There's no need to check if client.IsConnected after authenticating. If it wasn't connected, it would have thrown an exception in the Authenticate() method. It would have thrown an exception in the Connect() method as well if it didn't succeed. There is no need to check the IsConnected state if you literally just called Connect() 2 lines up.
  2. Why are you checking inboxFolder.Unread if you don't even use it anywhere? If you just want to download unread messages, change your search to be SearchQuery.NotSeen which will give you only the message UIDs that have not been read.
  3. I removed your IMailFolder inboxFolder = client.GetFolder(Constant.InboxFolder); logic because you don't need it. If you are going to do the SEARCH using client.Inbox, then don't iterate over the results with a different folder object.


来源:https://stackoverflow.com/questions/43331004/mailkit-how-to-download-all-attachments-locally-from-a-mimemessage

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!