2010-12-06 25 views
37

Estoy construyendo una aplicación que necesita saber dinámicamente/programáticamente y usar diferentes configuraciones de SMTP al enviar correos electrónicos.Configuración de múltiples SMTP en web.config?

Estoy acostumbrado a usar el enfoque system.net/mailSettings, pero según tengo entendido, eso solo permite una definición de conexión SMTP a la vez, utilizada por SmtpClient().

Sin embargo, necesito más de un enfoque connectionStrings-like, donde puedo obtener un conjunto de configuraciones basadas en una clave/nombre.

¿Alguna recomendación? Estoy abierto a omitir el enfoque comercial SmtpClient/mailSettings, y creo que tendré que ...

Respuesta

58

Necesitaba tener diferentes configuraciones smtp en el web.config dependiendo del entorno: desarrollo, montaje y producción.

Esto es lo que terminé usando:

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

Luego, en código:

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

Perfecto. Agradable y simple. No hay necesidad de ningún código nuevo. – alphadogg

+0

Miko y @alphadog Tu respuesta parece funcionar para una situación similar que he encontrado, pero no sé cómo usar el código que Mikko especificó en su respuesta "return (SmtpSection) ...." ¿Podrías dar más detalles? Aunque tal vez no sea apropiado, voy a crear una "Respuesta" con el código que tengo en lugar de hacer una nueva pregunta sobre SO. – REMESQ

+19

@Mikko su código no está bien explicado. Cómo usar SmtpSection devuelto? – Tomas

1

Simplemente pase los detalles relevantes cuando esté listo para enviar el correo y almacene todos esos ajustes en los ajustes de la aplicación de web.config.

Por ejemplo, crear las diferentes AppSettings (como "EmailUsername1", etc.) en web.config, y usted será capaz de llamar a ellos de forma totalmente separada de la siguiente manera:

 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

que terminó la construcción de mi propio cargador de configuración personalizado que se usa en una clase EmailService. Los datos de configuración se pueden almacenar en web.config de manera muy similar a las cadenas de conexión, y se pueden extraer por nombre de forma dinámica.

3

Esto puede o no puede ayudar a alguien, pero en caso de que consiguió Aquí busco la configuración de Mandrill para múltiples configuraciones de smtp. Terminé creando una clase que hereda de la clase SmtpClient siguiendo el código de esta persona, que es realmente agradable: 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; 
    } 
} 

He aquí un ejemplo de cómo llamar a esto:

 [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

Solo una ayuda adicional: Debería declarar el espacio de nombres System.Net.Configuration para usar SmtpSection. Y también System.Net para NetworkCredential. –

+0

¿Qué pasa con el campo "de"? – talles

0

que tenían la misma necesidad y la respuesta marcada trabajado para mí.

hice estos cambios en la 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="[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> 

Entonces, tengo un hilo que envía el correo:

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

Gracias =)

9

Así es como yo uso y funciona bien para mí (la configuración es similar a la respuesta de Mikko):

  1. Primera como secciones de configuración:

    <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. entonces sería el mejor para crear una cierta clase de envoltura. Tenga en cuenta que la mayor parte del código de abajo fue tomada desde el código fuente de .NET para 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. Después, simplemente envía un correo electrónico:.

    nueva CustomSmtpClient ("correos") Enviar (nueva MailMessage())

Cuestiones relacionadas