2010-12-06 110 views
37

我正在構建一個應用程序,它需要在發送電子郵件時動態/編程式地瞭解並使用不同的SMTP設置。在web.config中設置多個SMTP設置?

我習慣使用system.net/mailSettings方法,但據我所知,它只允許一次使用SmtpClient()使用的一個SMTP連接定義。

但是,我需要更多的類似connectionStrings的方法,我可以根據一個鍵/名稱來提取一組設置。

有什麼建議嗎?我打算跳過傳統的SmtpClient/mailSettings方法,我認爲必須...

回答

58

我需要在web.config中有不同的smtp配置,具體取決於環境:dev,staging和production。

這裏是我最終使用:

在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> 
代碼

然後:

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

完美。很好很簡單。不需要任何新代碼。 – alphadogg 2011-01-07 13:31:01

+0

Miko和@alphadog您的答案似乎適用於我遇到過的類似情況,但我不知道如何使用代碼Mikko在回答「return(SmtpSection)....」中指定的代碼。「您能詳細說明一下嗎?雖然可能不合適,但我會用我自己的代碼創建一個「答案」,而不是在SO上提出一個新問題。 – REMESQ 2012-02-07 13:27:08

1

只要在準備發送郵件時傳遞相關的詳細信息,並將所有這些設置存儲在web.config的應用程序設置中即可。

例如,創建不同的AppSettings(如「EmailUsername1」等)在web.config中,你將能夠完全獨立地稱他們爲:

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

我結束了我的構建自己的定製配置加載器在EmailService類中使用。配置數據可以像連接字符串一樣存儲在web.config中,並且可以動態地通過名稱來引用。

3

這可能會或可能不會幫助別人,但如果你有在這裏尋找多個smtp配置的Mandrill設置我最終創建了一個繼承自此人員代碼的SmtpClient類的類,這非常好: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; 
    } 
} 

下面是如何調用這個例子:

 [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); 
     } 
    } 
21
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); 
0

我有同樣的需求和標記答案爲我工作。

我做的

網絡這些變化。配置:

 <configSections> 
     <sectionGroup name="mailSettings2"> 
      <section name="noreply" type="System.Net.Configuration.SmtpSection"/> 
     </sectionGroup> 
     <section name="othersection" type="SomeType" /> 
     </configSections> 

     <mailSettings2> 
     <noreply deliveryMethod="Network" from="[email protected]"> // 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; 
    } 

謝謝=)

9

這是我如何使用它和它適用於我(設置類似於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> 
    

  2. 然後將是最好創建某種包裝的。請注意,大部分的代碼下面是從.NET源代碼採取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. 然後,只需發送電子郵件:

    新CustomSmtpClient( 「郵件」)發送(MAILMESSAGE新())