Practical ASP.NET

Getting E-Mail Out the Door

Having looked at how to prepare an e-mail object, Peter turns his attention to getting the message mailed to someone.

In a previous column ("The MailMessage Always Delivers"), I showed how you can create an e-mail message complete with attachments and multiple recipients using the MailMessage object. Of course, creating a message is no help to you unless you can send it -- which is the responsibility of the SmtpClient object. In fact, by using the SmtpClient, you can bypass creating a MailMessage object altogether for simple e-mails.

Logging In
.NET doesn't include an e-mail management system. Instead, the SmtpClient (found in the System.Net.Mail namespace, not in the System.Web.Mail namespace) lets you pass an e-mail to your e-mail management system to be mailed. When you create the SmtpClient, you can specify the URL or TCP/IP address of your SMTP server. This example references a server at "mail.company.com".

Once you've created your SmtpClient object, you can send an e-mail just by providing "to" and "from" addresses, a subject and a body, as this example does:

client.Send("[email protected]", _
                   "[email protected]", _
                  "A subject line", _
                  "The body of the e-mail")

If you want to create a more complicated e-mail (e.g., one with an attachment) you can just pass a MailMessage object (as described in more detail in the earlier column).

Many SMTP servers require users to provide some credentials (a user name and password) before they'll accept mail. You can pass credentials to the SMTP server one of three ways.

First, if the SMTP server is set up to recognize the user ID that ASP.NET is running under (typically "ASPNET" or "Network Service") then you can just pass the default credentials for the site. To trigger that behavior, just set the SmtpClient's UseDefaultCredentials property to True before calling the send method.

However, if you prefer, you can generate a set of credentials in your code by creating a NetworkCredential object and using it to set the SmtpClient object's Credentials property. This example logs on with the user ID "Fuller" and the password "abc123$".

If you're uncomfortable with embedding user IDs in your code, you can put the credentials in your web.config file where they can be encrypted by adding these tags (this example sets the "from" address, the server address, and the user ID and password):

<system.net>
   <mailSettings>
      <smtp from="[email protected]">
        <network host="mail.mysite.com" userName="Fuller" 
                        password="abc123$" />
      </smtp>
    </mailSettings>
<system.net>

Asynchronous Transmission
If you have a slow connection to your SMTP server, you can use an asynchronous send which doesn't wait for the SMTP server to respond. Be aware: You can't send another e-mail until the first e-mail has finished processing, so you can't use this method to improve responsiveness when sending multiple e-mails.

The asynchronous send requires one final, extra parameter compared to the standard Send method, which can be anything you want. This example sends a MailMessage object with the extra parameter set to "My Message":

client.SendAsync(mm, "My Message")

You'll also need to enable asynchronous operations for your page. I do that in the page directive in the .ASPX file by adding the Async attribute and setting it to true:

<%@ Page Language="VB" Async="true"...

You should probably check to see if your e-mail was sent successfully. To enable that, you'll need to declare your SmtpClient as a class-level variable using the WithEvents keyword:

Private WithEvents client As System.Net.Mail.SmtpClient

You can now catch the SendCompleted event that's fired when your send request finishes processing (either it succeeds or fails). The skeleton for the event handler looks like this.

The skeleton that's generated for you won't include the Shared keyword, so you'll have to add that yourself. There's a real possibility that this event will be fired after the rest of the code in your page has finished processing and has been removed from memory. Adding Shared to the method's signature allows the method to be called from the page's class without needing an instance of the page to be in memory.

Two properties on the e parameter are useful here: Error and UserState. If something goes wrong with your e-mail transmission, the Error property will have an Exception object that will tell you what happened; the UserState property will have that extra, final parameter you passed to the SendAsync method so you can determine which e-mail wasn't transmitted. If you do have an error, you can't assume that the page you sent the e-mail from is still available so you'll have to settle for writing the message out to a log file.

About the Author

Peter Vogel is a system architect and principal in PH&V Information Services. PH&V provides full-stack consulting from UX design through object modeling to database design. Peter tweets about his VSM columns with the hashtag #vogelarticles. His blog posts on user experience design can be found at http://blog.learningtree.com/tag/ui/.

comments powered by Disqus

Featured

  • Hands On: New VS Code Insiders Build Creates Web Page from Image in Seconds

    New Vision support with GitHub Copilot in the latest Visual Studio Code Insiders build takes a user-supplied mockup image and creates a web page from it in seconds, handling all the HTML and CSS.

  • Naive Bayes Regression Using C#

    Dr. James McCaffrey from Microsoft Research presents a complete end-to-end demonstration of the naive Bayes regression technique, where the goal is to predict a single numeric value. Compared to other machine learning regression techniques, naive Bayes regression is usually less accurate, but is simple, easy to implement and customize, works on both large and small datasets, is highly interpretable, and doesn't require tuning any hyperparameters.

  • VS Code Copilot Previews New GPT-4o AI Code Completion Model

    The 4o upgrade includes additional training on more than 275,000 high-quality public repositories in over 30 popular programming languages, said Microsoft-owned GitHub, which created the original "AI pair programmer" years ago.

  • Microsoft's Rust Embrace Continues with Azure SDK Beta

    "Rust's strong type system and ownership model help prevent common programming errors such as null pointer dereferencing and buffer overflows, leading to more secure and stable code."

  • Xcode IDE from Microsoft Archrival Apple Gets Copilot AI

    Just after expanding the reach of its Copilot AI coding assistant to the open-source Eclipse IDE, Microsoft showcased how it's going even further, providing details about a preview version for the Xcode IDE from archrival Apple.

Subscribe on YouTube

Upcoming Training Events