23

これは、先日メールの送信方法について質問したことに関連しています。

私の新しい関連する質問はこれです...私のアプリケーションのユーザーがファイアウォールの背後にいる場合、または client.Send(mail) という行が機能しないその他の理由がある場合はどうなりますか...

行の後:

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

送信する前にクライアントをテストするためにできることはありますか?

これをtry/catchループに入れることを考えましたが、テストを行ってから、smtpなどにアクセスできないというダイアログをポップアップしたいと思います。

(私も、潜在的に私のアプリケーション ユーザーも、ファイアウォール設定を調整する能力を持っていないと推測しています。たとえば、彼らは職場でアプリをインストールし、職場でインターネットを制御することはできません)。

-アディーナ

4

6 に答える 6

44

SMTP をテストしようとしているのであれば、実際に電子メールを送信せずに構成とネットワークの可用性を検証する方法を探していると思います。意味のあるダミーメールがなかったので、それが私が必要としていた方法です。

私の仲間の開発者の提案で、私はこの解決策を思いつきました。以下の使用法を持つ小さなヘルパー クラス。メールを送信するサービスのOnStartイベントで使用しました。

注: TCP ソケット関連の功績は Peter A. Bromberg ( http://www.eggheadcafe.com/articles/20030316.asp ) にあり、構成の読み取り関連はここにあります: app.config から system.net 設定にアクセスします。プログラムで C#

ヘルパー:

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");
}
于 2010-05-18T20:29:04.893 に答える
8

これは、例外処理が望ましい解決策になるケースだと思います。実際に試してみるまで、それが機能するかどうかはわかりません。失敗は例外です。

編集:

SmtpException を処理する必要があります。これには、Send() が失敗した理由を示す列挙型である StatusCode プロパティがあります。

于 2008-12-16T21:16:49.643 に答える
2

電子メールを送信する前に、サーバーがアクティブで実行されているかどうかをテストするために、HELO コマンドを送信してみることができます。ユーザーが存在するかどうかを確認したい場合は、VRFY コマンドを試すことができますが、これはセキュリティ上の理由から SMTP サーバーでは無効になっていることがよくあります。さらに読む: http://the-welters.com/professional/smtp.html これがお役に立てば幸いです。

于 2008-12-16T21:28:00.773 に答える
2

SmtpException 例外をキャッチします。サーバーに接続できなかったために失敗したかどうかがわかります。

試行する前にサーバーへの接続を開くことができるかどうかを確認したい場合は、TcpClient を使用して SocketExceptions をキャッチします。これを行うことと、Smtp.Send から問題をキャッチすることには何のメリットもありません。

于 2008-12-16T21:30:16.650 に答える