Domanda

Questo è legato a una domanda ho chiesto l'altro giorno su come inviare e-mail .

Il mio nuovo, domanda relativa è questa ... cosa succede se l'utente della mia applicazione è protetto da un firewall o di qualche altra ragione per cui la linea client.Send (mail) non funziona ...

Dopo le righe:

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

c'è qualcosa che posso fare per testare cliente prima di provare a inviare?

Ho pensato di mettere questo in un ciclo try / catch, ma preferirei fare una prova e poi apparire una finestra di dialogo dicendo: non può accedere smtp o qualcosa di simile.

(sto presumendo che né io, né il mio potenzialmente utente dell'applicazione, ha la possibilità di adeguare le proprie impostazioni del firewall. Per esempio ... che installare l'applicazione sul posto di lavoro e non hanno il controllo sulla loro Internet sul posto di lavoro)

-Adeena

È stato utile?

Soluzione

Credo che questo sia un caso in cui la gestione delle eccezioni sarebbe la soluzione preferita. Davvero non sai che funzionerà finché non si tenta, e il fallimento è un'eccezione.

Modifica:

Ti consigliamo di gestire SmtpException. Questa ha una proprietà StatusCode, che è un enum che vi dirà perché il Send () non è riuscita.

Altri suggerimenti

Credo che se si sta cercando di verificare l'SMTP è che si sta cercando un modo per convalidare la configurazione e la disponibilità della rete, senza in realtà l'invio di una e-mail. Qualsiasi modo che è quello che mi serviva in quanto non c'erano email fittizio che sarebbe di un senso.

Con il suggerimento del mio collega sviluppatore mi si avvicinò con questa soluzione. Una piccola classe di supporto con l'uso di seguito. L'ho usato durante l'evento OnStart di un servizio che invia messaggi di posta elettronica.

Nota: il credito per la roba socket TCP va a Peter A. Bromberg a http: / /www.eggheadcafe.com/articles/20030316.asp e la roba di configurazione lettura ai ragazzi qui: impostazioni System.Net accesso da app.config a livello di codice in 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;
    }
}

Utilizzo:

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

intercettare l'eccezione SmtpException, vi dirà se non è riuscito perché non si poteva connettersi al server.

Se si desidera verificare se è possibile aprire una connessione al server prima di ogni tentativo, Usa TcpClient e SocketExceptions cattura. Anche se non vedo alcun beneficio a fare questo vs problemi solo la cattura da Smtp.Send.

Si potrebbe provare a inviare un comando HELO per verificare se il server è attivo e in esecuzione prima di inviare l'e-mail. Se si vuole verificare se l'utente esiste si potrebbe provare con il comando VRFY, ma questo è spesso disattivato a server SMTP per motivi di sicurezza. Ulteriore lettura: http://the-welters.com/professional/smtp.html Spero che questo aiuti.

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

ho avuto anche questa necessità.

Ecco la biblioteca ho fatto (it invia un HELO e controlli per un 200, 220 o 250):

using SMTPConnectionTest;

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

if (SMTPConnectionTester.Ok()) // Reads settings from <smtp> in .config
{
    // Ready to go
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top