在web.config中设置多个SMTP设置?

39

我正在开发一个需要动态/编程方式知道并使用不同SMTP设置来发送电子邮件的应用程序。

我习惯于使用system.net/mailSettings方法,但据我所知,这只允许一次同时定义一个SMTP连接,由SmtpClient()使用。

然而,我需要更像connectionStrings一样的方法,可以根据关键字/名称提取一组设置。

有什么建议吗?我愿意跳过传统的SmtpClient/mailSettings方法,我认为我必须这样做...

8个回答

69

我需要根据环境(开发、测试和生产)在web.config中使用不同的smtp配置。

这是我最终使用的方法:

在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="mail1@temp.uri">
      <network host="..." defaultCredentials="false"/>
    </smtp_1>
    <smtp_2 deliveryMethod="Network" from="mail2@temp.uri">
      <network host="1..." defaultCredentials="false"/>
    </smtp_2>
    <smtp_3 deliveryMethod="Network" from="mail3@temp.uri">
      <network host="..." defaultCredentials="false"/>
    </smtp_3>
  </mailSettings>
</configuration>

然后在代码中:

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

Miko和@alphadog,你们的回答似乎适用于我遇到的类似情况,但我不知道如何使用Mikko在他的答案中指定的代码"return (SmtpSection)...."。你能详细说明一下吗?虽然可能不太合适,但我打算创建一个"Answer",而不是在SO上提出新问题。 - REMESQ
23
@Mikko,你的代码没有很好地解释。如何使用返回的SmtpSection? - Tomas

26
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);

只是额外的帮助:您需要声明System.Net.Configuration命名空间才能使用SmtpSection。还需要System.Net来使用NetworkCredential。 - Gautam Jain
“from”字段怎么样? - talles

17

这是我如何使用它,对我来说运行良好(设置与Mikko的答案类似):

  1. 首先设置配置部分:

<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>

  • 那么最好创建一个包装器。请注意,下面的大部分代码都来自于.NET的SmtpClient源代码这里

  • 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);
        }
    

    }

  • 然后只需发送电子邮件:

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


  • 3
    这可能会帮助到某些人,但如果您在寻找适用于多个SMTP配置的Mandrill设置,则我最终创建了一个继承自SmtpClient类的类,遵循这位朋友的代码,非常好:https://github.com/iurisilvio/mandrill-smtp.NET。请保留HTML标记。
        /// <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;
        }
    }
    

    以下是如何调用此功能的示例:
            [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 );
            }
        }
    

    2

    当您准备发送邮件时,只需传入相关详细信息,并将所有这些设置存储在您的应用程序设置或web.config中。例如,在web.config中创建不同的AppSettings(如“EmailUsername1”等),然后可以完全分别调用它们:

            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("someone@example.com");
    
            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);
    

    1

    我有同样的需求,标记的答案对我有用。

    我在这里做了一些更改:

    web.config:

          <configSections>
            <sectionGroup name="mailSettings2">
              <section name="noreply" type="System.Net.Configuration.SmtpSection"/>
            </sectionGroup>
            <section name="othersection" type="SomeType" />
          </configSections>
    
          <mailSettings2>
            <noreply deliveryMethod="Network" from="noreply@host.com"> // noreply, in my case - use your mail in the condition bellow
              <network enableSsl="false" password="<YourPass>" host="<YourHost>" port="25" userName="<YourUser>" defaultCredentials="false" />
            </noreply>
          </mailSettings2>
          ... </configSections>
    

    然后,我有一个线程发送邮件:

    SomePage.cs

    private bool SendMail(String From, String To, String Subject, String Html)
        {
            try
            {
                System.Net.Mail.SmtpClient SMTPSender = null;
    
                if (From.Split('@')[0] == "noreply")
                {
                    System.Net.Configuration.SmtpSection smtpSection = (SmtpSection)ConfigurationManager.GetSection("mailSettings2/noreply");
                    SMTPSender = new System.Net.Mail.SmtpClient(smtpSection.Network.Host, smtpSection.Network.Port);
                    SMTPSender.Credentials = new System.Net.NetworkCredential(smtpSection.Network.UserName, smtpSection.Network.Password);
                    System.Net.Mail.MailMessage Message = new System.Net.Mail.MailMessage();
                    Message.From = new System.Net.Mail.MailAddress(From);
    
                    Message.To.Add(To);
                    Message.Subject = Subject;
                    Message.Bcc.Add(Recipient);
                    Message.IsBodyHtml = true;
                    Message.Body = Html;
                    Message.BodyEncoding = Encoding.GetEncoding("ISO-8859-1");
                    Message.SubjectEncoding = Encoding.GetEncoding("ISO-8859-1");
                    SMTPSender.Send(Message);
    
                }
                else
                {
                    SMTPSender = new System.Net.Mail.SmtpClient();
                    System.Net.Mail.MailMessage Message = new System.Net.Mail.MailMessage();
                    Message.From = new System.Net.Mail.MailAddress(From);
    
                    SMTPSender.EnableSsl = SMTPSender.Port == <Port1> || SMTPSender.Port == <Port2>;
    
                    Message.To.Add(To);
                    Message.Subject = Subject;
                    Message.Bcc.Add(Recipient);
                    Message.IsBodyHtml = true;
                    Message.Body = Html;
                    Message.BodyEncoding = Encoding.GetEncoding("ISO-8859-1");
                    Message.SubjectEncoding = Encoding.GetEncoding("ISO-8859-1");
                    SMTPSender.Send(Message);
                }
            }
            catch (Exception Ex)
            {
                Logger.Error(Ex.Message, Ex.GetBaseException());
                return false;
            }
            return true;
        }
    

    谢谢 =)

    0

    最终我自己构建了一个定制的配置加载器,它被用在一个EmailService类中。配置数据可以像连接字符串一样存储在web.config文件中,并且可以根据名称动态获取。


    -1

    网页内容由stack overflow 提供, 点击上面的
    可以查看英文原文,
    原文链接