当多个子文件夹用斜杠等分隔在一个字符串中时,如何在 MailKit 中创建(或获取)具有多个子文件夹的文件夹?

问题描述 投票:0回答:1

我使用 MailKit 创建文件夹。这很简单,我可以例如在父文件夹上调用

CreateFolderAsync
(如果我想以异步方式)。

    public async Task<IMailFolder> GetOrCreateFolder(string folderName)
    {
        var rootFolder = await authenticatedClient.GetFolderAsync(imapClient.PersonalNamespaces[0].Path);
        var existingFolders = await rootFolder.GetSubfoldersAsync();
        var matchingFolder = existingFolders.FirstOrDefault(folder => folder.FullName == folderName);

        if (matchingFolder == null)
        {
            matchingFolder = await rootFolder.CreateAsync(folderName, true);
        }

        return matchingFolder;
    }

但是,如果我传入像

GetOrCreateFolder("folder/subfolder")
GetOrCreateFolder("folder.subfolder")
这样的字符串(因为我后来发现许多 IMAP 服务器显然使用
.
作为目录分隔符。这是由服务器在
IMailFolder.DirectorySeparator
中定义/返回的)
例如)。

如果您尝试这样做,两者都会抛出异常(“该名称不是合法的文件夹名称”):

System.ArgumentException
  HResult=0x80070057
  Nachricht = The name is not a legal folder name. Arg_ParamName_Name
  Quelle = MailKit
  Stapelüberwachung:
   bei MailKit.Net.Imap.ImapFolder.QueueCreateCommand(String name, Boolean isMessageFolder, CancellationToken cancellationToken, String& encodedName)
   bei MailKit.Net.Imap.ImapFolder.CreateAsync(String name, Boolean isMessageFolder, CancellationToken cancellationToken)
   // ...

  Diese Ausnahme wurde ursprünglich von dieser Aufrufliste ausgelöst:
    MailKit.Net.Imap.ImapFolder.QueueCreateCommand(string, bool, System.Threading.CancellationToken, out string)
    MailKit.Net.Imap.ImapFolder.CreateAsync(string, bool, System.Threading.CancellationToken)

您显然可以硬编码创建第一个文件夹,然后是第二个文件夹,但这确实一点也不灵活。 我的意思是,毕竟,

mkdir
在 Linux 上,例如还支持创建多个文件夹一次,为什么我们不能在这里呢?

那么,我怎样才能完成这项工作呢?

directory imap mailkit
1个回答
0
投票

实际上,我有一个答案,我只是“递归地”创建这样一个目录: private const char directorySeparator = '/'; /// <summary> /// Gets a folder or sub-folder (recursively). If needed, the folder(s) is/are automatically created. /// </summary> /// <param name="folderPath">The full path of the folder to create, separated by slashes (<see cref="directorySeparator"/>).</param> /// <returns>A task representing the asynchronous operation.</returns> public async Task<IMailFolder> GetOrCreateFolder(string folderPath) { var rootFolder = await imapClient.GetFolderAsync(imapClient.PersonalNamespaces[0].Path); return await GetOrCreateFolderRecursiveAsync(rootFolder, folderPath); } private async Task<IMailFolder> GetOrCreateFolderRecursiveAsync(IMailFolder parentFolder, string folderPath) { if (string.IsNullOrEmpty(folderPath) || folderPath == ".") return parentFolder; var (currentFolderName, remainingPath) = SplitCurrentFolderAndRemainingPath(folderPath, [directorySeparator, parentFolder.DirectorySeparator]); var existingFolders = await parentFolder.GetSubfoldersAsync(); var matchingFolder = existingFolders.FirstOrDefault(folder => folder.Name.Equals(currentFolderName, StringComparison.OrdinalIgnoreCase)); if (matchingFolder == null) { logger.LogInformation($"Creating folder {currentFolderName} under {parentFolder.FullName}."); matchingFolder = await parentFolder.CreateAsync(currentFolderName, true); } return await GetOrCreateFolderRecursiveAsync(matchingFolder, remainingPath); } private static (string currentFolderName, string remainingPath) SplitCurrentFolderAndRemainingPath(string folderPath, char[] separator) { var parts = folderPath.Split(separator, 2, StringSplitOptions.RemoveEmptyEntries); var currentFolderName = parts[0]; var remainingPath = parts.Length > 1 ? parts[1] : string.Empty; return (currentFolderName, remainingPath); }

它只是假设你有一个已经经过身份验证的 
imapClient

又名

ImapClient
当然。
logger
也是可选的。
它允许 

/

作为硬编码的目录分隔符或来自服务器的

IMailFolder.DirectorySeparator
,我之前已经提到过。 AFAIK,通常是一个
.
又名点。 AFAIK 如果
IMailFolder.DirectorySeparator
出现在您的文件夹中,服务器无论如何都会拒绝它,如上所示,因此在这里拆分它并没有什么坏处。
我只实现了异步方式,因为这就是我使用的方式,但显然,同步方式是等效的。

© www.soinside.com 2019 - 2024. All rights reserved.