IMAP Tutorial

Applies to: Rebex Total Pack, Rebex Mail Pack, Rebex IMAP

Namespaces and assemblies 

For information on TLS/SSL security, check out our TLS/SSL Tutorial!

There are several assemblies which have to be reference in your project to be able to use all features of Mail for .NET described here. Rebex.Imap.dll is needed for any IMAP operations and contains the Imap class and others in Rebex.Net namespace. Rebex.Mail.dll, Rebex.Common.dll and Rebex.Networking.dll contains classes that make it possible to read, create and write e-mail messages in MIME format and contains the MailMessage class in Rebex.Mail namespace and a number of classes that represent mail message headers in Rebex.Mime.Headers namespace.

To gain access to all described functionality, reference the two assemblies from your project and import the following namespaces in your source files:

using Rebex.Net;
using Rebex.Mail;
using Rebex.Mime.Headers;
Imports Rebex.Net
Imports Rebex.Mail
Imports Rebex.Mime.Headers

IMAP basics - connecting, logging in and disconnecting 

Typical IMAP session goes like this:

  • Connect to the IMAP server
  • Login - authenticate with user name and password
  • Work with folders and messages
  • Disconnect

Unlike much simpler POP3 protocol, IMAP is a multi-session protocol that supports multiple folders, also somewhat confusingly called mailboxes. While you are connected and authenticated, you will be informed about new incoming messages, and also about messages deleted or marked by other concurrent sessions using the same account. Luckily, you usually only have to care about most of this if you want to.

And now let's look at some sample code.

Imap client = new Imap();
// connect to server
client.Connect("imap.example.org");

// authenticate
client.Login("username", "password");

// work with folders and messages
//...

// disconnect
client.Disconnect();
Dim client As New Imap
'connect to server
client.Connect("imap.example.org")

'authenticate
client.Login("username", "password")

'work with folders and messages
'...

'disconnect
client.Disconnect()

Authenticating to an IMAP server 

The IMAP protocol supports several authentication methods. Normally, you just have to supply your credentials to the Login method. The library will automatically choose the best (most secure) authentication method available and log you in.

Additionally, you can retrieve the list of supported authentication methods using the Imap object's GetSupportedAuthenticationMethods method, and specify which one is to be used for login. (Or specify ImapAuthentication.Auto that will do this automatically.)

// create client and connect
Imap client = new Imap();
client.Connect("imap.example.org");

// let the library choose the best method
client.Login("username", "password");

// or choose one yourself
// client.Login("username", "password", ImapAuthentication.Plain);
'create client and connect
Dim client As New Imap
client.Connect("imap.example.org")

'let the library choose the best method
client.Login("username", "password")

'or choose one yourself
'client.Login("username", "password", ImapAuthentication.Plain)

Authentication using NTLM 

By default, the Login method won't try NTLM authentication, because it might not work correctly in some situations. However, if NTLM does work with your server, nothing stops you from using it. Just read the information on Microsoft Exchange in the FAQ first if you use that server.

// create client and connect
Imap client = new Imap();
client.Connect("imap.example.org");

// authenticate using NTLM
client.Login("domain\\username", "password", ImapAuthentication.Ntlm);
'create client and connect
Dim client As New Imap
client.Connect("imap.example.org")

'authenticate using NTLM
client.Login("domain\username", "password", SmtpAuthentication.Ntlm)

NTLM also makes it possible to authenticate as the user under whose context your application is running. This makes it possible for the user to log in without the need to specify his or her password.

// create client and connect
Imap client = new Imap();
client.Connect("imap.example.org");

// authenticate using NTLM
client.Login(ImapAuthentication.Ntlm);
'create client and connect
Dim client As New Imap
client.Connect("imap.example.org")

' authenticate using NTLM's single-sign-on feature
client.Login(SmtpAuthentication.Ntlm)

Working with folders 

IMAP supports multiple folders per account. In fact, a complete folder hierarchy might be available. However, to keep things simple, there is one special folder that is available in most IMAP implementations - it is called Inbox and it is the primary mailbox for a user on the IMAP server.

