MailBee. NET Objects Tutorials

Receiving message headers from POP3 server

Downloading the list of messages

Summary: Demonstrates using POP3 object for building message list without downloading entire messages.

Many e-mail applications give users the ability to select messages to be retrieved from the list of messages available in the mailbox on the server. To build such a list, it's required to get some preview information on each message in the mailbox. For POP3, this information is the message header.

Retrieving headers for all the messages in the mailbox

On success, DownloadMessageHeaders method of Pop3 class returns a MailMessageCollection object containing the downloaded message headers. Messages are returned in the same order as they are located in the mailbox: the first message is the oldest, the last one is the newest (see below how to change this order). If the POP3 server supports pipelining, this method will download all the messages in a single network operation, which greatly increases performance and reduces network traffic.

The sample code below prints "From", "To" and "Subject" fields of all messages in the mailbox.

Before using MailBee.NET Objects, make sure the correct license key is specified (see "Sales, Licensing, and Support" and "Using MailBee.NET Objects in Your Projects" sections).

Code example:

C#

Pop3 pop = new Pop3();

// Connect to POP3 server
pop.Connect("mail.domain.com");
pop.Login("jdoe", "secret");

// Download headers for all messages
MailMessageCollection msgs = pop.DownloadMessageHeaders();

// For each message, write its details to the console
foreach (MailMessage msg in msgs)
{
        Console.WriteLine("From: " + msg.From.AsString + ", To: " + msg.To.AsString);
        Console.WriteLine("Subject: " + msg.Subject);
}

// Disconnect from POP3 server
pop.Disconnect();

VB.NET

Dim pop As New Pop3

' Connect to POP3 server
pop.Connect("mail.domain.com")
pop.Login("jdoe", "secret")

' Download headers for all messages
Dim msgs As MailMessageCollection = pop.DownloadMessageHeaders()

' For each message, write its details to the console
Dim msg As MailMessage
For Each msg In msgs
        Console.WriteLine("From: " & msg.From.AsString & ", To: " & msg.To.AsString)
        Console.WriteLine("Subject: " & msg.Subject)
Next

' Disconnect from POP3 server
pop.Disconnect()

Displaying messages in the reverse-order (descending order)

It is often required to display the list of messages received from the mail server in the reverse order (from the newest messages to the oldest ones). By default, the mail server returns messages in the direct order (from the oldest to the newest ones). MailMessageCollection.Reverse allows the developer to have this collection re-sorted in the reverse order.

The sample code below prints "From" values in the reverse order using foreach loop. Additionally, it deletes messages with "remove" text in their "Subject" field from the mailbox.

Code example:

C#

Pop3 pop = new Pop3();

// Connect to POP3 server
pop.Connect("mail.domain.com");
pop.Login("jdoe", "secret");

// Download headers for all messages
MailMessageCollection msgs = pop.DownloadMessageHeaders();

// Reverse the order of the message list
msgs.Reverse();

// For each message, write its details to the console
foreach (MailMessage msg in msgs)
{
        Console.WriteLine("From: " + msg.From.AsString + ", To: " + msg.To.AsString);
        Console.WriteLine("Subject: " + msg.Subject);

        // Delete message with "remove" in Subject
        if (msg.Subject == "remove")
                pop.DeleteMessage(msg.IndexOnServer);
}

// Disconnect from POP3 server
pop.Disconnect();

VB.NET

Dim pop As New Pop3

' Connect to POP3 server
pop.Connect("mail.domain.com")
pop.Login("jdoe", "secret")

' Download headers for all messages
Dim msgs As MailMessageCollection = pop.DownloadMessageHeaders()

' Reverse the order of the message list
msgs.Reverse()

Dim msg As MailMessage
' For each message, write its details to the console
For Each msg In msgs
        Console.WriteLine("From: " & msg.From.AsString & ", To: " & msg.To.AsString)
        Console.WriteLine("Subject: " & msg.Subject)

        ' Delete message with "remove" in Subject
        If msg.Subject = "remove" Then
                pop.DeleteMessage(msg.IndexOnServer)
        End If
Next

' Disconnect from POP3 server
pop.Disconnect()

Retrieving headers for a particular message

Sometimes you might need to download headers for particular messages only. Common cases are:

* the mailbox contains a large number of messages (hundreds or thousands), and you want to download only 10-20 headers (usually for displaying the message list on per-page basis);

* specific needs of your task. For example, your application uses some kind of database to maintain messages, and only new messages should be searched and/or received;

* some messages were marked for deletion (using DeleteMessage method) and became undownloadable. Presence of such messages will cause DownloadMessageHeaders to fail. Note that the messages marked for deletion will be deleted permanently once the Disconnect method is called, so you will never face the issue above if you never attempt to retrieve messages after marking some of them for deletion.

