Sending Email in ASP.NET 2.0: Reply-To, Priority, and Read Receipts
By Scott Mitchell
Introduction
Email serves as a ubiquitous, asynchronous notification and information distribution system. Not surprisingly, there are
many web development scenarios where server-side code needs to generate an email and scuttle it off to the intended
recipient. Previous articles here on 4Guys have examined programmatically sending email messages in ASP.NET 1.x and
ASP.NET 2.0. See Sending Email from an ASP.NET Web Page
for ASP.NET 1.x examples; Sending
Email in ASP.NET 2.0 looks at code and scenarios for sending email from an ASP.NET
2.0 application.
The Sending Email in ASP.NET 2.0 article just covers the basics of sending email, illustrating how to define mail
settings in Web.config and how to create a page to send a simple, plain-text email. I followed up that initial
article with another one that delved into more advanced topics. Sending Emails in ASP.NET 2.0:
HTML-Formatted Emails, Attachments, and Gracefully Handling SMTP Exceptions showed readers how to send rich emails using
HTML, how to include attachments, and how to recover from errors that occur during the email sending process.
I was recently working with a client that needed to build a rather feature-rich email web page, one that included many of
the features found in stand-alone email clients like Microsoft Outlook. Some of these features included the ability to
request read receipts, to specify a Reply-To address, and to indicate the email's priority. These topics are covered in
this article. Read on to learn more!
This article assumes that you are already familiar with sending simple emails from an ASP.NET 2.0 web page; if not,
please first read Sending Email in ASP.NET 2.0 before
tackling this article...
A Word About SMTP Headers...
The three topics covered in this article - specifying a Reply-To address, setting the email's priority, and requesting
a read receipt - are all tasks that are accomplished using SMTP headers SMTP headers are additional bits of
information that are sent along with an email message and provide instructions to the SMTP server or the email client.
Except for the body of the email, all other information is transmitted through SMTP headers, including to To address,
the From address, the Subject, and so forth.
You can examine an email's headers in Outlook by right-clicking on an email message and choosing the Options item from the
context menu. The Internet Headers textbox lists the various SMTP headers.
The headers precede the body and take the following form:
Header: Value
For example, the Subject of the email is specified via the Subject SMTP header. Say that the email message's
subject is, "Check Out My Website!!11!". In the SMTP headers there would be the following entry:
Subject: Check Out My Website!!11!
The email client - Outlook, GMail, ThunderBird, whatever - determines the received email's subject by looking for that
particular header.
ASP.NET 2.0's MailMessage class includes a Headers
property from which the mail message's heaers can be inspected or modified prior to sending the message. For example, to
add a particular header, simply use the following code:
'(1) Create the MailMessage instance
Dim mm As New MailMessage(fromAddress, toAddress)
'(2) Add the header
mm.Headers.Add(headerName, headerValue)
Of course, you will rarely need to work directly with the Headers property because most of the headers that you'll
need to set are accessible through properties in the MailMessage class. For example, to specify the subject
simply set the Subject property. There's no need to manually add a Subject header via the
Headers collection.
The first two topics we'll look at in this article - specifying a Reply-To address and setting the email's priority -
can utilize existing properties in the MailMessage class. However, the final task - requesting a read receipt -
requires us to manually inject an SMTP header via the Headers property.
Specifying a Reply-To Address
Replying to an email message usually sends the response to the person who sent the email. However, there are scenarios
where you may want to have the reply go to an alternate email address. For example, if you are sending out an email on behalf
of someone else, you may want to have any replies go directly to the person you are sending out the email for. Specifying
a Reply-To email address is quite easy in ASP.NET: simply set the MailMessage class's
ReplyTo property
to the appropriate email address.
'(1) Create the MailMessage instance
Dim mm As New MailMessage(fromAddress, toAddress)
'(2) Assign the MailMessage's properties
mm.Subject = subject
mm.Body = body
'(3) Set the ReplyTo property mm.ReplyTo = New MailAddress("ENTER REPLY-TO ADDRESS HERE")
Notice that you have to set the ReplyTo property to a
MailAddress
object instance - you cannot just set it to a string. However, the MailAddress constructor can take in
the email address as a string, so you can simply assign the ReplyTo property to the email address using:
New MailAddress(address). The MailAddress constructor also includes
an overload that allows the display name to be specified (New MailAddress(address, displayName). Most email
clients display the display name, if present, instead of the email address.
Setting the ReplyTo property adds a Reply-To: replyToEmailAddress SMTP header to the
outgoing message. This header (and all of the other "core" email SMTP headers) is discussed in
RFC 822.
The download at the end of this article includes a working demo that shows the ReplyTo property in action.
If you use that demo and write an email from, say, mitchell@4guysfromrolla.com, and have the Reply-To set to, say,
billg@microsoft.com, the recipient of the email will see that it's from mitchell@4guysfromrolla.com. However, when they
reply to the email their reply will be directed to billg@microsoft.com, as the following screenshot shows:
Specifying the Email's Priority
Email messages can optionally include an Importance SMTP header that indicates the importance of a message. (Or, more precisely,
how important the sender believes the message to be!) The Importance SMTP header can have one of three values:
high, normal, or low. Many email clients will display a special icon next to those emails flagged with high or low importance.
Some email clients ignore this SMTP header altogether.
To specify a value for the Importance header, use the MailMessage's
Priority property.
This property must be assigned to one of the valid MailPriority
values of which - you guessed it - there are three: High, Normal, and Low.
The following code illustrates setting the priority to high.
'(1) Create the MailMessage instance
Dim mm As New MailMessage(fromAddress, toAddress)
'(2) Assign the MailMessage's properties
mm.Subject = subject
mm.Body = body
'(3) Set the Priority property to High mm.Priority = MailPriority.High
The following screenshot shows an email message that was sent with High priority. When viewing the message in Outlook,
a status message appears at the top of the email indicating that the message was sent with High importance.
Requesting a Read Receipt
Many email clients include a feature that allows you to request a receipt when your email is read by the recipient(s).
This mechanism works in the following way:
When you compose an email and request a read receipt, your email client sends along an additional SMTP header -
Disposition-Notification-To: sendReceiptToAddress.
Upon receiving and reading the email, the recipient's email client may or may not process the
Disposition-Notification-To header. (Some email clients just ignore this header.) Assuming that the
email client processed the Disposition-Notification-To header and that the recipient has not configured
their email client to reject sending read receipts, upon reading the email a short message will be automatically
sent from the recipient to the address specified in the Disposition-Notification-To header, indicating that
the email has been read.
What's important to understand here is that a read receipt request is just that - a request. The recipient may ignore
or deny the request.
There is no RequestReadReceipt property in the MailMessage class, so in order to
request one we need to manually add the Disposition-Notification-To header. As discussed in the
"A Word About SMTP Headers..." section earlier in this article, this is accomplished by using the Headers
property.
'(1) Create the MailMessage instance
Dim mm As New MailMessage(fromAddress, toAddress)
'(2) Assign the MailMessage's properties
mm.Subject = subject
mm.Body = body
If the email is received by a recipient whose email client understands read receipt requests and is configured to return
them, a read receipt email will be sent to sendReadReceiptToAddress.
The following screenshot shows the default response in Outlook when an email with a read request is received.
Conclusion
In this article we looked at performing some more advanced email-related features in ASP.NET 2.0. Except for the email
body, all other information is transmitted through SMTP headers. When sending an email using the MailMessage
class, you rarely have to worry about SMTP headers. Their complexity is abstracted away through the MailMessage
class's high-level properties. However, it is important to understand that these headers exist and how they work, because
there are situations - such as requesting a read receipt - in which there are no corresponding MailMessage
properties. In such cases, we need to work directly with the SMTP headers themselves, which is possible through the
MailMessage class's Headers property.