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.