Setting multiple SMTP settings in web.config?

40,962

Solution 1

I needed to have different smtp configurations in the web.config depending on the environment: dev, staging and production.

Here's what I ended up using:

In web.config:

<configuration>
  <configSections>
    <sectionGroup name="mailSettings">
      <section name="smtp_1" type="System.Net.Configuration.SmtpSection"/>
      <section name="smtp_2" type="System.Net.Configuration.SmtpSection"/>
      <section name="smtp_3" type="System.Net.Configuration.SmtpSection"/>
    </sectionGroup>
  </configSections>
  <mailSettings>
    <smtp_1 deliveryMethod="Network" from="[email protected]">
      <network host="..." defaultCredentials="false"/>
    </smtp_1>
    <smtp_2 deliveryMethod="Network" from="[email protected]">
      <network host="1..." defaultCredentials="false"/>
    </smtp_2>
    <smtp_3 deliveryMethod="Network" from="[email protected]">
      <network host="..." defaultCredentials="false"/>
    </smtp_3>
  </mailSettings>
</configuration>

Then in code:

return (SmtpSection)ConfigurationManager.GetSection("mailSettings/smtp_1");
return (SmtpSection)ConfigurationManager.GetSection("mailSettings/smtp_2");
return (SmtpSection)ConfigurationManager.GetSection("mailSettings/smtp_3");

Solution 2

SmtpSection smtpSection =  (SmtpSection)ConfigurationManager.GetSection("mailSettings/smtp_1");

SmtpClient smtpClient = new SmtpClient(smtpSection.Network.Host, smtpSection.Network.Port);
smtpClient.Credentials = new NetworkCredential(smtpSection.Network.UserName, smtpSection.Network.Password);

Solution 3

This is how i use it and it works fine for me (settings are similar to Mikko answer):

  1. First set up config sections:

    <configuration>
      <configSections>
        <sectionGroup name="mailSettings">
          <section name="default" type="System.Net.Configuration.SmtpSection" />
          <section name="mailings" type="System.Net.Configuration.SmtpSection" />
          <section name="partners" type="System.Net.Configuration.SmtpSection" />
        </sectionGroup>
      </configSections>
    <mailSettings>
      <default deliveryMethod="Network">
        <network host="smtp1.test.org" port="587" enableSsl="true"
               userName="test" password="test"/>
      </default>
      <mailings deliveryMethod="Network">
        <network host="smtp2.test.org" port="587" enableSsl="true"
               userName="test" password="test"/>
      </mailings>
    <partners deliveryMethod="Network">
      <network host="smtp3.test.org" port="587" enableSsl="true"
               userName="test" password="test"/>
    </partners>
    

  2. Then it would be the best to create a some sort of wrapper. Note that most of code below was taken from .NET source code for SmtpClient here

    public class CustomSmtpClient
    {
        private readonly SmtpClient _smtpClient;
    
        public CustomSmtpClient(string sectionName = "default")
        {
            SmtpSection section = (SmtpSection)ConfigurationManager.GetSection("mailSettings/" + sectionName);
    
            _smtpClient = new SmtpClient();
    
            if (section != null)
            {
                if (section.Network != null)
                {
                    _smtpClient.Host = section.Network.Host;
                    _smtpClient.Port = section.Network.Port;
                    _smtpClient.UseDefaultCredentials = section.Network.DefaultCredentials;
    
                    _smtpClient.Credentials = new NetworkCredential(section.Network.UserName, section.Network.Password, section.Network.ClientDomain);
                    _smtpClient.EnableSsl = section.Network.EnableSsl;
    
                    if (section.Network.TargetName != null)
                        _smtpClient.TargetName = section.Network.TargetName;
                }
    
                _smtpClient.DeliveryMethod = section.DeliveryMethod;
                if (section.SpecifiedPickupDirectory != null && section.SpecifiedPickupDirectory.PickupDirectoryLocation != null)
                    _smtpClient.PickupDirectoryLocation = section.SpecifiedPickupDirectory.PickupDirectoryLocation;
            }
        }
    
        public void Send(MailMessage message)
        {
            _smtpClient.Send(message);
        }
    

    }

  3. Then simply send email:

    new CustomSmtpClient("mailings").Send(new MailMessage())

Solution 4

