如何在 C# 中建立 IMAP 连接

列出 IMAP 服务器扩展

Aspose.Email 的 ImapClient 允许您检索服务器支持的扩展,如 IDLE、UNSELECT、QUOTA 等。这有助于在使用客户端特定功能之前确定扩展的可用性。 GetCapabilities() 方法以字符串数组的形式返回支持的扩展类型。以下代码片段展示了如何检索扩展。

// Connect and log in to IMAP
ImapClient client = new ImapClient("imap.gmail.com", "username", "password");
string[] getCapabilities = client.GetCapabilities();
foreach (string getCap in getCapabilities)
{
    Console.WriteLine(getCap);
}

标准 IMAP 连接

ImapClient 该类允许应用程序使用 IMAP 协议管理 IMAP 邮箱。该 ImapClient 该类用于连接 IMAP 邮件服务器并管理 IMAP 邮件文件夹中的邮件。要连接到 IMAP 服务器

  1. 创建该类的实例 ImapClient 类。
  2. 在构造函数中指定主机名、用户名和密码 ImapClient 构造函数.

注意,密码限制必须符合服务器的要求。邮件客户端本身不添加密码限制。

一旦 ImapClient 实例已初始化,下一次使用此实例调用任何操作时将连接到服务器。以下代码片段展示了如何使用上述步骤连接到 IMAP 服务器。

// Create an imapclient with host, user and password
ImapClient client = new ImapClient("localhost", "user", "password");

启用 SSL 的 IMAP 连接

使用 IMAP 服务器连接 描述了如何通过四个简单步骤连接到 IMAP 服务器:

  1. 创建该类的实例 ImapClient 类。
  2. 指定主机名、用户名和密码。
  3. 指定端口。
  4. 指定安全选项。

连接到启用 SSL 的 IMAP 服务器的过程类似,但需要您设置另外几个属性:

以下代码片段展示了如何

  1. 设置用户名、密码和端口。
  2. 设置安全选项。
// 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 支持 SOCKS 代理协议的 4、4a 和 5 版本。本文提供了使用代理邮件服务器访问邮箱的工作示例。要通过代理服务器访问邮箱:

  1. 初始化 SocksProxy 使用所需信息,即代理地址、端口和 SOCKS 版本。
  2. 初始化 ImapClient 使用主机地址、用户名、密码以及其他设置。
  3. 设置客户端的 SocksProxy 客户端的属性为 SocksProxy 上述创建的对象。

以下代码片段展示了如何通过代理服务器检索邮箱。

// 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 代理连接服务器

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 属性。它获取未读邮件的计数,然后获取一封邮件,再在只读模式下再次获取未读邮件计数。未读邮件计数保持不变,表明邮箱的永久状态未被更改。

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 for .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 客户端会尝试所有可能的连接参数,直至成功建立连接。服务器在正确连接时会向客户端发送问候字符串。服务器可能使用隐式或显式(START TLS)SSL/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 方法,如果您想在不进行兼容性检查的情况下设置协议。

下面的代码示例展示了如何为 ImapClient 类实例。

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

    // some code...
}

如果指定的加密协议在当前 .NET Framework 版本中不受支持,则以下行为之间的差异为 SetSupportedEncryptionUnsafe 方法和 SupportedEncryption 属性如下:

使用 IMAP IDLE 命令

Aspose.Email API ImapClient 提供打开到服务器的连接并等待电子邮件到达的功能。这避免了反复轮询服务器以获取新邮件。以下代码片段演示了如何使用 Aspose.Email 库监控 IMAP 邮箱收件箱的新邮件和已删除邮件,并基于这些事件执行特定操作:

// 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 扩展。这些扩展并非所有服务器都支持。

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 扩展列表命令。

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