When you think ASP, think...
Recent Articles
All Articles
ASP.NET Articles
ASPFAQs.com
Message Board
Related Web Technologies
User Tips!
Coding Tips
Search

Sections:
Book Reviews
Sample Chapters
Commonly Asked Message Board Questions
JavaScript Tutorials
MSDN Communities Hub
Official Docs
Security
Stump the SQL Guru!
Web Hosts
XML
Information:
Advertise
Feedback
Author an Article

ASP ASP.NET ASP FAQs Message Board Feedback
 
Print this Page!
Published: Wednesday, August 2, 2006

Sending Email in ASP.NET 2.0: HTML-Formatted Emails, Attachments, and Gracefully Handling SMTP Exceptions

By Scott Mitchell


Introduction


As detailed in last week's article, Sending Email in ASP.NET 2.0, the .NET Framework version 2.0 includes a new namespace (System.Net.Mail) and new classes for sending email. (The namespace (System.Web.Mail) and classes used in the .NET Framework version 1.x still exist for backwards compatibility.) Last week we examined how to use the MailMessage and SmtpClient classes in the System.Net.Mail namespace for sending simple, plain-text email messages.

This article looks at the more advanced email-related options. We'll see how to send HTML-formatted emails, how to include attachments, and how to gracefully handle SMTP exceptions when sending an email (such as invalid relay server credentials or if the relay server is offline). Read on to learn more!

This article assumes that you are already familiar with sending simple, plain-text 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...

- continued -

Sending HTML-Formatted Emails


In Sending Email in ASP.NET 2.0 we saw how to send plain-text emails by assigning the contents of the email to the MailMessage class's Body property. To send HTML-formatted emails, simply set the Body property to the HTML content to send, and then mark the MailMessage class's IsBodyHtml property to True.

To demonstrate sending an HTML-formatted message, I created a sample named HtmlEmail.aspx available for download at the end of this article. The germane code follows:

'(1) Create the MailMessage instance
Dim mm As New MailMessage(FromEmailAddress, ToEmailAddress)

'(2) Assign the MailMessage's properties
mm.Subject = "HTML-Formatted Email Demo Using the IsBodyHtml Property"
mm.Body = "<h2>This is an HTML-Formatted Email Send Using the <code>IsBodyHtml</code> Property</h2><p>Isn't HTML <em>neat</em>?</p><p>You can make all sorts of <span style=""color:red;font-weight:bold;"">pretty colors!!</span>.</p>"

mm.IsBodyHtml = True



'(3) Create the SmtpClient object
Dim smtp As New SmtpClient

'(4) Send the MailMessage (will use the Web.config settings)
smtp.Send(mm)

As you can see, simply set the Body property to the HTML content to send and the IsBodyHtml property to True, and you're done! The actual email content that gets sent to the relay server (and eventually down to the recipient's email client), looks something like the following:

x-sender: ToEmailAddress
x-receiver: FromEmailAddress
mime-version: 1.0
from: FromEmailAddress
to: ToEmailAddress
date: 25 Jul 2006 15:06:44 -0700
subject: HTML-Formatted Email Demo Using the IsBodyHtml Property
content-type: text/html; charset=us-ascii
content-transfer-encoding: quoted-printable

<h2>This is an HTML-Formatted Email Send Using the <code>IsBodyHtml</code>=
Property</h2><p>Isn't HTML <em>neat</em>?</p><p>You can make all sorts=
of <span style=3D"color:red;font-weight:bold;">pretty colors!!</span>.</p>

Viewing the Email Content Sent to the Relay Server
Interested in viewing the actual content sent to the relay server by the SmtpClient class (like the content shown above)? In Sending Email in ASP.NET 2.0 we discussed how the SmtpClient class can be configured to send the email to a relay server or have it dropped off in a specified directory. Using the latter option, we can explore the actual email content that would otherwise have been sent to the relay server. Check out the Web.config file in the code available for download at the end of this article - there's a commented out <smtp> element that shows how to configure the SmtpClient class to dump the email's contents to a specified directory.

