IMAP Tutorial
Applies to: Rebex Total Pack, Rebex Mail Pack, Rebex IMAP
Table of content
- Namespaces and assemblies
- IMAP basics - connecting, logging in and disconnecting
- Authenticating to an IMAP server
- Authentication using NTLM
- Working with folders
- Current folder
- Sequence numbers and unique IDs
- Retrieving the message list
- Downloading message headers
- Searching
- Message flags
- Downloading messages
- Deleting and undeleting messages
- Uploading messages
- Working with multiple messages
- Using events and logging communication
Namespaces and assemblies
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
In practice, sequence numbers will change after a call to |
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...