Rebex


Mail Message Tutorial

Applies to: Rebex Total Pack, Rebex Secure Mail

Table of content

#Namespaces and assemblies

For information on signed and encrypted mail, check out our S/MIME Tutorial!

To be able to use the features of Mail for .NET described here, Rebex.Mail.dll, Rebex.Common.dll and Rebex.Networking.dll assemblies have to be referenced from your project. They contains classes that enable you to create, read, process and save e-mail messages in MIME format using the MailMessage and related classes that reside in Rebex.Mail namespace. Also, it contains the Rebex.Mime.Headers namespace with a number of classes that represent mail message headers. And, for advanced and low-level MIME message access, there is Rebex.Mime namespace, but you will only need this if your needs are very special, because for majority of tasks, the much simpler classes of Rebex.Mail namespace are sufficient.

To gain access to all described functionality, reference the Rebex.Mail.dll assembly from your project and import the following namespaces in your source files:

C#

using Rebex.Mail;
using Rebex.Mime.Headers;

VB.NET

Imports Rebex.Mail
Imports Rebex.Mime.Headers

back to top...


#Creating a simple mail message

Creating a mail message is simple.

C#

using Rebex.Net;
using Rebex.Mime.Headers;
...

// create an instance of MailMessage
MailMessage message = new MailMessage();

// and set its properties to desired values
message.From = "hugo@example.com";
message.To = "joe@example.com";
message.Subject = "This is a simple message";
message.BodyText = "Hello, Joe!";
message.BodyHtml = "Hello, <b>Joe</b>!";

VB.NET

Imports Rebex.Net
Imports Rebex.Mime.Headers
...

'create an instance of MailMessage
Dim message As New MailMessage

'and set its properties to desired values
message.From = New MailAddressCollection("hugo@example.com")
message.To = New MailAddressCollection("joe@example.com")
message.Subject = "This is a simple message"
message.BodyText = "Hello, Joe!"
message.BodyHtml = "Hello, <b>Joe</b>!"

What next? You can send the message via SMTP, send it through IIS spool folder, upload it to an IMAP folder or save it to a file or write it to a stream to be used later.

back to top...


#Working with attachments

The MailMessage class has a property called Attachments that represents a collection of attachments. Each of them can be accessed or saved, and, obviously, you can modify it by adding new attachments or removing the existing ones.

C#

// add a local file as an attachment
message.Attachments.Add(
    new Attachment("c:\\data.zip"));

// add an attachment and set its filename
message.Attachments.Add(
    new Attachment("c:\\data.zip", "MyData.zip"));

// add an attachment and specify its filename and MIME type
message.Attachments.Add(new Attachment(
    "c:\\picture.jpg",
    "Picture.jpg",
    "image/jpeg"));

VB.NET

'add a local file as an attachment
message.Attachments.Add( _
New Attachment("c:\\data.zip"))

'add an attachment and set its filename
message.Attachments.Add( _
New Attachment("c:\data.zip", "MyData.zip"))

'add an attachment and specify its filename and MIME type
message.Attachments.Add(New Attachment( _
 "c:\\picture.jpg", _
 "Picture.jpg", _
 "image/jpeg"))

Many commonly used MIME types are defines inside the MediaTypeNames class.

Check out the Extract Attachments Sample for a code that reads a message and extracts its attachment to disk.

back to top...


#Creating a more advanced mail message

The MailMessage class also defines additional headers such as Priority, Date or MessageId that can be used to read and set the corresponding e-mail header fields. CC and Bcc are also available, and more. And if it is not enough, there is the Headers collection that contains all the headers, and you can access and add your own.

All properties that accept a list of mail addresses are in fact collection of MailAddress classes, so it is very simple to access, add and remove individual e-mails.

C#

// create an instance of MailMessage
MailMessage message = new MailMessage();

// and set its properties to desired values
message.From = "hugo@example.com";
message.To.Add("joe@example.com");
message.CC.Add("Mary Smith <mary@example.com>");
message.CC.Add(new MailAddress("joe@example.com"));
message.CC.Add(new MailAddress("john@example.com", "John Doe"));
message.CC.RemoveAt(1);
message.Subject = "This is a bit more advanced message";
message.BodyText = "Hello, Joe";
message.Priority = MailPriority.Low;
message.Date = new MailDateTime(new DateTime(2006, 3, 1, 12, 0, 0));

// generate a unique message ID to help identify replies
message.MessageId = new MessageId();
// and display it
Console.WriteLine(message.MessageId);

VB.NET

'create an instance of MailMessage
Dim message As New MailMessage