The email client - assuming it supports HTML-formatted emails - will display the HTML content within the email.

The HTML-formatted email.

Caveats on Sending HTML-Formatted Emails
When sending HTML-formatted emails, understand that the HTML you see on your screen may differ quite a bit from what your recipients see. Most all email clients strip out potentially dangerous HTML content (ActiveX controls and the like), many prevent JavaScript from running, and most handle external styles poorly. For a more thorough discussion on potential problems with sending HTML-formatted emails, check out Top 10 HTML Email Mistakes and CSS and Email, Kissing in a Tree.

Including Attachments


The MailMessage class has an Attachments property that is a collection of Attachment class instances. You can attach an existing file on the web server to the email message or base the content's attachment on a Stream. To illustrate sending emails will attachments, I created a demo where the visitor can fill out a feedback-like form to have an email sent to administrator. However, this feedback form allows the visitor to pick a file from their computer to be attached to the email sent from the web page (much like how the web-based email web applications - Hotmail, GMail, etc. - allow you to attach a file from your computer when sending an email).

To allow the visitor to attach a file from their computer, we need to allow the user to upload a file from their machine to the web server. This can be easily accomplished using the FileUpload control (which is new to ASP.NET 2.0). Let's look at the declarative syntax used for creating the user interface for this demo:

<table border="0">
    <tr>
        <td><b>Your Email:</b></td>
        <td><asp:TextBox runat="server" ID="UsersEmail" Columns="30"></asp:TextBox></td>
    </tr>
    <tr>
        <td><b>File to Send:</b></td>
        <td>
            

<asp:FileUpload ID="AttachmentFile" runat="server" />


        </td>
    </tr>
    <tr>
        <td colspan="2">
            <b>Body:</b><br />
            <asp:TextBox runat="server" ID="Body" TextMode="MultiLine" Columns="55" Rows="10"></asp:TextBox>
        </td>
    </tr>
    <tr>
        <td colspan="2" align="center">
            <asp:Button runat="server" ID="SendEmail" Text="Send Feedback" />
        </td>
    </tr>
</table>

The FileUpload control renders as a <input type="file" ... /> HTML element, which, in the browser, is displayed as a textbox with a Browse button. When clicked, a dialog box is opened from which the user can pick a file from their computer.

The user is prompted for a file to upload.

After filling in the feedback form, selecting a file to upload, and clicking the "Send Feedback" button, a postback occurs, sending the contents of the selected file up to the web server. In the "Send Feedback" Button's Click event handler, a MailMessage object is created and an attachment is added. Since the FileUpload provides a Stream to the uploaded data, we can simply point the new Attachment object at this Stream. There's no need to save the uploaded file to the web server's file system.

'Make sure a file has been uploaded
If String.IsNullOrEmpty(AttachmentFile.FileName) OrElse AttachmentFile.PostedFile Is Nothing Then
    Throw New ApplicationException("Egad, a file wasn't uploaded... you should probably use more graceful error handling than this, though...")
End If

'(1) Create the MailMessage instance
Dim mm As New MailMessage(FromEmailAddress, ToEmailAddress)

'(2) Assign the MailMessage's properties
mm.Subject = "Emailing an Uploaded File as an Attachment Demo"
mm.Body = Body.Text
mm.IsBodyHtml = False

'Attach the file

mm.Attachments.Add(New Attachment(AttachmentFile.PostedFile.InputStream, AttachmentFile.FileName))



'(3) Create the SmtpClient object
Dim smtp As New SmtpClient

'(4) Send the MailMessage (will use the Web.config settings)
smtp.Send(mm)

The Attachment constructor overload used in the code sample above expects two inputs: a reference to the Stream that contains the data to attach, and the name to use for the attachment. The FileUpload's InputStream and FileName properties are used for these two values.