The folder hierarchy resembles a common file system in many ways, but there are several differences. 1) The topmost (root) folder may not contain any messages, but there can be other folders at the topmost level of hierarchy in addition to Inbox. 2) Different hierarchy delimiters may be used for different folders or on different levels of the folder tree. However, in practise, the slash ('/') is used almost everywhere. Other popular delimiters are '\' and '.' (the latter is used by IMAP servers that provide access the USENET newsgroups). 3) There is a concept of currently selected folder, but (unlike a common file system) it is possible to unselect a folder so that no folder is currently selected. In fact, this is the default state of the IMAP session.

// create client, connect and log in
Imap client = new Imap();
client.Connect("imap.example.org");
client.Login("username", "password");

// retrieve the list of topmost folders
ImapFolderCollection folders = client.GetFolderList();

// and display it
foreach (ImapFolder folder in folders)
{
    Console.Write(folder.Name);
    Console.Write(" (delimiter is {0})", folder.Delimiter);
    Console.WriteLine();
}

// retrieve the list of folders under Inbox
// ImapFolderCollection folders = client.GetFolderList("Inbox");

// create a new folder called "Test" at the topmost level
client.CreateFolder("Test");

// and create a new folder called "Second" under the "Test" folder
client.CreateFolder("Test/Second");

// rename the "Second" folder
client.RenameFolder("Test/Second", "Test/Third");

// and delete both folders
client.DeleteFolder("Test/Third");
client.DeleteFolder("Test");
'create client, connect and log in
Dim client As New Imap
client.Connect("imap.example.org")
client.Login("username", "password")

'retrieve the list of topmost folders
Dim folders As ImapFolderCollection = client.GetFolderList()

'and display it
Dim folder As ImapFolder
For Each folder In folders
    Console.Write(folder.Name)
    Console.Write(" (delimiter is {0})", folder.Delimiter)
    Console.WriteLine()
Next

'retrieve the list of folders under Inbox
'Dim folders As ImapFolderCollection = client.GetFolderList("Inbox")

'create a new folder called "Test" at the topmost level
client.CreateFolder("Test")

'and create a new folder called "Second" under the "Test" folder
client.CreateFolder("Test/Second")

'rename the "Second" folder
client.RenameFolder("Test/Second", "Test/Third")

'and delete both folders
client.DeleteFolder("Test/Third")
client.DeleteFolder("Test")

Current folder 

Many IMAP commands operate on messages in the currently selected folder. If no folder is selected, many methods will just refuse to work and throw an exception. These include GetMessageList, GetMessage, Copy, DeleteMessages and in fact all other methods that work with messages with the exception of StoreMessage method that uploads a message into a specified folder and therefore doesn't need a folder to be selected.

To start using these methods, a folder has to be selected using the SelectFolder method. In addition to selecting a folder, this will also assign the CurrentFolder property of the Imap object to an instance of ImapFolder. This can be used to determine various useful information about the folder, such as message count, number of unseen messages and supported flags. And when you are done with the selected folder, just unselect it using the UnselectFolder method or select another one. A read-only select is also possible, meaning that no write operations will be permitted while the folder is selected.

// create client, connect and log in
Imap client = new Imap();
client.Connect("server");
client.Login("username", "password");
// select folder
client.SelectFolder("Inbox");

// show number of messages in the current folder
Console.WriteLine
(
    "There are {0} messages in the {1} folder.",
    client.CurrentFolder.TotalMessageCount,
    client.CurrentFolder.Name
);

// and also the number of unseen messages
Console.WriteLine
(
    "And {0} of them were not seen yet.",
    client.CurrentFolder.NotSeenMessageCount
);

//...

client.UnselectFolder();
'create client, connect and log in
Dim client As New Imap
client.Connect("server")
client.Login("username", "password")
'select folder
client.SelectFolder("Inbox")

'show number of messages in the current folder
Console.WriteLine( _
 "There are {0} messages in the {1} folder.", _
 client.CurrentFolder.TotalMessageCount, _
 client.CurrentFolder.Name)

'and also the number of unseen messages
Console.WriteLine( _
 "And {0} of them were not seen yet.", _
 client.CurrentFolder.NotSeenMessageCount)

'...

client.UnselectFolder()

Another useful method related to SelectFolder is GetFolderInfo. It returns an instance of ImapFolder that contains pretty much all the information SelectFolder would return, but, unlike SelectFolder, it does not unselect the current folder and select the new one. In fact, its purpose is to allow determining the status of a folder without unselecting the currently selected folder.