'and set its properties to desired values
message.From = New MailAddressCollection("hugo@example.com")
message.To.Add("joe@example.com")
message.CC.Add("Mary Smith <mary@example.com>")
message.CC.Add(New MailAddress("joe@example.com"))
message.CC.Add(New MailAddress("john@example.com", "John Doe"))
message.CC.RemoveAt(1)
message.Subject = "This is a bit more advanced message"
message.BodyText = "Hello, Joe"
message.Priority = MailPriority.Low
message.Date = New MailDateTime(New DateTime(2006, 3, 1, 12, 0, 0))

'generate a unique message ID to help identify replies
message.MessageId = New MessageId
'and display it
Console.WriteLine(message.MessageId)

Check out the Mail Editor Sample - a simple WinForm mail editor application.

back to top...


#Loading and saving messages

These two operations are extremely easy - just call the Load methods to load any e-mail message in MIME (usually use the ".eml" extension) or Microsoft Outlook (uses ".msg" extension) format. To save the message call the Save method and choose the desired message format.

Please note that most e-mail clients are capable of handling the MIME messages (such as Mirosoft Outlook Express and Mozilla Firefox). On the other hand, Microsoft Outlook is only able to send e-mail data in its proprietary format that is MSG.

C#

// create an instance of MailMessage
MailMessage message = new MailMessage();

// load the MIME message from a local disk file
message.Load("c:\\message.eml");

// save it into another MIME file
message.Save("c:\\from_MIME_message.eml", MailFormat.Mime);

// and save it again - this time into a memory stream
MemoryStream stream = new MemoryStream();
message.Save(stream, MailFormat.Mime);

// now save it as a MSG message
message.Save("c:\\from_MIME_message.msg", MailFormat.OutlookMsg);

// load some MSG message
message.Load("c:\\message.msg");

// save it into another MSG file
message.Save("c:\\from_MSG_message.msg", MailFormat.OutlookMsg);

// and finally save it as a MIME message
message.Save("c:\\from_MSG_message.eml", MailFormat.Mime);

VB.NET

'create an instance of MailMessage
Dim message As New MailMessage

' load the MIME message from a local disk file
message.Load("c:\message.eml")

' save it into another MIME file
message.Save("c:\from_MIME_message.eml", MailFormat.Mime)

' and save it again - this time into a memory stream
Dim stream As MemoryStream = New MemoryStream
message.Save(stream)

' now save it as a MSG message
message.Save("c:\from_MIME_message.msg", MailFormat.OutlookMsg)

' load some MSG message
message.Load("c:\message.msg")

' save it into another MSG file
message.Save("c:\from_MSG_message.msg", MailFormat.OutlookMsg)

' and finally save it as a MIME message
message.Save("c:\from_MSG_message.eml", MailFormat.Mime)

back to top...


#Replying to a message

Suppose you just got a mail message from Pop3 or Imap class and want to send a reply. To make it simple for the receiving side to match the reply with the original message, the message ID of the received message should be referenced in the reply.

C#

// an e-mail we just received
MailMessage original = imap.GetMailMessage(sequenceNumber);

// create the reply
MailMessage reply = new MailMessage();

// if the original mail had a message ID,
// reference it using the InReplyTo field
if (original.MessageId != null)
    reply.InReplyTo.Add(original.MessageId);

// and compose the reply
reply.To = original.From;
reply.CC = original.CC;
reply.From = "robot@example.org";
reply.MessageId = new MessageId();
reply.Subject = "RE: " + original.Subject;
reply.BodyText = "Hello, I just received your mail!";

// we are now ready to send the message

VB.NET

'an e-mail we just received
Dim original As MailMessage = imap.GetMailMessage(sequenceNumber)

'create the reply
Dim reply As New MailMessage

'if the original mail had a message ID,
'reference it using the InReplyTo field
If Not (original.MessageId Is Nothing) Then
    reply.InReplyTo.Add(original.MessageId)
End If

'and compose the reply
reply.To = original.From
reply.CC = original.CC
reply.From.Add(New MailAddress("robot@example.org"))
reply.MessageId = New MessageId
reply.Subject = "RE: " & original.Subject
reply.BodyText = "Hello, I just received your mail!"

'we are now ready to send the message

back to top...


#Forwarding a message as an attachment

Often, there is a need to forward a message (or more) to another account. For this purpose, an Attachment can be created from an existing MailMassege and sent as a part of another message.

C#

// an e-mail we just received
MailMessage original = imap.GetMailMessage(sequenceNumber);

// create a new message
MailMessage forward = new MailMessage();

// initialize it
forward.To = "mary@example.org";
forward.From = "peter@example.org";
forward.Subject = "FW: " + original.Subject;
forward.BodyText = "Hello, I am forwarding this to you!";

// and add the original e-mail as an attachment
forward.Attachments.Add(new Attachment(original));

// we are now ready to send the message

VB.NET

'an e-mail we just received
Dim original As MailMessage = imap.GetMailMessage(sequenceNumber)

'create a new message
Dim forward As New MailMessage()

