2017-04-10 43 views
1

我已经在线查看了其他示例,但我无法弄清楚如何从MimeMessage对象下载和存储所有附件。 我看过WriteTo(),但我无法让它工作。 也想知道附件是否会根据原始文件名保存,并在电子邮件中输入。 以下是我迄今为止:“我如何保存附件”MailKit:如何从MimeMessage本地下载所有附件

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

您需要对文件名进行一些清理。检查傻瓜,删除不好的字符... – Max

回答

2

这是所有在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.ContentObject.DecodeTo (stream); 
       } 
      } 
     } 
    } 
} 

的几个注意事项:

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