Sequence numbers and unique IDs 

The IMAP protocol uses two different IDs to identify messages.

ID type Description
int sequenceNumber

A number between 1..[number of messages in the IMAP folder]. In IMAP, unlike POP3, this number can change even during IMAP session when a message is permanently removed from a folder, either by the current session or another one. Then, the sequence number of each successive message in the mailbox is decremented by 1, and this must be reflected in sequence numbers used in subsequent methods. However, it is guaranteed that a sequence number will not change during or in between calls to methods that deal with messages and identify them using a sequence number, such as GetMessageList, GetMessage, SetMessageFlags, DeleteMessage or Search, so synchronization loss of message numbers between the client and the server is no concern if your code is structured correctly.

In practice, sequence numbers will change after a call to Purge or CheckForUpdates methods, and also after calls that deal with messages and identify them using a unique ID. You might also want to detect this using Imap.Notification event.

string uniqueId

Unlike sequence number, the message unique ID is permanent and does not change between sessions. A message will retain its unique ID until it is deleted.

A minority of IMAP servers is not capable of unique IDs that persist accross sessions, and other servers might reassign its IDs when some special situation occurs, but even in these rare situations it is guaranteed that a unique ID that once identified a message in a folder will never identify a different message in the same folder.

However, it is important to notice that unique IDs are only unique inside a specific folder, and not accross different folders. Also, as a consequence of this, a message will be assigned a new unique ID if copied to another folder.

Most IMAP methods that deal with messages have two variants - one that accepts sequence number and one that accepts a unique ID as parameter. Obviously, the unique ID variants should be preferred, as they are permanent and thus safer to deal with and much more error-prone.

It's also possible to map a given unique ID to a corresponding sequence number and vice-versa using the GetMessageInfo method.

// some valid unique ID we already retrieved in past
string uniqueId = "abcd13954986";

// create client, connect and log in
Imap client = new Imap();
client.Connect("imap.example.org");
client.Login("username", "password");

// get message info with the sequence number
ImapMessageInfo info = client.GetMessageInfo
(
    uniqueId,
    ImapListFields.SequenceNumber
);
if (info == null)
{
    Console.WriteLine("Message not found, probably deleted?");
}
else
{
    // read the sequence number from it
    int sequenceNumber = info.SequenceNumber;

    // and use it to download the message
    client.GetMessage(sequenceNumber, localPath);

    // please note that this sample is rather pointless,
    // because we could have done this in the first place:
    // client.GetMessage(uniqueId, localPath);
}
'some valid unique ID we already retrieved in past
Dim uniqueId As String = "abcd13954986"

'create client, connect and log in
Dim client As New Imap
client.Connect("imap.example.org")
client.Login("username", "password")

'get message info with the sequence number
Dim info As ImapMessageInfo = client.GetMessageInfo( _
 uniqueId, _
 ImapListFields.SequenceNumber)

If info Is Nothing Then
    Console.WriteLine("Message not found, probably deleted?")
Else
    'read the sequence number from it
    Dim sequenceNumber As Integer = info.SequenceNumber

    'and use it to download the message
    client.GetMessage(sequenceNumber, localPath)

    'please note that this sample is rather pointless,
    'because we could have done this in the first place:
    'client.GetMessage(uniqueId, localPath)
End If

Retrieving the message list 

To get a list of messages in the mailbox, call the GetMessageList method. It accepts an optional parameter that specifies what information to retrieve from the server:

Parameter value Description
ImapListFields.SequenceNumber Message sequence number for current session.
ImapListFields.UniqueID Message unique ID that is permanent and does not change between sessions.
ImapListFields.Length Message data size in bytes.
ImapListFields.Flags Message flags (see the ImapMessageFlags enum for the list of message flags).
ImapListFields.ReceivedDate Date and time at which the message was received by the mail server.
ImapListFields.Fast Combination of SequenceNumber, UniqueId, Length, Flags and ReceivedDate.
ImapListFields.Envelope Same as Fast, but also downloads the message envelope info - a selection of most important header fields of the message such as Date, From, To, Subject or Message ID fields. This is the default for GetMessageList method if no fields argument is specified.
ImapListFields.FullHeaders Same as Fast, but also downloads complete message headers of each message. This variant is the most verbose, but also the slowest, and in fact seldom needed, because nearly all interesting information about the message is already returned by ImapListFields.Envelope. See the next section for more discussion about this.
ImapListFields.Body Text and HTML bodies of the message.
ImapListFields.MessageStructure Information about the message structure - list of message parts (bodies, resources and attachments) with detailed info (file names, lengths, content types, content IDs). To access this information, use ImapMessageInfo.GetMailMessage method.