This may or may not help someone but in case you got here looking for Mandrill setup for multiple smtp configurations I ended up creating a class that inherits from the SmtpClient class following this persons code here which is really nice: https://github.com/iurisilvio/mandrill-smtp.NET

    /// <summary>
/// Overrides the default SMTP Client class to go ahead and default the host and port to Mandrills goodies.
/// </summary>
public class MandrillSmtpClient : SmtpClient
{

    public MandrillSmtpClient( string smtpUsername, string apiKey, string host = "smtp.mandrillapp.com", int port = 587 )
        : base( host, port )
    {

        this.Credentials = new NetworkCredential( smtpUsername, apiKey );

        this.EnableSsl = true;
    }
}

Here's an example of how to call this:

        [Test]
    public void SendMandrillTaggedEmail()
    {

        string SMTPUsername = _config( "MandrillSMTP_Username" );
        string APIKey = _config( "MandrillSMTP_Password" );

        using( var client = new MandrillSmtpClient( SMTPUsername, APIKey ) ) {

            MandrillMailMessage message = new MandrillMailMessage() 
            { 
                From = new MailAddress( _config( "FromEMail" ) ) 
            };

            string to = _config( "ValidToEmail" );

            message.To.Add( to );

            message.MandrillHeader.PreserveRecipients = false;

            message.MandrillHeader.Tracks.Add( ETrack.opens );
            message.MandrillHeader.Tracks.Add( ETrack.clicks_all );

            message.MandrillHeader.Tags.Add( "NewsLetterSignup" );
            message.MandrillHeader.Tags.Add( "InTrial" );
            message.MandrillHeader.Tags.Add( "FreeContest" );


            message.Subject = "Test message 3";

            message.Body = "love, love, love";

            client.Send( message );
        }
    }

Solution 5

Just pass in the relevant details when you are ready to send the mail, and store all of those settings in your app setttings of web.config.

For example, create the different AppSettings (like "EmailUsername1", etc.) in web.config, and you will be able to call them completely separately as follows:

        System.Net.Mail.MailMessage mail = null;
        System.Net.Mail.SmtpClient smtp = null;

        mail = new System.Net.Mail.MailMessage();

        //set the addresses
        mail.From = new System.Net.Mail.MailAddress(System.Configuration.ConfigurationManager.AppSettings["Email1"]);
        mail.To.Add("[email protected]");

        mail.Subject = "The secret to the universe";
        mail.Body = "42";

        //send the message
        smtp = new System.Net.Mail.SmtpClient(System.Configuration.ConfigurationManager.AppSettings["YourSMTPServer"]);

        //to authenticate, set the username and password properites on the SmtpClient
        smtp.Credentials = new System.Net.NetworkCredential(System.Configuration.ConfigurationManager.AppSettings["EmailUsername1"], System.Configuration.ConfigurationManager.AppSettings["EmailPassword1"]);
        smtp.UseDefaultCredentials = false;
        smtp.Port = System.Configuration.ConfigurationManager.AppSettings["EmailSMTPPort"];
        smtp.EnableSsl = false;

        smtp.Send(mail);
Share:
40,962
alphadogg
Author by

alphadogg

Alphadogg loves macrame, scrapbooking and tearing flesh off forest creatures while pack hunting.

Updated on March 28, 2020

Comments

  • alphadogg
    alphadogg about 4 years

    I am building an app that needs to dynamically/programatically know of and use different SMTP settings when sending email.

    I'm used to using the system.net/mailSettings approach, but as I understand it, that only allows one SMTP connection definition at a time, used by SmtpClient().

    However, I need more of a connectionStrings-like approach, where I can pull a set of settings based on a key/name.

    Any recommendations? I'm open to skipping the tradintional SmtpClient/mailSettings approach, and I think will have to...

  • REMESQ
    REMESQ over 12 years
    Miko and @alphadog Your answer would seem to work for a similar situation I have encountered, but I don't know how to use the code Mikko specified in his answer "return (SmtpSection)...." Could you elaborate? Although maybe not appropriate, I am going to create an "Answer" with the code I have rather than ask a new question on SO.
  • Tomas
    Tomas almost 12 years
    @Mikko your code is not well explained. How to use returned SmtpSection?
  • Gautam Jain
    Gautam Jain over 10 years
    Just an additional help: You would need to declare System.Net.Configuration namespace to use SmtpSection. And also System.Net for NetworkCredential.
  • talles
    talles almost 7 years
    What about the "from" field?