You can retrieve headers for a single message using DownloadMessageHeaders method. To download the header of each message in the specified range (let's say, 10 messages starting from 30-th), use DownloadMessageHeaders method.

The sample code below prints "From", "To" and "Subject" fields of all messages in the mailbox. It also downloads 10 messages starting from the message #21. Index of the first message in the mailbox is 1. It is also necessary to check the lower and the upper boundary in the range of messages to be downloaded. If you try to retrieve messages starting with #21 but there are only 10 messages available in the mailbox, you will get MailBeeInvalidArgumentException. Messages are returned in the direct order (from the oldest to the newest ones).

Code example:

C#

Pop3 pop = new Pop3();

// Connect to POP3 server
pop.Connect("mail.domain.com");
pop.Login("jdoe", "secret");

// The ordinal position of the first message to be downloaded
int startIndex = 21;

// Number of messages to be downloaded
int count = 100;

// Check lower boundary in the range of messages to be downloaded
if ( (startIndex + count - 1) > pop.InboxMessageCount) count = -1;

// Download headers in the specified range.
MailMessageCollection msgs = pop.DownloadMessageHeaders(startIndex, count);

// For each message, write its details to the console
foreach (MailMessage msg in msgs)
{
        Console.WriteLine("From: " + msg.From.AsString + ", To: " + msg.To.AsString);
        Console.WriteLine("Subject: " + msg.Subject);
}

// Disconnect from POP3 server
pop.Disconnect();

VB.NET

Dim pop As New Pop3

' Connect to POP3 server
pop.Connect("mail.domain.com")
pop.Login("jdoe", "secret")

' The ordinal position of the first message to be downloaded
Dim startIndex As Integer = 21

' Number of messages to be downloaded
Dim count As Integer = 100

' Check lower boundary in the range of messages to be downloaded
If (startIndex + count - 1) > pop.InboxMessageCount Then
        count = -1
End If

' Download headers in the specified range.
Dim msgs As MailMessageCollection = pop.DownloadMessageHeaders(startIndex, count)

' For each message, write its details to the console
Dim msg As MailMessage
For Each msg In msgs
        Console.WriteLine("From: " & msg.From.AsString & ", To: " & msg.To.AsString)
        Console.WriteLine("Subject: " & msg.Subject)
Next

' Disconnect from POP3 server
pop.Disconnect()

Detecting attachments

Summary: highlights detecting whether a message has any attachments when only message headers are available.

In the majority of all e-mail applications it is common to show a paper-clip for messages with attachments.

The POP3 protocol (unlike IMAP4) does not provide the mechanism to preview attachments. Fortunately, most of the messages with attachments have some indirect information about attachments in their headers. This allows MailBee to detect attachments in the message even if only the message header is available.

MailMessage.HasAttachments property returns true if the message has one or more attachments. If only message headers (not the entire message) were received from the mail server, this property may not be 100% accurate. The developer should download the entire message to be sure if it really has any attachments. This is because the message header contains only indirect information about attachments which might be wrong. Also, it's not possible to determine the number of attachments, their sizes or filenames.

Sample code description

For each message in the mailbox the sample code below reports whether attachments are present.

Before using MailBee.NET Objects, make sure the correct license key is specified (see "Sales, Licensing, and Support" and "Using MailBee.NET Objects in Your Projects" sections).

Code example:

C#

Pop3 pop = new Pop3();

// Connect to POP3 server
pop.Connect("mail.domain.com");
pop.Login("jdoe", "secret");

// Download headers for all messages
MailMessageCollection msgs = pop.DownloadMessageHeaders();

// Check each message in mailbox
foreach (MailMessage msg in msgs)
{
if (msg.HasAttachments)
  Console.WriteLine ("Message #" + msg.IndexOnServer + " has attachment(s)");
else
  Console.WriteLine ("Message #" + msg.IndexOnServer + " has no attachment(s)");
}

// Disconnect from POP3 server
pop.Disconnect();

VB.NET

Dim pop As New Pop3

' Connect to POP3 server
pop.Connect("mail.domain.com")
pop.Login("jdoe", "secret")

' Download headers for all messages
Dim msgs As MailMessageCollection = pop.DownloadMessageHeaders()

' Check each message in mailbox
Dim msg As MailMessage
For Each msg In msgs
        If msg.HasAttachments Then
                Console.WriteLine("Message #" & msg.IndexOnServer & " has attachment(s)")
        Else
                Console.WriteLine("Message #" & msg.IndexOnServer & " has no attachment(s)")
        End If
Next

pop.Disconnect()

Retrieve a few body lines along with the headers

Summary: Demonstrates how to get a few lines of the body in addition to message headers when retrieving the list of messages from the POP3 server.

In some cases you may need to get somewhat more than just message headers. The contents of "From:" and "Subject:" fields do not often answer the question "what is the message about?"

Fortunately, the DownloadMessageHeaders method supports the optional parameter bodyLineCount which specifies how many lines of the body to retrieve in addition to the headers.

The larger bodyLineCount is, the bigger piece of the body is returned, and the connection produces lager traffic. If the bodyLineCount is larger than the actual number of body lines in a message, the entire message is returned. As a rule, 20-40 lines of the body describe the message quite enough.

Note: Avoid setting the bodyLineCount to very small values (less than 20). Many e-mail messages have some special (non-textual) information in the first 5-10 lines of the body while the actual body text starts after these lines.

Note: If only the message header was received from the mail server (not the entire message), MailMessage.Size property will contain the size of this header, not of the entire message. To get the size of the entire message, use SizeOnServer property.

Detailed information about parsing messages with incomplete body

For MailBee parser (the module which converts messages into MailMessage objects), there is no difference between entire and incomplete messages. The available content is fully parsed anyway. Thus, if the retrieved piece of the message contains any attachments, they will be parsed and added to MailMessage.Attachments but the size and the contents of certain attachments will be incorrect if they have not been downloaded completely. Those attachments which did not fall into the scope of the retrieved piece of the body section will not be appended to MailMessage.Attachments at all. In other words, MailBee puts into MailMessage object all the information available in the incomplete message, even if the information on some part of the message is incomplete.

If you have one attachment (named "abc.gif", 1234 bytes in size) in the downloaded incomplete message, you can be sure that the full message contains at least one attachment (named "abc.gif") and the size of this attachment is not less than 1234 bytes.

If you have two attachments in the downloaded incomplete message, this means that the first attachment has been downloaded completely and its size and contents correspond to the real values. This is due to the fact that attachments are located in the message one after another, thus each new object guarantees that the previous object data was received completely (e.g. if you have 6 attachments in the incomplete message, this means at least 5 of them have been downloaded completely).

Downloading text body

MailMessage object has two properties which allow a user to get or set the plain-text body or HTML body of the message. To get the plain-text of the message, use the BodyPlainText property. If there is no plain-text body in the message, you will get an empty string by default. To get HTML body, use BodyHtmlText property (you will get an empty string if the message does not have an HTML body).

If your application can display only plain-text displaying, it's possible to convert the HTML-formatted message into the plain text. MailMessage class has Parser property which sets the options which affect how the MailMessage object is being parsed. This property allows you to perform the following operations: automatic generating of plain-text and HTML bodies, saving of the HTML body into a file, etc.

With regard to incomplete messages, conversion of plain-text into HTML or vice versa can be useful even for messages having both versions of the bodies. This is because the incomplete message might have the plain-text body partially available while the HTML body (which usually follows the plain-text body in the message source) might not fall into the downloaded range of the message source. Another case is when the message is HTML-only but you need to display its preview as plain-text (for instance, in a tool-tip).

Sample code description

The sample code below gets the header and the 25 first body lines of the message source of each message and writes the first line of the plain-text body of each message into the console.

Before using MailBee.NET Objects, make sure the correct license key is specified (see "Sales, Licensing, and Support" and "Using MailBee.NET Objects in Your Projects" sections).

Code example:

C#

Pop3 pop = new Pop3();

//Connect to POP3 server
pop.Connect("mail.domain.com");
pop.Login("jdoe", "secret");

// Download all messages incompletely
MailMessageCollection msgs = pop.DownloadMessageHeaders(1, -1, 25);

foreach (MailMessage msg in msgs)
{
        msg.Parser.HtmlToPlainMode = HtmlToPlainAutoConvert.IfNoPlain;
        int n = msg.BodyPlainText.IndexOf('\n');
        if (n > 0)
        {  
                Console.WriteLine("Body Preview: " + strLine.Substring(0, n));
        }
        else
        {
                Console.WriteLine("Body Preview: " + msg.BodyPlainText;
        }
}

// Disconnect from POP3 server
pop.Disconnect();

VB.NET

Dim pop As New Pop3

' Connect to POP3 server
pop.Connect("mail.domain.com")
pop.Login("jdoe", "secret")

' Download all messages incompletely
Dim msgs As MailMessageCollection = pop.DownloadMessageHeaders(1, -1, 25)

Dim n As Integer
Dim msg As MailMessage

For Each msg In msgs
        msg.Parser.HtmlToPlainMode = HtmlToPlainAutoConvert.IfNoPlain
        Dim strLine As String = msg.BodyPlainText
        n = msg.BodyPlainText.IndexOf(vbLf)
        If n > 0 Then
                Console.WriteLine("Body Preview: " + strLine.Substring(0, n))
        Else
                Console.WriteLine("Body Preview: " + msg.BodyPlainText)
        End If
Next

' Disconnect from POP3 server
pop.Disconnect()