Как установить соединения IMAP на C#

Список расширений IMAP‑сервера

Aspose.Email ImapClient позволяет получить расширения сервера, поддерживаемые сервером, такие как IDLE, UNSELECT, QUOTA и др. Это помогает определить наличие расширения перед использованием клиента для конкретной функции. GetCapabilities() метод возвращает поддерживаемые типы расширений в виде массива строк. Ниже приведён фрагмент кода, показывающий, как получить расширения.

Стандартное IMAP‑соединение

Этот ImapClient класс позволяет приложениям управлять IMAP‑почтовыми ящиками с помощью протокола IMAP. ImapClient класс используется для подключения к IMAP‑почтовым серверам и управления письмами в IMAP‑папках. Чтобы подключиться к IMAP‑серверу

  1. Создать экземпляр ImapClient класс.
  2. Укажите имя хоста, имя пользователя и пароль в Конструктор ImapClient.

Обратите внимание, ограничения пароля должны соответствовать требованиям сервера. Почтовый клиент не добавляет ограничений пароля.

После того как ImapClient Экземпляр инициализирован, следующий вызов любой операции с этим экземпляром подключит к серверу. Ниже показан фрагмент кода, демонстрирующий, как подключиться к IMAP‑серверу, следуя вышеописанным шагам.

// For complete examples and data files, please go to https://github.com/aspose-email/Aspose.Email-for-.NET
// Create an imapclient with host, user and password
ImapClient client = new ImapClient("localhost", "user", "password");

IMAP‑соединение с поддержкой SSL

Подключение к IMAP‑серверу описано, как подключиться к IMAP‑серверу в четыре простых шага:

  1. Создать экземпляр ImapClient класс.
  2. Укажите имя хоста, имя пользователя и пароль.
  3. Укажите порт.
  4. Укажите параметры безопасности.

Процесс подключения к IMAP‑серверу с включённым SSL похож, но требует задать несколько дополнительных свойств:

Ниже показан фрагмент кода, демонстрирующий, как

  1. Установите имя пользователя, пароль и порт.
  2. Установите параметр безопасности.
// For complete examples and data files, please go to https://github.com/aspose-email/Aspose.Email-for-.NET
// Create an instance of the ImapClient class
ImapClient client = new ImapClient("imap.domain.com", 993, "user@domain.com", "pwd");
            
// Set the security mode to implicit
client.SecurityOptions = SecurityOptions.SSLImplicit;

Настройка прокси‑соединения

Подключение к серверу через прокси

Прокси‑серверы обычно используются для связи с внешним миром. В таких случаях почтовые клиенты не могут работать в Интернете без указания адреса прокси. Aspose.Email поддерживает версии 4, 4a и 5 протокола SOCKS‑прокси. В этой статье приведён рабочий пример доступа к ящику с помощью прокси‑почтового сервера. Чтобы получить доступ к ящику через прокси‑сервер:

  1. Инициализировать SocksProxy с требуемой информацией, то есть адресом прокси, портом и версией SOCKS.
  2. Инициализировать ImapClient с адресом хоста, именем пользователя, паролем и другими настройками.
  3. Установить SocksProxy свойство клиента для SocksProxy объект, созданный выше.

Ниже показан фрагмент кода, демонстрирующий, как получить почтовый ящик через прокси‑сервер.

// For complete examples and data files, please go to https://github.com/aspose-email/Aspose.Email-for-.NET
// Connect and log in to IMAP and set SecurityOptions
ImapClient client = new ImapClient("imap.domain.com", "username", "password");
client.SecurityOptions = SecurityOptions.Auto;
            
string proxyAddress = "192.168.203.142"; // proxy address
int proxyPort = 1080; // proxy port
SocksProxy proxy = new SocksProxy(proxyAddress, proxyPort, SocksVersion.SocksV5);

// Set the proxy
client.Proxy = proxy;
           