These fields are bit flags, which means that combinations such as UniqueId|Flags or UniqueId|SequenceNumber|Length are also possible - use bitwise or operator for this (| in C#, or in VB.NET).

The following code shows how to download a message list and show a unique ID and From/Subject headers of each message:

// create client, connect and log in
Imap client = new Imap();
client.Connect("imap.example.org");
client.Login("username", "password");

// select folder
client.SelectFolder("Inbox");

// get message list - envelope headers
ImapMessageCollection messages =
    client.GetMessageList(ImapListFields.Envelope);

// display info about each message
Console.WriteLine("UID | From | To | Subject");
foreach (ImapMessageInfo message in messages)
{
    Console.WriteLine(
        "{0} | {1} | {2} | {3}",
        message.UniqueId,
        message.From,
        message.To,
        message.Subject);
}
'create client, connect and log in
Dim client As New Imap
client.Connect("imap.example.org")
client.Login("username", "password")

'select folder
client.SelectFolder("Inbox")

'get message list - envelope headers
Dim messages As ImapMessageCollection = _
client.GetMessageList(ImapListFields.Envelope)

'display info about each message
Console.WriteLine("UID | From | To | Subject")
Dim message As ImapMessageInfo
For Each message In messages
    Console.WriteLine( _
     "{0} | {1} | {2} | {3}", _
     message.UniqueId, _
     message.From, _
     message.To, _
     message.Subject)
Next

Downloading message headers 

The simplest method for downloading all message headers is to call GetMessageList with parameter ImapListFields.FullHeaders, as described in the Retrieving the message list tutorial. It retrieves headers for all messages in the mailbox.

However, as mentioned earlier, this might take a very long time if there are too many messages in the mailbox or the connection bandwidth is limited. If this is the case, it is advisable either to download envelopes (ImapListFields.Envelope) only, which is a bit faster, or to only ask for a simple message list with the IDs, length, etc. (ImapListFields.Fast) and retrieve message headers of each message separately using the GetMessageInfo method - and this can even be done later or only when needed.

// create client, connect and log in
Imap client = new Imap();
client.Connect("imap.example.org");
client.Login("username", "password");

int sequenceNumber = 1; // the first message

ImapMessageInfo info = client.GetMessageInfo
(
    sequenceNumber,
    ImapListFields.Envelope
);
// or FullHeaders if needed

Console.Write("Date: " + info.Date);
Console.Write("From: " + info.From);
Console.Write("Subject: " + info.Subject);
'create client, connect and log in
Dim client As New Imap
client.Connect("imap.example.org")
client.Login("username", "password")

Dim sequenceNumber As Integer = 1 'the first message

Dim info As ImapMessageInfo = client.GetMessageInfo( _
 sequenceNumber, _
 ImapListFields.Envelope)
' or FullHeaders if needed

Console.Write("Date: " & info.Date.ToString())
Console.Write("From: " & info.From.ToString())
Console.Write("Subject: " & info.Subject)

Searching 

IMAP supports a search command that is quite powerful. You can search for messages matching given criteria using the Search method. It accepts a variable number of search parameters, so comlex queries are possible. See the table following the sample code for a list of possibilities.

Please note that this method only operates on a currently selected folder.

// create client, connect and log in
Imap client = new Imap();
client.Connect("server");
client.Login("username", "password");

// select the folder for search operation
client.SelectFolder("Inbox");

// find messages from "joe@example.org"
ImapMessageCollection fromJoe = client.Search
(
        ImapSearchParameter.From("joe@example.org")
);

// find messages from the last year
// and larger than 100KB
ImapMessageCollection largeAndOld = client.Search
(
        ImapSearchParameter.Arrived(DateTime.Now.AddYears(-1), DateTime.Now),
        ImapSearchParameter.Size(1024 * 100, Int32.MaxValue)
);

// find messages that contain "test"
// and "mail" in their subject and
// "Regards" in their body
ImapMessageCollection complexFilterResult = client.Search
(
        ImapSearchParameter.Subject("test"),
        ImapSearchParameter.Subject("mail"),
        ImapSearchParameter.Body("Regards")
);
'create client, connect and log in
Dim client As New Imap
client.Connect("server")
client.Login("username", "password")

'select the folder for search operation
client.SelectFolder("Inbox")

'find messages from "joe@example.org"
Dim fromJoe As New ImapMessageCollection
fromJoe = client.Search( _
ImapSearchParameter.From("joe@example.org"))

'find messages from the last year
'and larger than 100KB
Dim largeAndOld As New ImapMessageCollection
largeAndOld = client.Search( _
ImapSearchParameter.Arrived(DateTime.Now.AddYears(-1), DateTime.Now), _
ImapSearchParameter.Size(1024 * 100, Integer.MaxValue))

'find messages that contain "test" and "mail" in their subject and
'"Regards" in their body
Dim complexFilterResult As New ImapMessageCollection
complexFilterResult = client.Search( _
ImapSearchParameter.Subject("test"), _
ImapSearchParameter.Subject("mail"), _
ImapSearchParameter.Body("Regards"))

Note that the returned list will contain only the envelope information about each message. To load more information (including the message body) use the overloaded method Search(ImapListFields, parameters).

The following table shows all the available search parameters:

Search parameter Description
From(address) Messages that contain the specified string in their From field.
NotFrom Messages that do not contain the specified string in their From field.
To(address) Messages that contain the specified string in their To field.
NotTo Messages that do not contain the specified string in their To field.
CC(address) Messages that contain the specified string in their CC field.
NotCC Messages that do not contain the specified string in their CC field.
Bcc(address) Messages that contain the specified string in their BCC field.
NotBcc Messages that do not contain the specified string in their BCC field.
Subject(queryTerm) Messages that contain the specified string in their subject field.
Body(queryTerm) Messages that contain the specified string in their body.
FullText(queryTerm) Messages that contain the specified string in their headers or body.
Arrived(on) Messages that arrived on the specified date (disregarding time).
Arrived(since, before) Messages that arrived in the specified date interval (disregarding time).
Sent(on) Messages that were sent on the specified date (disregarding time).
Sent(since, before) Messages that were sent in the specified date interval (disregarding time).
HasFlagsAllOf(flags) Messages with all the specified flags set.
HasFlagsNoneOf(flags) Messages with none of the specified flags set.
Deleted Messages whose Deleted flag is set.
New Messages whose Recent flag is set and Seen flag not set.
Recent Messages whose Recent flag is set.
NotRecent Messages whose Recent flag is not set.
Header(headerName, queryTerm) Messages that contain the specified string in the specified header.
Size(min, max) Messages whose size within the specified interval.
All Search for all messages. Same as GetMessageList method.

Message flags 

Message flags such as "Deleted", "Recent" or "Answered" indicate message states. Most of them can be changed, only the "Recent" flag is read-only. Message flags are returned as a part of GetMessageList/GetMessageInfo/Search response as the Flags property of the ImapMessageInfo class, and you can also search for messages with specified flags set. The following sample demonstrates setting message flags.

// create client, connect and log in
Imap client = new Imap();
client.Connect("imap.example.org");
client.Login("username", "password");

// select folder
client.SelectFolder("Inbox");

// set the "flagged for special attention" flag on
// the first message in the Inbox
client.SetMessageFlags
    (1, ImapFlagAction.Add, ImapMessageFlags.Flagged);

// clear the "flagged for special attention" flag  on
// the first message in the Inbox
client.SetMessageFlags
    (1, ImapFlagAction.Remove, ImapMessageFlags.Flagged);

// mark the message as deleted
client.DeleteMessage(1);
// this is equivalent to:
// client.SetMessageFlags
//    (1, ImapFlagAction.Add, ImapMessageFlags.Deleted);
'create client, connect and log in
Dim client As New Imap
client.Connect("imap.example.org")
client.Login("username", "password")

'select folder
client.SelectFolder("Inbox")

'set the "flagged for special attention" flag on
'the first message in the Inbox
client.SetMessageFlags( _
 1, ImapFlagAction.Add, ImapMessageFlags.Flagged)

'clear the "flagged for special attention" flag  on
'the first message in the Inbox
client.SetMessageFlags( _
 1, ImapFlagAction.Remove, ImapMessageFlags.Flagged)

'mark the message as deleted
client.DeleteMessage(1)
'this is equivalent to:
'client.SetMessageFlags( _
'   1, ImapFlagAction.Add, ImapMessageFlags.Deleted)

Downloading messages 

Finally, let's start downloading some messages! It is very simple - just call the GetMailMessage method and you retrieve an instance of the MailMessage class that contains the message corresponding to the supplied sequence number. You can read message headers, body and attachments from it, modify it, save it to disk or send it again using our Smtp class. For more info about this, check out our MailMessage class tutorial.

Alternatively, if all you need is to download the message data and save it to disk or write it into a stream, and you don't need to access the message content in any way at the moment, just call the GetMessage method instead. This won't return an instance of MailMessage and just writes the message data into the supplied local path or stream.

// create client, connect and log in
Imap client = new Imap();
client.Connect("imap.example.org");
client.Login("username", "password");

// select folder
client.SelectFolder("Inbox");

// get message list
ImapMessageCollection list = client.GetMessageList(ImapListFields.Fast);

if (list.Count == 0)
{
    Console.WriteLine("There are no messages in the mailbox.");
}
else
{
    // download the first message
    MailMessage message = client.GetMailMessage(list[0].SequenceNumber);
    //...
}
'create client, connect and log in
Dim client As New Imap
client.Connect("imap.example.org")
client.Login("username", "password")

'select folder
client.SelectFolder("Inbox")

'get message list
Dim list As ImapMessageCollection = client.GetMessageList(ImapListFields.Fast)

If list.Count = 0 Then
    Console.WriteLine("There are no messages in the mailbox.")
Else
    'download the first message
    Dim message As MailMessage = client.GetMailMessage(list(0).SequenceNumber)
    '...
End If

Deleting and undeleting messages 

To delete a message, call the Delete method with message sequence number as an argument.

The Delete method marks a message as deleted. These won't disappear from the mailbox immediately and will still appear in subsequent message lists until the Purge method is called, current folder is changed using SelectFolder or the session is disconnected using Disconnect method. Before a call to one of these methods, deleted messages can be undeleted using the UndeleteMessage method.

// create client, connect and log in
Imap client = new Imap();
client.Connect("imap.example.org");
client.Login("username", "password");

// select folder
client.SelectFolder("Inbox");

// delete the first message
client.DeleteMessage(1);

// delete the second message
client.DeleteMessage(2);

// undelete the first message
client.UndeleteMessage(1);

// permanently remove the message marked as deleted
client.Purge();

// delete the first message (1 refers to a different message now)
client.DeleteMessage(1);

// unselecting current folder will remove deleted messages as well
client.UnselectFolder();
'create client, connect and log in
Dim client As New Imap
client.Connect("imap.example.org")
client.Login("username", "password")

'select folder
client.SelectFolder("Inbox")

'delete the first message
client.DeleteMessage(1)

'delete the second message
client.DeleteMessage(2)

'undelete the first message
client.UndeleteMessage(1)

'permanently remove the message marked as deleted
client.Purge()

'delete the first message (1 refers to a different message now)
client.DeleteMessage(1)

'unselecting current folder will remove deleted messages as well
client.UnselectFolder()

Uploading messages 

IMAP also supports uploading messages from a client to a folder, and the StoreMessage method can be used to achieve this. In addition to a local file or a stream, it also accepts an instance of the MailMessage class. For more info about it, check out our MailMessage class tutorial.

Also, unlike other message-related methods, StoreMessage uploads the message into the specified folder and not to the current folder. This makes it possible to upload a message even when no folder is selected, or to a folder different from the one currently selected.

Please note that this method only uploads the message to the specific folder. It does not provide any mechanism to transfer the message to a recipient. User Smtp class if you need this.

// create client, connect and log in
Imap client = new Imap();
client.Connect("imap.example.org");
client.Login("username", "password");

MailMessage mail = new MailMessage();
mail.From        = "from@example.org";
mail.To          = "to@example.org";
mail.Subject     = "Mail subject";
mail.BodyText    = "Hello from Rebex";
mail.Priority    = MailPriority.High;

// upload the message into Inbox
client.StoreMessage("Inbox", mail);
'create client, connect and log in
Dim client As New Imap
client.Connect("imap.example.org")
client.Login("username", "password")

Dim mail As New MailMessage
mail.From = New MailAddressCollection("from@example.org")
mail.To = New MailAddressCollection("to@example.org")
mail.Subject = "Mail subject"
mail.BodyText = "Hello from Rebex"
mail.Priority = MailPriority.High

'upload the message into Inbox
client.StoreMessage("Inbox", mail)

Working with multiple messages 

Many Imap methods accept a message set as a parameter. This makes it possible to process multiple messages at once, usually in a single round-trip to the server, which can be a benefit on slow connections. All these methods accept a ImapMessageSet as an argument, which is a set of either individual unique IDs or sequence numbers, or their ranges. (Combination of both unique IDs and sequence numbers in a single message set is not supported).

The methods that accept ImapMessageSet argument are:

  • GetMessageList
  • Search
  • Copy
  • SetMessageFlags
  • DeleteMessage
  • UndeleteMessage

The following code demonstrates deleting several messages using a single call.

// create client, connect and log in
Imap client = new Imap();
client.Connect("imap.example.org");
client.Login("username", "password");

// build a message set for messages 1, 4 and 8-11
ImapMessageSet ms = new ImapMessageSet();
ms.Add(1);
ms.Add(5);
ms.AddRange(8, 11);

// delete messages in this message set
client.DeleteMessage(ms);

// delete messages 2, 3, 4 and 7
client.DeleteMessage
(
    new ImapMessageSet(2, 3, 4, 7)
);
'create client, connect and log in
Dim client As New Imap
client.Connect("imap.example.org")
client.Login("username", "password")

'build a message set for messages 1, 4 and 8-11
Dim ms As New ImapMessageSet
ms.Add(1)
ms.Add(5)
ms.AddRange(8, 11)

'delete messages in this message set
client.DeleteMessage(ms)

'delete messages 2, 3, 4 and 7
client.DeleteMessage(New ImapMessageSet(2, 3, 4, 7))

Using events and logging communication 

In case something goes wrong, it is very useful to have a log of commands sent to the server and responses received from it for diagnostics purposes. To make this possible, the Imap class declares the following events:

Event name Description
CommandSent Occurs when a command (for example CAPABILITY or FETCH) is sent to the server.
ResponseRead Occurs when response is received from the server.
Notification Occurs when an unsolicited notification is received from a server, either as a response to another command or CheckForUpdates method.
StateChanged Occurs when the session state changes, such as from Disconnected to Ready, from Ready to Sending or from Sending to Reading.
TransferProgress Occurs when a block of message data is received or sent to the server.

The CommandSent or ResponseRead events are particularly useful for the purpose of generating a communication log, the TransferProgress event can be used by a GUI application to display amount of transfered data or a progress bar, and RejectedRecipient event can be used to override default behaviour of not transmitting the message at all if a single recipient is rejected.

Imap client = new Imap();
client.CommandSent += client_CommandSent;
client.ResponseRead += client_ResponseRead;
client.Connect("imap.example.org");
Dim client As New Imap
AddHandler client.CommandSent, AddressOf client_CommandSent
AddHandler client.ResponseRead, AddressOf client_ResponseRead
client.Connect("imap.example.org")
private void client_CommandSent(object sender, ImapCommandSentEventArgs e)
{
    Console.WriteLine("Command: {0}", e.Command);
}

private void client_ResponseRead(object sender, ImapResponseReadEventArgs e)
{
    Console.WriteLine("Response: {0}", e.Response);
}
Public Sub client_CommandSent(ByVal sender As Object, ByVal e As _
ImapCommandSentEventArgs)
    Console.WriteLine("Command: {0}", e.Command)
End Sub

Public Sub client_ResponseRead(ByVal sender As Object, ByVal e As _
ImapResponseReadEventArgs)
    Console.WriteLine("Response: {0}", e.Response)
End Sub

Back to tutorial list...