Pergunta

Isso está relacionado a uma pergunta que fiz no outro dia em como enviar e-mail .

Meu, pergunta relacionada novo é este ... e se o usuário do meu aplicativo está atrás de um firewall ou algum outro motivo pelo qual o client.Send line (e-mail) não vai funcionar ...

Depois das linhas:

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

Existe algo que eu possa fazer para cliente de teste antes de tentar enviar?

Eu pensei em colocar isso em um loop try / catch, mas eu prefiro fazer um teste e, em seguida, aparecer uma janela dizendo: não é possível o acesso SMTP ou algo parecido.

(estou presumindo que nem eu, nem potencialmente meu usuário do aplicativo, tem a capacidade de ajustar suas configurações de firewall. Por exemplo ... eles instalar o aplicativo no trabalho e não tem controle sobre sua internet no trabalho)

-Adeena

Foi útil?

Solução

Eu acho que este é um caso em que a manipulação de exceção seria a solução preferida. Você realmente não sei o que ele vai trabalhar até que você tente, eo fracasso é uma exceção.

Editar:

Você vai querer lidar com SmtpException. Isto tem uma propriedade StatusCode, que é uma enumeração que irá dizer-lhe por que o Send () falhou.

Outras dicas

Eu acho que se você estiver olhando para testar o SMTP é que você está procurando uma forma de validar a sua configuração e disponibilidade de rede sem enviar um e-mail. Qualquer forma que é o que eu precisava desde que não havia nenhum e-mail fictício que faria sentido feito.

Com a sugestão do meu colega desenvolvedor eu vim com essa solução. A classe auxiliar pequena com o uso abaixo. Usei-o no evento OnStart de um serviço que envia e-mails.

Nota: o crédito para as coisas socket TCP vai para Peter A. Bromberg em http: / /www.eggheadcafe.com/articles/20030316.asp ea configuração ler coisas para os caras aqui: configurações de Acesso system.net de app.config programação em C #

Helper:

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

Uso:

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

capturar a exceção SmtpException, ele vai dizer se ele falhou porque você não pôde se conectar ao servidor.

Se você quiser verificar se você pode abrir uma conexão com o servidor antes de qualquer tentativa, Use TcpClient e SocketExceptions captura. Embora eu não vejo nenhum benefício para fazer isso vs apenas recuperar problemas de Smtp.Send.

Você poderia tentar enviar um comando HELO para testar se o servidor está ativo e em execução antes de enviar o e-mail. Se você quiser verificar se o usuário existe, você pode tentar com o comando VRFY, mas isso muitas vezes é desativado em servidores SMTP devido a razões de segurança. Outras leituras: http://the-welters.com/professional/smtp.html Espero que isso ajude.

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

Eu também tive essa necessidade.

Aqui está a biblioteca Eu fiz (é enviar um HELO e verifica se há um 200, 220 ou 250) :

using SMTPConnectionTest;

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

if (SMTPConnectionTester.Ok()) // Reads settings from <smtp> in .config
{
    // Ready to go
}
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top