try
{
    client.SelectFolder("Inbox");
}
catch (Exception ex)
{
    Console.WriteLine(ex.Message);
}

Подключение к серверу через HTTP‑прокси

// For complete examples and data files, please go to https://github.com/aspose-email/Aspose.Email-for-.NET
HttpProxy proxy = new HttpProxy("18.222.124.59", 8080);
using (ImapClient client = new ImapClient("imap.domain.com", "username", "password"))
{
    client.Proxy = proxy;
    client.SelectFolder("Inbox");
}

Соединение в режиме только чтения

Этот ImapClient класс предоставляет ReadOnly свойство, которое при установке в true указывает, что никаких изменений в постоянном состоянии почтового ящика не должно происходить. Ниже пример кода, демонстрирующий использование ImapClient.ReadOnly свойства. Оно получает количество непрочитанных сообщений, затем извлекает одно сообщение и снова получает количество непрочитанных сообщений в режиме только для чтения. Количество непрочитанных сообщений остаётся прежним, что указывает на то, что постоянное состояние почтового ящика не изменилось.

// For complete examples and data files, please go to https://github.com/aspose-email/Aspose.Email-for-.NET
ImapClient imapClient = new ImapClient();
imapClient.Host = "<HOST>";
imapClient.Port = 993;
imapClient.Username = "<USERNAME>";
imapClient.Password = "<PASSWORD>";
imapClient.SupportedEncryption = EncryptionProtocols.Tls;
imapClient.SecurityOptions = SecurityOptions.SSLImplicit;

ImapQueryBuilder imapQueryBuilder = new ImapQueryBuilder();
imapQueryBuilder.HasNoFlags(ImapMessageFlags.IsRead); /* get unread messages. */
MailQuery query = imapQueryBuilder.GetQuery();

imapClient.ReadOnly = true;
imapClient.SelectFolder("Inbox");
ImapMessageInfoCollection messageInfoCol = imapClient.ListMessages(query);
Console.WriteLine("Initial Unread Count: " + messageInfoCol.Count());
if (messageInfoCol.Count() > 0)
{
    imapClient.FetchMessage(messageInfoCol[0].SequenceNumber);

    messageInfoCol = imapClient.ListMessages(query);
    // This count will be equal to the initial count
    Console.WriteLine("Updated Unread Count: " + messageInfoCol.Count());
}
else
{
    Console.WriteLine("No unread messages found");
}

Настройка аутентификации CRAM-MD5

Для безопасной аутентификации и доступа к серверу электронной почты Aspose.Email для .NET предлагает метод аутентификации CRAM-MD5. Следующий фрагмент кода покажет, как он работает с ImapClient:

imapClient.AllowedAuthentication = ImapKnownAuthenticationType.CramMD5;

Установка тайм‑аутов для операций IMAP

Каждая почтовая операция занимает время, зависящее от множества факторов (сетевые задержки, размер данных, производительность сервера и т.д.). Вы можете установить тайм‑аут для всех почтовых операций. Пример кода ниже показывает, как это сделать с помощью Тайм‑аут свойство. Примечание: не следует задавать большие значения, чтобы избежать длительного ожидания в приложении.

Настроить тайм‑аут операции

using (ImapClient imapClient = new ImapClient("host", 993, "username", "password", SecurityOptions.SSLImplicit))
{
    imapClient.Timeout = 60000; // 60 seconds

    // some code...
}

Ограничить тайм‑аут приветствия

IMAP‑клиент может использовать автоматический режим установления соединения. В этом режиме клиент перебирает все возможные параметры подключения, пока соединение не будет установлено. При корректном соединении IMAP‑сервер посылает клиенту строку приветствия. Серверы могут инициировать SSL/TLS соединение неявно или явно (START TLS). Если режим соединения не совпадает (например, сервер ожидает неявного SSL‑соединения, а клиент пытается установить незащищённое или явное SSL‑соединение), сервер не отправит строку приветствия, и пользователь будет ожидать долго, пока не наступит тайм‑аут, после чего клиент перейдёт к следующему варианту подключения. Чтобы избежать этой проблемы, введено свойство GreetingTimeout. Это свойство позволяет задать тайм‑аут для строки приветствия и сократить время автоматического установления соединения.

