gpt4 book ai didi

c# - 尝试在 MailKit 中获取文件夹时出现异常,但在首先枚举文件夹时却没有

转载 作者:行者123 更新时间:2023-12-04 07:35:19 25 4
gpt4 key购买 nike

我正在使用 MaikKit,并且正在尝试找出如何在 Jim 中获取邮件我在 Gmail 帐户中设置的文件夹。我尝试按如下方式枚举文件夹...

    private void GetFolders() {
using ImapClient client = new();
EmailAccount emailAccount = EmailAccountOptions.Value;
client.Connect(emailAccount.Server, emailAccount.Port, SecureSocketOptions.SslOnConnect);
client.Authenticate(emailAccount.UserName, emailAccount.Password);

foreach (FolderNamespace ns in client.PersonalNamespaces) {
IMailFolder folder = client.GetFolder(ns);
_msg += $"<br/>Ns: {ns.Path} / {folder.FullName}";
foreach (IMailFolder subfolder in folder.GetSubfolders()) {
_msg += $"<br/>&nbsp;&nbsp; {subfolder.FullName}";
}
}

try {
IMailFolder jim = client.GetFolder(new FolderNamespace('/', "Jim"));
jim.Open(FolderAccess.ReadOnly);
_msg += $"<br/>Got Jim, has {jim.Count} email(s)";
}
catch (Exception ex) {
_msg += $"<br/>Ex ({ex.GetType()}): {ex.Message}";
}
}
这显示了以下...
Ns: /
INBOX
Jim
[Gmail]

✔✔
Got Jim, has 1 email(s)
所以,看来我可以访问 Jim没有问题。因为这样做的目的是访问 Jim只是,不需要枚举。但是,当我删除它时,我得到了一个异常(exception)......
Ns: /
Ex (MailKit.FolderNotFoundException): The requested folder could not be found
经过一些试验和错误,我发现以下工作......
private void GetFolders() {
using ImapClient client = new();
EmailAccount emailAccount = EmailAccountOptions.Value;
client.Connect(emailAccount.Server, emailAccount.Port, SecureSocketOptions.SslOnConnect);
client.Authenticate(emailAccount.UserName, emailAccount.Password);

foreach (FolderNamespace ns in client.PersonalNamespaces) {
IMailFolder folder = client.GetFolder(ns);
var subs = folder.GetSubfolders();
}

try {
IMailFolder jim = client.GetFolder(new FolderNamespace('/', "Jim"));
jim.Open(FolderAccess.ReadOnly);
_msg += $"<br/>Got Jim, has {jim.Count} email(s)";
}
catch (Exception ex) {
_msg += $"<br/>Ex ({ex.GetType()}): {ex.Message}";
}
}
...但是如果我取消对 folder.GetSubfolders() 的调用它引发异常。
如果我更改代码以查找 INBOX反而...
IMailFolder jim = client.GetFolder(new FolderNamespace('/', "INBOX"));
...那么即使没有调用 folder.GetSubfolders() 也可以正常工作.
有人知道为什么会这样吗?据我所知, foreach循环没有做任何会影响 Jim 的事情.

最佳答案

很清楚,使用 ImapClient.GetFolder (FolderNamespace)您使用它的方式不是使用该 API 的正确方式。
使用 MailKit 时要考虑的一些通用 API 规则:

  • 全部 需要网络 I/O 的 API 采用 CancellationToken争论。因此,如果 *Client 或 *Folder API 不采用 CancellationToken ,这意味着它是缓存查找或其他不需要访问网络的东西。
  • MailKit API 不需要您调用构造函数来将字符串传递给方法;-)

  • ImapClient.GetFolder(FolderNamespace) API,有一个等价的 ImapFolder.GetFolder(string path, CancellationToken)用于此类任务的 API。
    (注意: FolderNamespace .ctor 是公开的唯一原因是因为有人可能想要实现 MailKit IMailStoreIImapClient 接口(interface)并且需要能够创建 FolderNamespace 实例)。
    也就是说,我不愿意推荐这个 API,因为 MailKit 的 ImapFolder旨在通过 ImapFolder.GetSubfolders() 一次获取 1 级文件夹和/或 ImapFolder.GetSubfolder() API 等 ImapClient.GetFolder() API 是一个巨大的 hack,它必须递归地获取文件夹路径并将它们串在一起。
    请记住 ImapFolder实例有 ParentFolder MailKit API 保证将始终设置的属性。
    这使得很难保证开发人员是否可以在树中的任何位置请求随机文件夹 ImapClient。水平使用完整路径。
    无论如何...是的, Imapclient.GetFolder (string path, CancellationToken) API 存在并且它可以工作,如果你愿意,你可以使用它,但要知道我讨厌那个 API。
    好的,现在谈谈为什么你的 client.GetFolder(new FolderNamespace(...))如果您删除对 GetSubfolders() 的调用,hack 将不起作用
    正如您所发现的, IMailFolder jim = client.GetFolder(new FolderNamespace('/', "Jim"));仅当调用如 var subs = folder.GetSubfolders(); 时才有效在它恰好返回 /Jim 之前存在文件夹作为子文件夹之一。
    你的问题是:为什么?
    (或者你的问题是:为什么没有那条线它不起作用?)
    无论哪种方式,答案都是一样的。
    MailKit 的 ImapClient 会缓存 IMAP 文件夹树中存在的已知文件夹,以便它可以快速轻松地找到每个文件夹的父文件夹,而不必显式调用 LIST在路径中的每个父节点上,以构建 ImapFolder链(记住:每个 ImapFolder 都有一个 ParentFolder 属性,它指向一个 ImapFolder 实例,该实例表示其直接父级一直到根)。
    所以...那 GetSubfolders()调用正在添加 /Jim文件夹到缓存。
    由于 GetFolder (new FolderNamesdpace ('/', "Jim"))调用不能出网络,它依赖于内部缓存。连接后缓存中唯一存在的文件夹是 NAMESPACE 中返回的文件夹。命令和 INBOX .由于 LIST,其他所有内容都被添加到缓存中。响应(作为 GetSubfolders()GetSubfolder() 调用的结果)。

    关于c# - 尝试在 MailKit 中获取文件夹时出现异常,但在首先枚举文件夹时却没有,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67776798/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com