Откройте почтовую папку в MailKit, когда нет пространств имен папок.

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

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 неожиданно отключился.

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

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


Еще немного деталей:

  • .Нет 4.6.1
  • MailKit/MimeKit версии 1.1, но обновление до 2.4.1 не помогло
  • IMAP-аккаунт Office365

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

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

person TheLethalCoder    schedule 09.01.2020    source источник
comment
Пожалуйста, получите журнал протокола, потому что всегда должно быть по крайней мере 1 пространство имен. github.com/jstedfast/MailKit/blob/master/FAQ.md# Журнал протокола   -  person jstedfast    schedule 09.01.2020
comment
@jstedfast Сделал это, но не совсем уверен, что я в этом ищу.   -  person TheLethalCoder    schedule 09.01.2020
comment
Вот почему вы должны опубликовать его (после очистки команды AUTHENTICATE или LOGIN), чтобы другие люди могли его проанализировать.   -  person jstedfast    schedule 09.01.2020
comment
Я предполагаю, что INBOX, вероятно, является корневым пространством имен, но я не узнаю об этом, пока не посмотрю журнал протокола (даже в этом случае у PersonalNamespaces должно быть 1 пространство имен).   -  person jstedfast    schedule 09.01.2020
comment
@jstedfast Опубликовал журнал протокола. Но да, все 3 пространства имен пусты.   -  person TheLethalCoder    schedule 09.01.2020
comment
Пространства имен пусты, потому что, по-видимому, сервер IMAP находится в каком-то сломанном состоянии, когда он знает, что вы аутентифицированы, но думает, что вы не подключены (что даже невозможно, потому что для аутентификации вам НУЖНО быть подключенным).   -  person jstedfast    schedule 09.01.2020
comment
@jstedfast Не мог бы наш клиент вообще перезапустить сервер IMAP с помощью ... может быть?   -  person TheLethalCoder    schedule 09.01.2020
comment
Возможно... Я только что заметил, что это Exchange, и я знаю, что MailKit работает с Exchange, так что это странно. Клиент подключается к порту 993? или порт 143? Могут ли они попробовать изменить порт, к которому они подключаются?   -  person jstedfast    schedule 09.01.2020
comment
@jstedfast Порт 993 с useSSL = true.   -  person TheLethalCoder    schedule 09.01.2020
comment
Примечание: имейте в виду, что 993 — это порт SSL, поэтому третий аргумент Connect() также необходимо будет изменить, если только вы не используете Connect (hostName, port, SecureSocketOptions.Auto)   -  person jstedfast    schedule 09.01.2020
comment
Я надеялся, что клиент был на 143 и что может быть Exchange считает, что режим подключения без SSL не подключен. Возможно, стоит попробовать порт 143, но это вряд ли сработает.   -  person jstedfast    schedule 09.01.2020
comment
Да, похоже, не сработало, я попробую несколько комбинаций, но это странно.   -  person TheLethalCoder    schedule 09.01.2020
comment
Ага! unix.stackexchange.com/questions/164823/   -  person jstedfast    schedule 09.01.2020
comment
@jstedfast О, неправильный пароль? Странно... Я попрошу нашего клиента проверить, правильный ли он у них.   -  person TheLethalCoder    schedule 09.01.2020
comment
FWIW, даже если проблема с паролем является решением, я бы все же рекомендовал сохранить client.AuthenticationMechanisms.Remove ("XOAUTH2"); до тех пор, пока вы не обновитесь до MailKit 2.x (2.x больше не пытается использовать XOAUTH2, если вы явно не укажете это).   -  person jstedfast    schedule 09.01.2020
comment
@jstedfast Отлично, я сохраню это и опубликую в нашем следующем выпуске!   -  person TheLethalCoder    schedule 09.01.2020


Ответы (1)


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

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-change-my-exchange-password — похоже, что в Exchange IMAP есть ошибка, из-за которой, если имя пользователя верное, но указан неправильный пароль, сервер Exchange IMAP «аутентифицирует» пользователя, но попадет в это странное состояние «аутентифицирован, но не подключен», что приведет к возникновению вышеуказанных ошибок.

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

person jstedfast    schedule 09.01.2020
comment
Все еще не работает, к сожалению, это на клиенте, поэтому не нам решать, менять ли сервер IMAP. И да, все еще в земле 1.1, пока не могу обновить. - person TheLethalCoder; 09.01.2020
comment
Сменил пароль и теперь все работает, спасибо большое за помощь. - person TheLethalCoder; 09.01.2020