using (ImapClient client = new ImapClient("localhost", 993, "username", "password"))
{
    client.GreetingTimeout = 4000;
    client.SelectFolder(ImapFolderInfo.InBox);
}

Использование криптографических протоколов с IMAP

Aspose.Email поддерживает криптографические протоколы SSL (устаревший) и TLS для обеспечения безопасности связи. Вы можете включить криптографическое шифрование, чтобы защитить обмен данными между вашим приложением и почтовыми серверами.

ПРИМЕЧАНИЕ: Устанавливайте только те версии протокола, которые поддерживаются .NET Framework. Если некоторые версии криптографического протокола не поддерживаются текущей версией .NET Framework, они будут проигнорированы и пропущены. В этом случае исключения генерироваться не будут. Пожалуйста, используйте SetSupportedEncryptionUnsafe методом, если вы хотите установить протоколы без проверок совместимости.

Пример кода ниже показывает, как установить TLS 1.3 для ImapClient экземпляр класса.

using (ImapClient imapClient = new ImapClient("host", 993, "username", "password", SecurityOptions.SSLImplicit))
{
    imapClient.SupportedEncryption = EncryptionProtocols.Tls13;

    // some code...
}

Если указанный протокол шифрования не поддерживается в текущей версии .NET Framework, различие в поведении между SetSupportedEncryptionUnsafe метод и SupportedEncryption свойство выглядит следующим образом:

  • Если SupportedEncryption при использовании свойства, почтовый клиент понижает уровень протокола шифрования до поддерживаемого.
  • Если SetSupportedEncryptionUnsafe при использовании метода, почтовый клиент генерирует исключения.

Использование команды IMAP IDLE

API Aspose.Email ImapClient предоставляет возможность открыть соединение с сервером и ждать поступления электронного сообщения. Это позволяет избежать постоянного опроса сервера на предмет новых писем. Следующий фрагмент кода демонстрирует, как использовать библиотеку Aspose.Email для мониторинга IMAP‑почтового ящика на предмет новых и удалённых сообщений, а затем выполнять конкретные действия в зависимости от этих событий:

// For complete examples and data files, please go to https://github.com/aspose-email/Aspose.Email-for-.NET
// Connect and log in to IMAP 
ImapClient client = new ImapClient("imap.domain.com", "username", "password");

ManualResetEvent manualResetEvent = new ManualResetEvent(false);
ImapMonitoringEventArgs eventArgs = null;
client.StartMonitoring(delegate(object sender, ImapMonitoringEventArgs e)
{
    eventArgs = e;
    manualResetEvent.Set();
});
Thread.Sleep(2000);
SmtpClient smtpClient = new SmtpClient("exchange.aspose.com", "username", "password");
smtpClient.Send(new MailMessage("from@aspose.com", "to@aspose.com", "EMAILNET-34875 - " + Guid.NewGuid(), "EMAILNET-34875 Support for IMAP idle command"));
manualResetEvent.WaitOne(10000);
manualResetEvent.Reset();
Console.WriteLine(eventArgs.NewMessages.Length);
Console.WriteLine(eventArgs.DeletedMessages.Length);
client.StopMonitoring("Inbox");
smtpClient.Send(new MailMessage("from@aspose.com", "to@aspose.com", "EMAILNET-34875 - " + Guid.NewGuid(), "EMAILNET-34875 Support for IMAP idle command"));
manualResetEvent.WaitOne(5000);

Следующий пример кода показывает, как настроить асинхронный мониторинг новых электронных сообщений:

var client = = new ImapClient("imap.domain.com", "username", "password");