'initialize it
forward.To.Add(New MailAddress("mary@example.org"))
forward.From.Add(New MailAddress("peter@example.org"))
forward.Subject = "FW: " & original.Subject
forward.BodyText = "Hello, I am forwarding this to you!"

'and add the original e-mail as an attachment
forward.Attachments.Add(New Attachment(original))

'we are now ready to send the message

back to top...


#Custom headers - requesting a read receipt

Message headers are commonly used to store various e-mail metadata such as spam filtering score, mail agent name or other flags.

One of the headers can be used to request a delivery receipt for the message. This will make the recipient's mail client (such as Outlook) to notify us when the user reads the message. Please note that the reply is not mandatory - not all e-mail clients support it and those who do usually ask the user for a permission before sending the receipt. Even though, it is still a useful feature.

To enable the delivery notification, add the Disposition-Notification-To header with its value set to an e-mail address that will receive the message. Then send the message via SMTP.

C#

// create a new message
MailMessage message = new MailMessage();

// initialize it
message.From = "joe@example.org";
message.To = "bill@example.org";

// and request the read receipt
message.Headers.Add("Disposition-Notification-To", "joe@example.org");

VB.NET

'create a new message
Dim message As New MailMessage

'initialize it
message.From.Add(New MailAddress("joe@example.org"))
message.To.Add(New MailAddress("bill@example.org"))

'and request the read receipt
message.Headers.Add("Disposition-Notification-To", "joe@example.org")

back to top...


#Sending mail through IIS spool folder

This functionality is no supported in Rebex Mail for .NET Compact Framework.

If Microsoft IIS mail server or Exchange is running on the same machine where your Rebex Mail application is to be deployed, you can send the MailMessage by submitting it to the IIS spool folder. IIS will locate the message and deliver it.

C#

// create an instance of MailMessage
MailMessage message = new MailMessage();

// set its properties to desired values
message.From = "hugo@example.com";
message.To = "joe@example.com";
message.Subject = "We will send this using IIS";
message.BodyText = "Hello, Joe!";

// and send it using IIS pickup directory spool
MailSpool.Send(MailServerType.Iis, message);

VB.NET

'create an instance of MailMessage
Dim message As New MailMessage

'set its properties to desired values
message.From.Add(New MailAddress("hugo@example.com"))
message.To.Add(New MailAddress("joe@example.com"))
message.Subject = "We will send this using IIS"
message.BodyText = "Hello, Joe!"

'and send it using IIS pickup directory spool
MailSpool.Send(MailServerType.Iis, message)

back to top...


#Creating HTML mails with embedded images and CSS styles

This task can be quite tricky as there are many e-mail clients and every one of them has different behavior when it comes to reading these types of emails. Probably one of the most compatible ways to create these types of emails is to use content IDs - every image needs to be prefixed with "cid:", so the HTML would look like this: <img src="cid:1234@domain"> and CSS like this: background: url(cid:1234@domain). Even Outlook is able to display this without problems (which isn't the case for other methods - for example without the content ID prefixes).

C#

MailMessage message = new MailMessage();

LinkedResource picture = new LinkedResource(@"c:\temp\image.jpg", "image/jpeg");
picture.ContentId = "0123456789@rebex.net"; // a unique ID

AlternateView htmlView = new AlternateView();
htmlView.SetContent(
    "<html><body><img src='cid:0123456789@rebex.net'></body></html>",
    MediaTypeNames.Text.Html);

message.AlternateViews.Add(htmlView);
message.Resources.Add(picture);

VB.NET

Dim message As New MailMessage

Dim picture As LinkedResource
picture = New LinkedResource("c:\temp\image.jpg", "image/jpeg")
picture.ContentId = "0123456789@rebex.net" ' a unique ID

Dim htmlView As New AlternateView()
htmlView.SetContent( _
 "<html><body><img src='cid:0123456789@rebex.net'></body></html>", _
 MediaTypeNames.Text.Html)

message.AlternateViews.Add(htmlView)
message.Resources.Add(picture)

While it is also possible to create an e-mail with a detached and embedded CSS template this way, MS Outlook won't display it even with the content ID specified, even though Outlook Express displays it just fine. As far as we know, there is no way to make this work in Outlook. The obvious workaround is to include the CSS stylesheet inside the HTML code and this mostly works - but Outlook ignores any embedded images specified in this CSS, unfortunately, and it is not alone - Mozilla Thunderbird does the same thing. Outlook Express works just fine, though.

However, if the HTML and CSS is constructed with the following limitations in mind, desired result can be achieved:

  • use content IDs to reference images
  • include your CSS inside the HTML
  • only reference images from CSS in the "style" attribute of HTML elements (such as <div style='background:url(cid:0123456789@rebex.net)'>) or directly from <img> element (<img src='cid:0123456789@rebex.net'>)

back to top...


Back to tutorial list...