C# 调用client.Send()之前是否可以测试SmtpClient?

C# 调用client.Send()之前是否可以测试SmtpClient?,c#,email,smtpclient,C#,Email,Smtpclient,这与前几天我问的一个问题有关 我的新的相关问题是。。。如果我的应用程序的用户在防火墙后面或者其他原因导致line client.Send(mail)无法工作,该怎么办 行后: SmtpClient client = new SmtpClient("mysmtpserver.com", myportID); client.Credentials = new System.Net.NetworkCredential("myusername.com", "mypassword"); 在尝试发送之前,

这与前几天我问的一个问题有关

我的新的相关问题是。。。如果我的应用程序的用户在防火墙后面或者其他原因导致line client.Send(mail)无法工作,该怎么办

行后:

SmtpClient client = new SmtpClient("mysmtpserver.com", myportID);
client.Credentials = new System.Net.NetworkCredential("myusername.com", "mypassword");
在尝试发送之前,我可以做些什么来测试客户端吗

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

(我认为我和潜在的应用程序用户都没有能力调整防火墙设置。例如,他们在工作时安装应用程序,在工作时无法控制互联网)


-Adeena

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

编辑:


您将需要处理SmtpException。这有一个StatusCode属性,它是一个枚举,将告诉您发送()失败的原因。

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

捕获SmtpException异常,它将告诉您是否因为无法连接到服务器而失败


如果要在尝试之前检查是否可以打开与服务器的连接,请使用TcpClient和catch SocketExceptions。虽然我不认为这样做比仅仅从Smtp.Send中捕获问题有任何好处。

我认为如果您希望测试Smtp,那么您正在寻找一种方法来验证您的配置和网络可用性,而不实际发送电子邮件。不管怎样,这正是我所需要的,因为没有任何虚假的电子邮件是有意义的

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

注意:TCP套接字的内容归Peter A.Bromberg所有,配置读取的内容归以下人员所有:

助手:

public static class SmtpHelper
{
    /// <summary>
    /// test the smtp connection by sending a HELO command
    /// </summary>
    /// <param name="config"></param>
    /// <returns></returns>
    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);
    }

    /// <summary>
    /// test the smtp connection by sending a HELO command
    /// </summary>
    /// <param name="smtpServerAddress"></param>
    /// <param name="port"></param>
    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");
}
我也有这个需要

(它发送一个
直升机
,并检查是否有200、220或250):

使用SMTPConnectionTest;
if(SMTPConnection.Ok(“myhost”,25))
{
//准备好了吗
}
if(SMTPConnectionTester.Ok())//从in.config读取设置
{
//准备好了吗
}

但捕获异常的原因不是有其他原因吗。。。我知道这是一种特殊的可能性,我想把它当作自己的事情来处理。。。这有意义吗?我正在尝试实现事务性电子邮件发送者,但不能使用异常,因为测试应该位于事务流的不同部分。很好的解决方案。工作起来很有魅力,如果由于某种原因第一个SMTP服务器不可用,我可以轻松地在SMTP服务器之间切换。太好了。我将
Dns.GetHostEntry
更改为
Dns.GetHostAddresses
,如果传递了IP地址且未找到反向Dns条目,则速度更快且不会失败。请注意,由于使用了
套接字,此代码将随机失败。可用的
。此处是否未显示更多相关代码?C#编译器不知道什么是配置。我假设它是应用程序中配置类的一部分。我需要做什么来解决编译错误?我正在使用Visual Studio 2015。@octopusgrabbus您需要添加一个参考
System.Configuration
和一个
using System.Configuration语句到您的类。还需要
系统
系统.Net
系统.Net.Configuration
系统.Net.Sockets
系统.Text
使用
声明。嗯,可能是因为它已加载到您的应用程序,或者您需要在轮询的基础上验证与SMTP服务器的连接,你还没有电子邮件要发送,你想测试/确保你的发送能力,当你这样做的时候-这就是为什么.link不再存在的原因
using SMTPConnectionTest;

if (SMTPConnection.Ok("myhost", 25))
{
   // Ready to go
}

if (SMTPConnectionTester.Ok()) // Reads settings from <smtp> 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;
    }