Подтвердить что ты не робот

Могу ли я тестировать SmtpClient перед вызовом client.Send()?

Это связано с вопросом, который я задал в другой день на как отправить электронную почту.

Мой новый, связанный с этим вопрос: что, если пользователь моего приложения находится за брандмауэром или по какой-то другой причине, почему строка client.Send(mail) не будет работать...

После строк:

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

есть ли что-то, что я могу сделать, чтобы протестировать клиента, прежде чем пытаться отправить?

Я подумал о том, чтобы поместить это в цикл try/catch, но я бы предпочел сделать тест, а затем открыть диалог, говорящий: не могу получить доступ к smtp или что-то в этом роде.

(Я предполагаю, что ни я, ни потенциально пользователь моего приложения не могут настроить свои настройки брандмауэра. Например... они устанавливают приложение на работу и не контролируют свой Интернет на работе)

-Adeena

4b9b3361

Ответ 1

Я думаю, что это случай, когда обработка исключений будет предпочтительным решением. Вы действительно не знаете, что он будет работать до тех пор, пока вы не попробуете, а сбой - исключение.

Edit:

Вы хотите обработать SmtpException. Это свойство StatusCode, которое представляет собой перечисление, которое сообщит вам, почему сбой Send() не удалось.

Ответ 2

Я думаю, что если вы хотите проверить SMTP, это значит, что вы ищете способ проверить свою конфигурацию и доступность сети, не отправив электронное письмо. В любом случае, что мне было нужно, так как не было никакого фиктивного письма, которое имело бы смысл.

С предложением моего коллеги-разработчика я придумал это решение. Небольшой вспомогательный класс с использованием ниже. Я использовал его в событии OnStart службы, которая отправляет электронные письма.

Примечание: кредит на материал сокета TCP идет на Peter A. Bromberg по адресу http://www.eggheadcafe.com/articles/20030316.asp, а файл конфига для ребята здесь: Доступ к параметрам system.net.net из app.config программно в С#

Помощник:

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

Ответ 3

Поймать исключение SmtpException, оно сообщит вам, было ли это неудачно, потому что вы не могли подключиться к серверу.

Если вы хотите проверить, можете ли вы открыть соединение с сервером перед любой попыткой, используйте TcpClient и уловите SocketExceptions. Хотя я не вижу никакой пользы для этого, а просто улавливаю проблемы с Smtp.Send.

Ответ 4

Вы можете попытаться отправить команду HELO, чтобы проверить, активен ли сервер и запускается до его отправки. Если вы хотите проверить, существует ли пользователь, вы можете попробовать с помощью команды VRFY, но это часто отключается на SMTP-серверах из-за соображений безопасности. Дальнейшее чтение: http://the-welters.com/professional/smtp.html Надеюсь, это поможет.

Ответ 5

У меня также была эта необходимость.

Здесь библиотека, которую я создал (она отправляет HELO и проверяет наличие 200, 220 или 250):

using SMTPConnectionTest;

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

if (SMTPConnectionTester.Ok()) // Reads settings from <smtp> in .config
{
    // Ready to go
}

Ответ 6

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