Migrating from System.Web.Mail to System.Net.Mail

I discovered how great the new System.Net.Mail namespace is this weekend.

The now obsoleted System.Web.Mail was just a wrapper around CDONTS. It worked pretty well. It would churn out messages into the C:\InetPub\MailRoot\Pickup folder. So in a web farm we would configure the smtp service to route mail to a "smarthost". In our case we configured the smart host to route the mail through our exchange server. You could write your own code to set the relay server most likely reading the setting from your web.config’s appSettings.

After upgrading a web project to ASP.NET 2.0 I noticed several warnings about System.Web.Mail being obsolete and I should use System.Net.Mail. Well, this turned out to be a brain dead simple thing to convert and in the end it works even better. Here is the old way:

MailMessage message = new MailMessage();

message.To = "to@foo.com";

message.From = "from@bar.com";

message.Subject = "Hello subject";

message.Body = "Hello body";

 

// you can set the relay server in code like this:

// SmtpMail.SmtpServer = ConfigurationSettings.AppSettings["SmtpServer"];

SmtpMail.Send(message);

All you have to do to convert is change your using statement from System.Web.Mail to System.Net.Mail and use and instance of SmtpClient class rather than the static SmtpMail class:

 

MailMessage message = new MailMessage();

message.To = "to@foo.com";

message.From = "from@bar.com";

message.Subject = "Hello subject";

message.Body = "Hello body";

 

SmtpClient smtp = new SmtpClient();

smtp.Send(message);

 

Not a lot of difference there. But here’s the cool thing. You can control how it sends the email with the web/app.config like this:

 

  <system.net>

    <mailSettings>

      <smtp deliveryMethod="Network">

        <network host="mail.mydomain.com" port="25" />

      </smtp>

      <!-- Use this setting for development

      <smtp deliveryMethod="SpecifiedPickupDirectory">

        <specifiedPickupDirectory pickupDirectoryLocation="C:\Temp" />

      </smtp>

      -->

    </mailSettings>

  </system.net>

 

Now I can have it drop the messages in a temp folder when I’m developing and have the production web.config relay the email through the main email server.

 

It’s also worth noting that the old System.Web.Mail.SmtpMail was single threaded. If you needed to do a lot of email processing it would totally suck. Take a look at what the send on the old one did:

 

public static void Send(MailMessage message)
{
      lock (SmtpMail._lockObject)
      {
            if (Environment.OSVersion.Platform != PlatformID.Win32NT)
            {
                  throw new PlatformNotSupportedException(SR.GetString("RequiresNT"));
            }
            if (Environment.OSVersion.Version.Major <= 4)
            {
                  SmtpMail.CdoNtsHelper.Send(message);
            }
            else
            {
                  SmtpMail.CdoSysHelper.Send(message);
            }
      }
} 

Yuck! This was a nice bottleneck. As apposed to:

public class SmtpClient
{
      // Events
      public event SendCompletedEventHandler SendCompleted;
 
      // Methods
      public void Send(MailMessage message);
      public void Send(string from, string recipients, string subject, string body);
      public void SendAsync(MailMessage message, object userToken);
      public void SendAsync(string from, string recipients, string subject, string body, object userToken);
      public void SendAsyncCancel();
}

SmtpClient is not a static class like SmtpMail was. So you can have many email sends going at the same time. Plus notice the Async versions of the Send method. This is much more conducive to NT services or Windows Forms applications that need to send emails.

 

8 Comments

  • Thanks! This is a kick ass article! Now I can build my long-desired newsletter service.

  • It is my understanding that the MailMessage object To: and From: have changed...



    The To: is now a collection of MailAdresses (so you'd add it as message.To.Add(&quot;email@email.com&quot;)



    The From: is a single MailAddress..



    Not sure how you got your code to compile, unless you're still using the old MailMessage?

  • Hi. Sorry, but that code isn't working. As Jason R said, it's impossible 'cause to and from are now different. The first thing is that the "to" property is now read only.

  • oMessage.To.Add(New MailAddress(sTo)) is a better way to access the To property.

  • Hi David,
    I would like to tap into your experience with a unique problem.

    I have a client that hosts their website with a 3rd party that does not support 'code behind'. I've created an .asp 'Address Change' form that I want to email to the client's email address when filled in correctly. My client hosts their own e-mail with MS Exchange.

    I use System.Web.Mail and pass an HTML forms page to the body.

    I tests fine locally with the 3rd party host's default SMTP Server as the address of the System.web.mail SMTP server (I guess it defaults to the client's network Exchange SMTP).

    It does not work when implemented on the Web. I cannot connect to the client's Exchange SMTP even with the proper CDO authentification.

    Does System.net.mail do this better? What does the web host have to have installed to run System.Net.mail?

    Any info would be appreciated.

    Tom

  • Hi David,

    I just sent a message regarding a problem with System.web.mail on a 3rd party web host.

    I neglected to include a return e-mail.

    Thanks Tom

  • Does anyone have experience in using System.Net.Mail in an SSIS script? We are getting the following error message when run from SQL Server.

    Date 7/15/2010 2:43:38 PM
    Log Job History (SSIS_EMAIL_QUEUE_SendEmail)

    Step ID 1
    Server XXX\SQL2008
    Job Name SSIS_EMAIL_QUEUE_SendEmail
    Step Name SendMail dev
    Duration 00:00:07
    Sql Severity 0
    Sql Message ID 0
    Operator Emailed
    Operator Net sent
    Operator Paged
    Retries Attempted 0

    Message
    Executed as user: XXX\SYSTEM. Microsoft (R) SQL Server Execute Package Utility Version 10.0.2531.0 for 32-bit Copyright (C) Microsoft Corp 1984-2005. All rights reserved. Started: 2:43:38 PM Error: 2010-07-15 14:43:45.33 Code: 0x00000004 Source: Send HTML Email Description: The binary code for the script is not found. Please open the script in the designer by clicking Edit Script button and make sure it builds successfully. End Error Error: 2010-07-15 14:43:45.33 Code: 0xC0024107 Source: Send HTML Email Description: There were errors during task validation. End Error DTExec: The package execution returned DTSER_FAILURE (1). Started: 2:43:38 PM Finished: 2:43:45 PM Elapsed: 6.75 seconds. The package execution failed. The step failed.

  • Well this is kind of old but I noticed that for System.Net.Mail its not a straightforward to change

    MailMessage message = new MailMessage();
    message.To.Add = New MailAddress("to@foo.com");
    message.From = New MailAddress("from@bar.com");
    message.Subject = "Hello subject";
    message.Body = "Hello body";

Comments have been disabled for this content.