How to Test Smtpclient Before Calling Client.Send()

Can I test SmtpClient before calling client.Send()?

I think this is a case where exception handling would be the preferred solution. You really don't know that it will work until you try, and failure is an exception.

Edit:

You'll want to handle SmtpException. This has a StatusCode property, which is an enum that will tell you why the Send() failed.

Testing SMTP server is running via C#

You can try saying EHLO to your server and see if it responds with 250 OK. Of course this test doesn't guarantee you that you will succeed sending the mail later, but it is a good indication.

And here's a sample:

class Program
{
static void Main(string[] args)
{
using (var client = new TcpClient())
{
var server = "smtp.gmail.com";
var port = 465;
client.Connect(server, port);
// As GMail requires SSL we should use SslStream
// If your SMTP server doesn't support SSL you can
// work directly with the underlying stream
using (var stream = client.GetStream())
using (var sslStream = new SslStream(stream))
{
sslStream.AuthenticateAsClient(server);
using (var writer = new StreamWriter(sslStream))
using (var reader = new StreamReader(sslStream))
{
writer.WriteLine("EHLO " + server);
writer.Flush();
Console.WriteLine(reader.ReadLine());
// GMail responds with: 220 mx.google.com ESMTP
}
}
}
}
}

And here's the list of codes to expect.

Synchronous SmtpClient send, doesn't hit SendCompleted handler

If you are sending synchronously then your completed handler will never fire because the associated event is only triggered for async calls.

In a synchronous call, just put whatever code you would have put in your handler after your call to Send:

client.Send(message);
//TODO: Put your handler code here.

How can I test C# SmtpClient code in Vista

Please see:

How can I save an email instead of sending when using SmtpClient?

Can I test SmtpClient before calling client.Send()?

SmtpClient sends email to junk

Loop over SmtpClient.Send()

The Papercut library will not be able to facilitate the behavior you're looking for because each time you call Send it will drop the current connection and establish another connection to the server and do the handshake anyway. Here's the source from their CodePlex repository:

public void Send()
{
string response;

Connect(session.Sender, 25);
response = Response();
if (response.Substring(0, 3) != "220")
throw new SmtpException(response);

Write("HELO {0}\r\n", Util.GetIPAddress());
response = Response();
if (response.Substring(0, 3) != "250")
throw new SmtpException(response);

Write("MAIL FROM:<{0}>\r\n", session.MailFrom);
response = Response();
if (response.Substring(0, 3) != "250")
throw new SmtpException(response);

session.Recipients.ForEach(address =>
{
Write("RCPT TO:<{0}>\r\n", address);
response = Response();
if (response.Substring(0, 3) != "250")
throw new SmtpException(response);
});

Write("DATA\r\n");
response = Response();
if (response.Substring(0, 3) != "354")
throw new SmtpException(response);

NetworkStream stream = GetStream();
stream.Write(session.Message, 0, session.Message.Length);

Write("\r\n.\r\n");
response = Response();
if (response.Substring(0, 3) != "250")
throw new SmtpException(response);

Write("QUIT\r\n");
response = Response();
if (response.IndexOf("221") == -1)
throw new SmtpException(response);
}

You could of course change the source to do what you are after considering it is open source.

The SMTP server requires a secure connection or the client was not authenticated. The server response was: 5.5.1 Authentication Required?

First check for gmail's security related issues. You may have enabled double authentication in gmail. Also check your gmail inbox if you are getting any security alerts. In such cases check other answer of @mjb as below

Below is the very general thing that i always check first for such issues

client.UseDefaultCredentials = true;

set it to false.

Note @Joe King's answer - you must set client.UseDefaultCredentials before you set client.Credentials



Related Topics



Leave a reply



Submit