//anySuccess is a flag to prevent infinite Client.ResumeMonitoring calls
var anySuccess = false;
await client.StartMonitoringAsync(OnNewMessagesCallback, OnErrorCallback);

void OnErrorCallback(object eventSender, ImapMonitoringErrorEventArgs errorEventArguments)
{
    //The exception can be handled here
    Logger.Debug.Write(
        $"An error occured while folder monitoring: {errorEventArguments.FolderName}",
        errorEventArguments.Error);
    //IMAP folder monitoring is stopped on any error. Here is an example
    //of resuming after that.
    if (!anySuccess) return;
    anySuccess = false;
    //Make sure you use ResumeMonitoring instead of StartMonitoring here
    //to prevent missing any emails between the error handling and resuming.
    client.ResumeMonitoring(OnNewMessagesCallback, OnErrorCallback,
        errorEventArguments.MonitoringState);
}

void OnNewMessagesCallback(object sender, ImapMonitoringEventArgs successEventArgs)
{
    anySuccess = true;
    //Use successEventArgs.NewMessages to handle new messages
    //Use successEventArgs.DeletedMessages to handle deleted messages
}

Поддержка расширений IMAP

Aspose.Email API обеспечивает поддержку расширений IMAP. В настоящее время API поддерживает следующие расширения IMAP. Эти расширения не поддерживаются всеми серверами.

// For complete examples and data files, please go to https://github.com/aspose-email/Aspose.Email-for-.NET
using (ImapClient client = new ImapClient("imap.gmail.com", 993, "username", "password"))
{
    // Set SecurityOptions
    client.SecurityOptions = SecurityOptions.Auto;
    Console.WriteLine(client.IdSupported.ToString());

    ImapIdentificationInfo serverIdentificationInfo1 = client.IntroduceClient();
    ImapIdentificationInfo serverIdentificationInfo2 = client.IntroduceClient(ImapIdentificationInfo.DefaultValue);

    // Display ImapIdentificationInfo properties
    Console.WriteLine(serverIdentificationInfo1.ToString(), serverIdentificationInfo2);
    Console.WriteLine(serverIdentificationInfo1.Name);
    Console.WriteLine(serverIdentificationInfo1.Vendor);
    Console.WriteLine(serverIdentificationInfo1.SupportUrl);
    Console.WriteLine(serverIdentificationInfo1.Version);
}

Расширенная команда списка IMAP4

В следующем фрагменте кода показано, как использовать расширенную команду списка IMAP4.

// For complete examples and data files, please go to https://github.com/aspose-email/Aspose.Email-for-.NET
using (ImapClient client = new ImapClient("imap.gmail.com", 993, "username", "password"))
{
    ImapFolderInfoCollection folderInfoCol = client.ListFolders("*");
    Console.WriteLine("Extended List Supported: " + client.ExtendedListSupported);
    foreach (ImapFolderInfo folderInfo in folderInfoCol)
    {
        switch (folderInfo.Name)
        {
            case "[Gmail]/All Mail":
                Console.WriteLine("Has Children: " + folderInfo.HasChildren);
                break;
            case "[Gmail]/Bin":
                Console.WriteLine("Bin has children? " + folderInfo.HasChildren);
                break;
            case "[Gmail]/Drafts":
                Console.WriteLine("Drafts has children? " + folderInfo.HasChildren);
                break;
            case "[Gmail]/Important":
                Console.WriteLine("Important has Children? " + folderInfo.HasChildren);
                break;
            case "[Gmail]/Sent Mail":
                Console.WriteLine("Sent Mail has Children? " + folderInfo.HasChildren);
                break;
            case "[Gmail]/Spam":
                Console.WriteLine("Spam has Children? " + folderInfo.HasChildren);
                break;
            case "[Gmail]/Starred":
                Console.WriteLine("Starred has Children? " + folderInfo.HasChildren);
                break;
        }
    }
}