使用MailKit检查imap文件夹是否存在

时间:2018-08-02 00:03:57

标签: c# imap mailkit

我正在尝试将邮件移动到另一个文件夹,但是我找不到一种简单的方法来检查目标文件夹是否存在,我假设给定的文件夹路径是一个根文件夹,我可以尝试以下操作:

public void MoveMessages(Config accountInfo, List<int> uids, string 
   sourceFolderName, string targetFolderName)   
{
            ValidateAccountInfoConfiguration(accountInfo);
            using (var client = new ImapClient())
            {
                Authenticate(accountInfo, client);

                var sourceFolder = GetSourceFolder(sourceFolderName, client);
                sourceFolder.Open(FolderAccess.ReadWrite);
                var topLevelFolder = client.GetFolder(client.PersonalNamespaces[0]);
                var topFolders = topLevelFolder.GetSubfolders();
                var targetFolder = topFolders.FirstOrDefault(folder => folder.Name == targetFolderName);
                if (targetFolder == null)
                    targetFolder = topLevelFolder.Create(targetFolderName, true);
                var uidsToMove = GetUniqueIds(sourceFolder, SearchQuery.Seen).Where(uid => uids.Any(uidToMove => uidToMove == uid.Id)).ToList();
                sourceFolder.MoveTo(uidsToMove, targetFolder);
                sourceFolder.Expunge(uidsToMove);

            }
        }

在文档中,IMailFolder接口包含Exists属性,但是当我尝试使用IMailFolder.GetFolder(“ pathToFolder”)获取文件夹时,如果该文件夹不存在,则会抛出folderNotFound异常,因此我无法理解其用法遇有遗物,我错过了什么?还是我当前的实现是获取目标文件夹的正确方法?

2 个答案:

答案 0 :(得分:0)

您当前的实现是正确的方法。

Exists属性对于某些IMAP服务器非常有用,例如,这些IMAP服务器支持缺少直接父级的叶节点文件夹(这意味着父级文件夹将具有Exists == false)。

我仅在使用MailDir作为其存储格式的IMAP服务器上看到过这种情况,因为它创建文件夹的方式。

通常您有一棵这样的文件夹树:

toplevel
toplevel/sublevel
toplevel/sublevel/leaf-node

每个文件夹必须一直存在到树的下方。

但是MailDir不使用UNIX或DOS目录分隔符,它使用'.',因此您可以具有以下文件夹列表:

toplevel
toplevel.sublevel.leaf-node

在上面的示例中,没有toplevel.sublevel文件夹,但是它将出现在IMailFolder节点的树中……因此,需要有一个Exists属性。 / p>

答案 1 :(得分:0)

除了下载完整的文件夹列表之外,还有以下方法:

public async Task<bool> FolderExistsAsync(ImapClient c, string path) {
    try {
       await c.GetFolderAsync(path);
    } catch (FolderNotFoundException) {
        return false;
    }
    return true;
}

(尽管我不喜欢将try / catch块用于“正常”控制流)