【问题标题】:Creating GMail folders with Mailkit使用 Mailkit 创建 GMail 文件夹
【发布时间】:2016-03-15 22:40:15
【问题描述】:

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

        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 中),它应该在根文件夹中创建它们。但是,尝试在收件箱文件夹下创建文件夹并没有失败,它只是创建了一个名为“收件箱/文件夹名称”的标签。理想情况下,我希望创建此文件夹的任何尝试都失败,因此可以简单地在根目录上创建它。我想这是从 IMAP 到 GMail 标签系统的转换中的一个问题。

有没有办法阻止“收件箱/文件夹名称”标签,或者在创建它之前识别这个问题?或者有没有办法识别这是一个 gmail 服务器并为它实现一个特殊的子句?

下面是 CreateChildFolder 和 CreateFolderOnRoot 代码。

IMAPFolder 类

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

【问题讨论】:

    标签: email mailkit mimekit


    【解决方案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 只会在它存在的情况下得到它。

    【讨论】:

    • 识别文件夹不存在不是问题,唯一的问题是创建文件夹。我想要的逻辑是: - 获取收件箱文件夹下的文件夹。 - 如果不存在,请从根目录获取文件夹。 - 如果不存在,请在收件箱文件夹下创建文件夹。 - 如果这不能完成,请在根目录上创建它。问题是“尝试”在收件箱下创建文件夹时。使用真正的文件夹结构,它可以工作,但使用 gmail,它会创建一个“收件箱/标签”文件夹,而不是失败。
    • 哦,那么,解决这个问题的唯一方法就是在你的代码中使用特定于 GMail 的逻辑来处理这种情况。
    猜你喜欢
    • 2016-02-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-12-24
    • 2023-03-08
    • 2018-12-07
    • 2015-01-29
    相关资源
    最近更新 更多