ASP.NET: Using pickup directory for outgoing e-mails
Sending e-mails out from web applications is very common task. When we are working on or test our systems with real e-mail addresses we don’t want recipients to receive e-mails (specially if we are using some subset of real data9. In this posting I will show you how to make ASP.NET SMTP client to write e-mails to disc instead of sending them out.
SMTP settings for web application
I have seen many times the code where all SMTP information is kept in app settings just to read them in code and give to SMTP client. It is not necessary because we can define all these settings under system.web => mailsettings node.
If you are using web.config to keep SMTP settings then all you have to do in your code is just to create SmtpClient with empty constructor.
var smtpClient = new SmtpClient();
Empty constructor means that all settings are read from web.config file.
What is pickup directory?
If you want drastically raise e-mail throughput of your SMTP server then it is not very wise plan to communicate with it using SMTP protocol. it adds only additional overhead to your network and SMTP server. Okay, clients make connections, send messages out and it is also overhead we can avoid.
If clients write their e-mails to some folder that SMTP server can access then SMTP server has e-mail forwarding as only resource-eager task to do. File operations are way faster than communication over SMTP protocol. The directory where clients write their e-mails as files is called pickup directory.
By example, Exchange server has support for pickup directories. And as there are applications with a lot of users who want e-mail notifications then .NET SMTP client supports writing e-mails to pickup directory instead of sending them out.
How to configure ASP.NET SMTP to use pickup directory?
Let’s say, it is more than easy. It is very easy. This is all you need.
<system.net>
<mailSettings>
<smtp deliveryMethod="SpecifiedPickupDirectory">
<specifiedPickupDirectory pickupDirectoryLocation="c:\temp\maildrop\"/>
</smtp>
</mailSettings>
</system.net>
Now make sure you don’t miss come points:
- Pickup directory must physically exist because it is not created automatically.
- IIS (or Cassini) must have write permissions to pickup directory.
- Go through your code and look for hardcoded SMTP settings. Also take a look at all places in your code where you send out e-mails that there are not some custom settings used for SMTP!
Also don’t forget that your mails will be written now to pickup directory and they are not sent out to recipients anymore.
Advanced scenario: configuring SMTP client in code
In some advanced scenarios you may need to support multiple SMTP servers. If configuration is dynamic or it is not kept in web.config you need to initialize your SmtpClient in code. This is all you need to do.
var smtpClient = new SmtpClient();
smtpClient.DeliveryMethod = SmtpDeliveryMethod.SpecifiedPickupDirectory;
smtpClient.PickupDirectoryLocation = pickupFolder;
Easy, isn’t it? i like when advanced scenarios end up with simple and elegant solutions but not with rocket science.
Note for IIS SMTP service
SMTP service of IIS is also able to use pickup directory. If you have set up IIS with SMTP service you can configure your ASP.NET application to use IIS pickup folder. In this case you have to use the following setting for delivery method.
SmtpDeliveryMethod.PickupDirectoryFromIis
You can set this setting also in web.config file.
<system.net>
<mailSettings>
<smtp deliveryMethod="PickupDirectoryFromIis" />
</mailSettings>
</system.net>
Conclusion
Who was still using different methods to avoid sending e-mails out in development or testing environment can now remove all the bad code from application and live on mail settings of ASP.NET. It is easy to configure and you have less code to support e-mails when you use built-in e-mail features wisely.