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
Apiresource VS APIscope VS Identityresource
How to Drag and Drop a Button from One Panel to Another Panel
Disabling Screen Saver and Power Options in C#
Open Link in New Tab (Webbrowser Control)
Linq to Find Series of Consecutive Numbers
MVC 4 How Pass Data Correctly from Controller to View
System.Drawing in Windows or ASP.NET Services
Alternative to Multiple String.Replaces
Best Practice: Convert Linq Query Result to a Datatable Without Looping
How Can a Windows Service Determine Its Servicename
How to Get Around Lack of Covariance with Ireadonlydictionary
Performance Cost of 'Try' in C#
Simple Way to Display Row Numbers on Wpf Datagrid
Disable Transitive Project Reference in .Net Standard 2
C# - Static Types Cannot Be Used as Type Arguments