Read system.net/mailSettings/smtp settings from web.config

There is a standard way of specifying SMTP settings in .NET applications. .NET uses config files (app.config or web.config in case of ASP.NET) and element to specify the appropriate SMTP parameters to send e-mail.

Sample configuration (in this case Gmail SMTP settings) looks as follows:

<configuration>

<system.net>
  <mailSettings>
    <smtp deliveryMethod="network" from="pam@gmail.com">
      <network
        host="smtp.gmail.com"
        port="465"
        enableSsl="true"
        userName="pam@gmail.com"
        password="password"
    />
    </smtp>
  </mailSettings>
</system.net>

</configuration>

If port attribute is omitted default value (25) is used. SMTP protocol typically uses ports 587 and 25 for non SSL connections, and port 465 for SSL ones.

Although Mail.dll SMTP component does not support reading from web.config directly, it is quite easy to read those settings programmatically and use them with Mail.dll classes.

Here’s the simple sample that reads from mailSettings section:

SmtpSection section = (SmtpSection)ConfigurationManager.GetSection("system.net/mailSettings/smtp");

string from = section.From;
string host = section.Network.Host;
int port = section.Network.Port;
bool enableSsl = section.Network.EnableSsl;
string user = section.Network.UserName;
string password = section.Network.Password;

Use web.config’s mailSettings with Mail.dll

In most cases you want to send email via SMTP server (DeliveryMethod set to SmtpDeliveryMethod.Network). Here’s the sample that uses web.config settings and Mail.dll’s STMP component to send an email message:

SmtpSection section = (SmtpSection)ConfigurationManager.GetSection("system.net/mailSettings/smtp");

IMail email = Fluent.Mail
            .Text("Hi, how are you?")
            .Subject("Hello")
            .To("to@example.com")
            .From(section.From)
            .Create();

using (Smtp client = new Smtp())
{
    client.Connect(section.Network.Host, section.Network.Port, 
        section.Network.EnableSsl);
    client.UseBestLogin(section.Network.UserName, section.Network.Password);
    client.SendMessage(email);
    client.Close();
}

IIS pickup folder

If you plan to use local IIS SMTP service to send emails you created using Mail.dll, you’ll need to save those emails to IIS pickup folder.

You can specify folder location explicitly using SpecifiedPickupDirectory.PickupDirectoryLocation (default location is “c:\Inetpub\mailroot\Pickup”). You can also use SmtpDeliveryMethod.PickupDirectoryFromIis constant – in this case we’ll get pickup folder location directly from IIS metabase.

Following is the code that recognizes different DeliveryMethods and acts accordingly:

SmtpSection section = (SmtpSection)ConfigurationManager.GetSection("system.net/mailSettings/smtp");
IMail email = Fluent.Mail
            .Text("Hi, how are you?")
            .Subject("Hello")
            .To("lesnikowski@limilabs.com")
            .From(section.From)
            .Create();

if (section.DeliveryMethod == SmtpDeliveryMethod.Network)
{
    using (Smtp client = new Smtp())
    {
        client.Connect(section.Network.Host, section.Network.Port, 
            section.Network.EnableSsl);
        client.UseBestLogin(section.Network.UserName, section.Network.Password);
        client.SendMessage(email);
        client.Close();
    }
}
else if (section.DeliveryMethod == SmtpDeliveryMethod.SpecifiedPickupDirectory)
{
    string pickupFolder = section.SpecifiedPickupDirectory.PickupDirectoryLocation;
    email.Save(Path.Combine(pickupFolder, "email.eml"));
}
else if (section.DeliveryMethod == SmtpDeliveryMethod.PickupDirectoryFromIis)
{
    Assembly system = AppDomain.CurrentDomain.GetAssemblies()
        .First(x => x.GetName().Name == "System");
    
    Type iisPickupType = Type.GetType(
        "System.Net.Mail.IisPickupDirectory, " 
        + system.GetName().FullName, 
        true);
    // -or- use fully qualified system assembly name directly:
    //Type iisPickupType = Type.GetType(
    //    "System.Net.Mail.IisPickupDirectory, " 
    //    + "System, Version=4.0.0.0, Culture=neutral, "
    //    + "PublicKeyToken=b77a5c561934e089",
    //    true);

    string pickupFolder = (string)iisPickupType.InvokeMember(
        "GetPickupDirectory", 
        BindingFlags.InvokeMethod | BindingFlags.Static | BindingFlags.NonPublic, 
        null, null, null);

    email.Save(Path.Combine(pickupFolder, "email.eml"));
}

Tags: , ,

3 Responses to “Read system.net/mailSettings/smtp settings from web.config”

  1. Martin Says:

    Being able to use system.net/mailSettings/smtp settings from web.config is definately useful and great to see.. its a shame that it couldn’t also successfully read from the section as I have a project where customized site settings are held in an extended appSettings file= “web-nichesettings.config” file to keep a clean separation of concerns.

    Having Mail.dll being able to hook up to SMTP in this way would keep the white label code even cleaner.

  2. Limilabs support Says:

    @Martin,

    ‘appSettings’ is a completely different section than ‘system.net’. ‘system.net’ section doesn’t support file attribute at all.

  3. Anthony Says:

    Tip for anyone using IIS/Pickup folder and working off the Mail.dll example above.

    If you are enumerating through a list of recipients you will want to create a unique file name for each email you save otherwise your loop will just keep overwriting the previous file you created.

    In c# you can use: Guid.NewGuid() to get a unique value.

    In the case of the Mail.dll example above you would write:

    string saveFile = Guid.NewGuid().ToString() + ".eml";
    email.Save(Path.Combine(pickupFolder, saveFile));
    

    Hope that helps somebody.

Questions?

Consider using our Q&A forum for asking any questions.