Mail Message Tutorial
Applies to: Rebex Total Pack, Rebex Mail Pack, Rebex IMAP, Rebex POP3, Rebex EWS, Rebex Graph, Rebex SMTP, Rebex MSG
Table of content
- Namespaces and assemblies
- Creating a simple mail message
- Working with attachments
- Creating a more advanced mail message
- Loading and saving messages
- Replying to a message
- Forwarding a message as an attachment
- Custom headers - requesting a read receipt
- Sending mail through IIS spool folder
- Creating HTML mails with embedded images and CSS styles
Namespaces and assemblies
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:
using Rebex.Mail; using Rebex.Mime.Headers;
Imports Rebex.Mail Imports Rebex.Mime.Headers
Creating a simple mail message
Creating a mail message is simple.
// 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>!";
'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.
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.
// 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"));
'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.
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.
// 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);
'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.
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.
// 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);
'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)
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.
// 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
'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
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.
// 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
'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
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.
// 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");
'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")
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.
// 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);
'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)
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).
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);
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 tutorial list...