我可以在调用client.Send()之前测试SmtpClient吗?

这与我前几天询问如何发送电子邮件的问题有关 。

我的新相关问题就是这个……如果我的应用程序的用户是在防火墙后面或者为什么行client.Send(mail)将无法正常工作…

线后:

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

在尝试发送之前,我可以做些什么来测试客户端?

我想把它放在一个try / catch循环中,但我宁愿做一个测试,然后弹出一个对话框说:无法访问smtp或类似的东西。

(我假设我,也不是我的应用程序用户,都有能力调整他们的防火墙设置。例如……他们在工作时安装应用程序,并且在工作时无法控制他们的互联网)

-Adeena

我认为这是一种exception处理将是首选解决方案的情况。 在你尝试之前,你真的不知道它会起作用,而失败是一个例外。

编辑:

你会想要处理SmtpException。 它有一个StatusCode属性,它是一个枚举,它将告诉你Send()失败的原因。

我认为,如果您要测试SMTP,那么您正在寻找一种方法来validation您的配置和网络可用性,而无需实际发送电子邮件。 任何方式都是我需要的,因为没有任何虚拟的电子邮件是有意义的。

在我的开发人员的建议下,我提出了这个解决方案。 一个小助手类,用法如下。 我在发送电子邮件的服务的OnStart事件中使用它。

注意:TCP套接字的功劳归功于Peter A. Bromberg, url为http://www.eggheadcafe.com/articles/20030316.asp ,配置读取内容的人员: 从app.config访问system.net设置以编程方式在C#中

帮手:

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

用法:

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

捕获SmtpExceptionexception,它会告诉您它是否因为无法连接到服务器而失败。

如果要在任何尝试之前检查是否可以打开与服务器的连接,请使用TcpClient并捕获SocketExceptions。 虽然我没有看到这样做有什么好处,只是从Smtp.Send中捕获问题。

您可以尝试发送HELO命令来测试服务器是否处于活动状态并且在发送电子邮件之前运行。 如果要检查用户是否存在,可以尝试使用VRFY命令,但由于安全原因,这通常在SMTP服务器上禁用。 进一步阅读: http : //the-welters.com/professional/smtp.html希望这会有所帮助。

我也有这个需要。

这是我制作的图书馆 (发送HELO并检查HELO或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; }