¿Puedo probar SmtpClient antes de llamar a client.Send ()?

Esto está relacionado con una pregunta que hice el otro día sobre cómo enviar un correo electrónico .

Mi nueva pregunta relacionada es esta … ¿Qué pasa si el usuario de mi aplicación está detrás de un cortafuegos o alguna otra razón por la cual la línea cliente.Enviar (correo) no funcionará …

Después de las líneas:

SmtpClient client = new SmtpClient("mysmtpserver.com", myportID); client.Credentials = new System.Net.NetworkCredential("myusername.com", "mypassword"); 

¿hay algo que pueda hacer para probar al cliente antes de intentar enviar?

Pensé en poner esto en un ciclo de prueba / captura, pero preferiría hacer una prueba y luego abrir un cuadro de diálogo que dijera: no puedo acceder a smtp o algo así.

(Supongo que ni yo, ni potencialmente mi usuario de la aplicación, tengo la capacidad de ajustar la configuración de su firewall. Por ejemplo … instalan la aplicación en el trabajo y no tienen control sobre su internet en el trabajo)

-Adeena

Creo que este es un caso en el que el manejo de excepciones sería la solución preferida. Realmente no sabes que funcionará hasta que lo intentes, y el fracaso es una excepción.

Editar:

Querrá manejar SmtpException. Tiene una propiedad StatusCode, que es una enumeración que le indicará por qué no se pudo enviar Send ().

Creo que si buscas probar el SMTP es que estás buscando una manera de validar tu configuración y disponibilidad de red sin enviar un correo electrónico. De cualquier forma eso es lo que necesitaba ya que no había ningún correo electrónico falso que tuviera sentido.

Con la sugerencia de mi compañero desarrollador, se me ocurrió esta solución. Una pequeña clase de ayuda con el uso a continuación. Lo usé en el evento OnStart de un servicio que envía correos electrónicos.

Nota: el crédito para las cosas de socket TCP va a Peter A. Bromberg en http://www.eggheadcafe.com/articles/20030316.asp y la configuración leyó cosas a los chicos aquí: Acceda a la configuración de system.net desde app.config programáticamente en C #

Ayudante:

 public static class SmtpHelper { ///  /// test the smtp connection by sending a HELO command ///  ///  ///  public static bool TestConnection(Configuration config) { MailSettingsSectionGroup mailSettings = config.GetSectionGroup("system.net/mailSettings") as MailSettingsSectionGroup; if (mailSettings == null) { throw new ConfigurationErrorsException("The system.net/mailSettings configuration section group could not be read."); } return TestConnection(mailSettings.Smtp.Network.Host, mailSettings.Smtp.Network.Port); } ///  /// test the smtp connection by sending a HELO command ///  ///  ///  public static bool TestConnection(string smtpServerAddress, int port) { IPHostEntry hostEntry = Dns.GetHostEntry(smtpServerAddress); IPEndPoint endPoint = new IPEndPoint(hostEntry.AddressList[0], port); using (Socket tcpSocket = new Socket(endPoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp)) { //try to connect and test the rsponse for code 220 = success tcpSocket.Connect(endPoint); if (!CheckResponse(tcpSocket, 220)) { return false; } // send HELO and test the response for code 250 = proper response SendData(tcpSocket, string.Format("HELO {0}\r\n", Dns.GetHostName())); if (!CheckResponse(tcpSocket, 250)) { return false; } // if we got here it's that we can connect to the smtp server return true; } } private static void SendData(Socket socket, string data) { byte[] dataArray = Encoding.ASCII.GetBytes(data); socket.Send(dataArray, 0, dataArray.Length, SocketFlags.None); } private static bool CheckResponse(Socket socket, int expectedCode) { while (socket.Available == 0) { System.Threading.Thread.Sleep(100); } byte[] responseArray = new byte[1024]; socket.Receive(responseArray, 0, socket.Available, SocketFlags.None); string responseData = Encoding.ASCII.GetString(responseArray); int responseCode = Convert.ToInt32(responseData.Substring(0, 3)); if (responseCode == expectedCode) { return true; } return false; } } 

Uso:

 if (!SmtpHelper.TestConnection(ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None))) { throw new ApplicationException("The smtp connection test failed"); } 

Captura la excepción SmtpException, te dirá si falló porque no pudiste conectarte al servidor.

Si desea verificar si puede abrir una conexión con el servidor antes de cualquier bash, use TcpClient y capture SocketExceptions. Aunque no veo ningún beneficio al hacer esto frente a los problemas de Smtp.Send.

Podría intentar enviar un comando HELO para probar si el servidor está activo y ejecutándose antes para enviar el correo electrónico. Si desea verificar si el usuario existe, podría intentar con el comando VRFY, pero esto a menudo está deshabilitado en los servidores SMTP debido a razones de seguridad. Lectura adicional: http://the-welters.com/professional/smtp.html Espero que esto ayude.

También tuve esta necesidad.

Aquí está la biblioteca que hice (envía un HELO y comprueba un 200, 220 o 250):

 using SMTPConnectionTest; if (SMTPConnection.Ok("myhost", 25)) { // Ready to go } if (SMTPConnectionTester.Ok()) // Reads settings from  in .config { // Ready to go } 
  private bool isValidSMTP(string hostName) { bool hostAvailable= false; try { TcpClient smtpTestClient = new TcpClient(); smtpTestClient.Connect(hostName, 25); if (smtpTestClient.Connected)//connection is established { NetworkStream netStream = smtpTestClient.GetStream(); StreamReader sReader = new StreamReader(netStream); if (sReader.ReadLine().Contains("220"))//host is available for communication { hostAvailable= true; } smtpTestClient.Close(); } } catch { //some action like writing to error log } return hostAvailable; }