如何在 C# 中建立 IMAP 连接

列出 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");

启用 SSL 的 IMAP 连接

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

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

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

以下代码片段展示了如何

  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 支持 SOCKS 代理协议的 4、4a 和 5 版本。本文提供了使用代理邮件服务器访问邮箱的工作示例。要通过代理服务器访问邮箱:

  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 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 邮箱收件箱的新邮件和已删除邮件,并基于这些事件执行特定操作:

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