使用Mailkit创建GMail文件夹

时间:2016-03-15 22:40:16

标签: email mailkit mimekit

我有一个使用Mailkit的SMTP和IMAP的电子邮件提供商。我目前使用的主要功能是从收件箱中读取邮件,根据电子邮件的内容,它们将进入“已处理”或“已忽略”文件夹。在我们与Exchange一起使用的现有系统中,这些文件夹作为收件箱的子文件夹存在。如果文件夹不存在,则会创建它们。下面是一个示例代码段:

        var _inboxFolder = _provider.GetInboxFolder();
        var folder = _inboxFolder.GetChildFolder(folderName);
        if (folder == null)
        {
            // If Gmail, Inbox does not allow children. Check for folder in root.
            folder = _provider.GetFolder(folderName);
        }
        if (folder == null)
        {
            // Create new folder under Inbox
            folder = _inboxFolder.CreateChildFolder(folderName);
            if (folder == null)
            {
                // Cannot create under Inbox, create on root
                folder = _provider.CreateFolderOnRoot(folderName);
            }
        }

这些都使用我自己的提供程序,它基于我们用于其他提供程序的接口,因此存在一些对其他提供程序有意义的“奇怪”逻辑。 GetInboxFolder和GetFolder返回一个文件夹,但如果找不到,则返回null。这适用于所有提供商 - 如果文件夹不存在,则可以创建它们。

创建文件夹时出现问题。如果找不到文件夹,则应在“收件箱”文件夹下创建它们。如果这不可能发生(例如在Gmail中),它应该在根文件夹上创建它们。但是,尝试在“收件箱”文件夹下创建文件夹不会失败,它只会创建一个名为“INBOX / FolderName”的标签。理想情况下,我想尝试创建此文件夹失败,因此可以简单地在根目录上创建它。我想这是从IMAP到GMail标签系统的转换中的一个问题。

有没有办法阻止“INBOX / FolderName”标签,或在创建之前识别此问题?或者有没有办法确定这是一个gmail服务器并为它实现一个特殊条款?

有一些额外的信息,CreateChildFolder和CreateFolderOnRoot代码如下。

IMAPFolder Class

    public IEmailFolder CreateChildFolder(string displayName)
    {
        if (_imapClient == null || !_imapClient.IsConnected)
        {
            throw new NotLoggedInException();
        }

        return new ImapFolder(_folder.Create(displayName, true), _imapClient);
    }

IMAPClient类

    public IEmailFolder CreateFolderOnRoot(string displayName)
    {
        if (_client == null)
        {
            throw new NotLoggedInException();
        }

        try
        {
            var toplevel = _client.GetFolder(_client.PersonalNamespaces[0]);
            var mailkit = toplevel.Create(displayName, true);
            return new ImapFolder(mailkit, _client);
        }
        catch (Exception exception)
        {
            throw new LoadFolderFailedException(exception);
        }
    }

1 个答案:

答案 0 :(得分:1)

GMail"标签系统"是GMail如何实现文件夹。他们没有实现物理文件夹,他们所做的是"虚拟"文件夹只是用户定义的标签,文件夹只是对所有已应用标签的邮件的查询。

也就是说,GMail根命名空间是string.Empty。有些IMAP服务器的根命名空间为"INBOX"(例如Courier IMAP,我认为)。

您的CreateFolderOnRoot方法应该在GMail的根目录下创建一个文件夹,它不会在INBOX下创建它,所以您的问题非常混乱。

如果要在INBOX下添加文件夹,只需使用client.Inbox.Create (displayName, true);

即可
  

创建文件夹时出现问题。如果找不到文件夹,则应在“收件箱”文件夹下创建它们。

这让我觉得你真正想做的是:

try {
    var toplevel = _client.GetFolder(_client.PersonalNamespaces[0]);
    var mailkit = folder.GetSubfolder(displayName);
    return new ImapFolder(mailkit, _client);
} catch (Exception ex) {
    throw new LoadFolderFailedException(ex);
}

请注意使用GetSubfolder而不是CreateCreate将始终创建该文件夹。 GetSubfolder只有在存在的情况下才能获得。