Откройте почтовую папку в MailKit, когда нет пространств имен папок - PullRequest
1 голос
/ 09 января 2020

У нас возникла небольшая проблема на клиенте при попытке открыть почтовую папку, и ее не удалось найти, поэтому я создал следующий метод, чтобы изо всех сил найти пространство имен папки, в которой находилась папка почты.

private FolderNamespace FindFolderNamespace(ImapClient imapClient, string folderName)
{
    string[] folderNameParts = folderName.Split('/');

    FolderNamespaceCollection folderNamespaces = new FolderNamespaceCollection();
    foreach (FolderNamespace folderNamespace in imapClient.PersonalNamespaces) folderNamespaces.Add(folderNamespace);
    foreach (FolderNamespace folderNamespace in imapClient.SharedNamespaces) folderNamespaces.Add(folderNamespace);
    foreach (FolderNamespace folderNamespace in imapClient.OtherNamespaces) folderNamespaces.Add(folderNamespace);

    Dictionary<FolderNamespace, string> potentialFolderNamespaces = new Dictionary<FolderNamespace, string>();
    foreach (FolderNamespace folderNamespace in folderNamespaces)
    {
        IMailFolder mailFolder = imapClient.GetFolder(folderNamespace);
        foreach (string folderNamePart in folderNameParts)
        {
            if (mailFolder.GetSubfolders().Any(mf => mf.Name.Equals(folderNamePart, StringComparison.OrdinalIgnoreCase)))
            {
                mailFolder = mailFolder.GetSubfolder(folderNamePart);
            }
            else
            {
                break;
            }
        }

        if (mailFolder.FullName.IndexOf(folderName, StringComparison.OrdinalIgnoreCase) >= 0)
        {
            return folderNamespace;
        }

        if (!mailFolder.IsNamespace)
        {
            potentialFolderNamespaces.Add(folderNamespace, mailFolder.FullName);
        }
    }

    FolderNamespace closestFolderNameSpace = potentialFolderNamespaces.OrderByDescending(n => n.Value.Length).FirstOrDefault().Key;
    if (closestFolderNameSpace != null)
    {
        return closestFolderNameSpace;
    }

    FolderNamespace defaultFolderNamespace = folderNamespaces.FirstOrDefault();

    return defaultFolderNamespace;
}

Однако это не сработало. При ближайшем рассмотрении кажется, что PersonalNamespaces, SharedNamespaces и OtherNamespaces все пусты и поэтому для этой учетной записи нет пространств имен папок.

В качестве быстрой проверки я только что попробовал следующее:

imapClient.GetFolder(folderName)

Однако это вызвало исключение ImapProtocolException:

Сервер IMAP неожиданно отключился.

Попытка использовать только имя папки root также сделала то же самое.

Я немного растерялся, как открыть папку в этой учетной записи, так как не могу ее найти. Как я могу это сделать?


Некоторые дополнительные сведения:

  • . Net 4.6.1
  • MailKit / MimeKit версии 1.1, но с обновлением до 2.4 .1 не помогло
  • Учетная запись Office365 IMAP

Журнал протокола:

Connected to --cut--
S: * OK The Microsoft Exchange IMAP4 service is ready. --cut--
C: A00000000 CAPABILITY
S: * CAPABILITY IMAP4 IMAP4rev1 AUTH=PLAIN AUTH=XOAUTH2 SASL-IR UIDPLUS MOVE ID UNSELECT CHILDREN IDLE NAMESPACE LITERAL+
S: A00000000 OK CAPABILITY completed.
C: A00000001 AUTHENTICATE XOAUTH2 --cut--
S: A00000001 NO AUTHENTICATE failed.
C: A00000002 AUTHENTICATE PLAIN --cut--
S: A00000002 OK AUTHENTICATE completed.
C: A00000003 CAPABILITY
S: * CAPABILITY IMAP4 IMAP4rev1 AUTH=PLAIN AUTH=XOAUTH2 SASL-IR UIDPLUS MOVE ID UNSELECT CLIENTACCESSRULES CLIENTNETWORKPRESENCELOCATION BACKENDAUTHENTICATE CHILDREN IDLE NAMESPACE LITERAL+
S: A00000003 OK CAPABILITY completed.
C: A00000004 NAMESPACE
S: A00000004 BAD User is authenticated but not connected.
C: A00000005 LIST "" "INBOX"
S: A00000005 BAD User is authenticated but not connected.
S: * BYE Connection closed. 14

1 Ответ

1 голос
/ 09 января 2020

Вот проблема:

C: A00000004 NAMESPACE
S: A00000004 BAD User is authenticated but not connected.
C: A00000005 LIST "" "INBOX"
S: A00000005 BAD User is authenticated but not connected.
S: * BYE Connection closed. 14

После аутентификации MailKit отправляет команду NAMESPACE, чтобы получить список пространств имен с сервера, но отвечает бессмысленной ошибкой, утверждая, что клиент аутентифицирован, но не подключен (э-э, это невозможно, или мы не будем отправлять команды или получать ответы, да).

Когда MailKit получает BAD-ответ на команду NAMESPACE, он возвращается к попытке получить информацию для INBOX. папка ... для которой он возвращает ту же ошибку BAD, которая не имеет смысла.

Вывод: Сервер IMAP сломан.

Возможное решение (кроме получения нового сервера IMAP, который не сосет):

Этот журнал выглядит так, как будто он был получен с использованием старой версии MailKit (1.1?), поэтому попробуйте сделать это перед вызовом Authenticate("username", "password"):

client.AuthenticationMechanisms.Remove ("XOAUTH2");

Если это все равно приводит к команде BAD NAMESPACE, тогда я не уверен, что можно сделать ...

Обновление:

На основе https://unix.stackexchange.com/questions/164823/user-is-authenticated-but-not-connected-after-changing-my-exchange-password - звучит ли В Exchange IMAP есть ошибка, из-за которой, если имя пользователя правильное, но введен неверный пароль, сервер Exchange IMAP будет «аутентифицировать» пользователя, но попадет в это странное состояние «аутентифицирован, но не подключен», что приведет к возникновению вышеуказанных ошибок.

Решение состоит в том, чтобы предоставить правильный пароль.

...