The email, which includes the attachment.

Handling SMTP Exceptions


When sending an email from an ASP.NET page, what happens if the relay server is down, or if the authentication information used is invalid? In the face of an SMTP error, the SmtpClient class will throw an SmtpException exception. To gracefully handle such problems, we can add exception handling code around the code that sends the email. If there's an SmtpException we can then display a more friendly and informative error message (or, perhaps, write the email's contents to a file to be sent later).

In the download at the end of this article I've included a demo that allows the visitor to specify the relay server to use, along with authentication information. If there's an error in attempting to send an email, a client-side alert box is displayed, explaining the problem. To test this out, enter an invalid relay server hostname or invalid credentials for a relay server that requires authentication.

Try
    '(1) Create the MailMessage instance
    Dim mm As New MailMessage(FromEmailAddress, ToEmailAddress)

    '(2) Assign the MailMessage's properties
    mm.Subject = "Test Email... DO NOT PANIC!!!1!!!111!!"
    mm.Body = "This is a test message..."
    mm.IsBodyHtml = False

    '(3) Create the SmtpClient object
    Dim smtp As New SmtpClient

    'Set the SMTP settings...
    smtp.Host = Hostname.Text
    If Not String.IsNullOrEmpty(Port.Text) Then
        smtp.Port = Convert.ToInt32(Port.Text)
    End If

    If Not String.IsNullOrEmpty(Username.Text) Then
        smtp.Credentials = New NetworkCredential(Username.Text, Password.Text)
    End If

    '(4) Send the MailMessage (will use the Web.config settings)
    smtp.Send(mm)

    'Display a client-side popup, explaining that the email has been sent
    ClientScript.RegisterStartupScript(Me.GetType(), "HiMom!", String.Format("alert('An test email has successfully been sent to {0}');", ToAddress.Replace("'", "\'")), True)

Catch smtpEx As SmtpException
    'A problem occurred when sending the email message
    ClientScript.RegisterStartupScript(Me.GetType(), "OhCrap", String.Format("alert('There was a problem in sending the email: {0}');", smtpEx.Message.Replace("'", "\'")), True)

Catch generalEx As Exception
    'Some other problem occurred
    ClientScript.RegisterStartupScript(Me.GetType(), "OhCrap", String.Format("alert('There was a general problem: {0}');", generalEx.Message.Replace("'", "\'")), True)
End Try

This code catches both SMTP-specific error messages and general ones (such as assigning invalid email addresses to the MailMessage object's To or From properties). In either case, a client-side alert box is displayed informing the user of the details of the error.

An error message is displayed in a client-side alert box.

Conclusion


In this article we saw how to send HTML-formatted emails, send emails with attachments, and gracefully handle exceptions arising from sending an email message. Sending an HTML-formatted email is as simple as specifying the HTML content in the Body property and setting the IsBodyHtml property to True. The real challenge comes in making sure the HTML content used is rendered as expected by the popular email clients. To add an attachment to an email, simply add an Attachment object to the MailMessage's Attachments collection. The data for the attachment can come from a file on the web server or from a Stream. Finally, to handle SMTP-level exceptions, add exception handling code that catches the SmtpException thrown by the SmtpClient class when unable to transport the message to the relay server.

For more on sending email in ASP.NET 2.0, be sure to read Sending Email in ASP.NET 2.0: Reply-To, Priority, and Read Receipts.

Happy Programming!

  • By Scott Mitchell


    Attachments


  • Download the complete code samples examined in this article (in ZIP format)
  • Suggested Readings


  • www.SystemNetMail.com (a great set of FAQs and samples for sending email using the System.Net.Mail namespace classes)
  • Sending Email in ASP.NET 2.0: Reply-To, Priority, and Read Receipts


  • ASP.NET [1.x] [2.0] | ASPMessageboard.com | ASPFAQs.com | Advertise | Feedback | Author an Article