Send mail with Gmail SMTP using MailKit SMTP Client in .NET core 2.2 is not working for me

GetTaxSolutions picture GetTaxSolutions · Mar 27, 2019 · Viewed 9.8k times · Source

I'm using NLog an target to send log to some emails using smtp.google.com:587 SMTP server. When I'm using standard System.Net.Mail.SmtpClient library it's working without any problems but when using MailKit it throw me error:

Error sending mail. Exception: >System.Net.Internals.SocketExceptionFactory+ExtendedSocketException (10061): .No connection could be made because the target machine actively refused it .>[::ffff:173.194.76.108]:587

I added one solution with two console projects. One using MailKit and other System.Net.Mail. All settings parameters looks are the same but it doesn't work in MailKit:

using System;
using System.Diagnostics;
using MailKit.Net.Smtp;
using MailKit;
using MailKit.Security;
using MimeKit;

namespace SendMailKit
{
    class Program
    {
        public static void Main(string[] args)
        {
            Console.WriteLine("Create message");
            var message = new MimeMessage();
            message.From.Add(new MailboxAddress("GTS", "[email protected]"));
            message.To.Add(new MailboxAddress("Me", "[email protected]"));
            message.Subject = "Test mail";
            message.Body = new TextPart("plain")
            {
                Text = @"Hello, This is the test"
            };

            Console.WriteLine("Create SMTP client");
            using (var client = new SmtpClient())
            {
                // For demo-purposes, accept all SSL certificates (in case the server supports STARTTLS)
                client.ServerCertificateValidationCallback = (s, c, h, e) => true;
                Console.WriteLine("Connect");
                **client.Connect("smtp.gmail.com", 587, true);**
                Console.WriteLine("Authenticate");
                client.Authenticate("tfs.gettaxsolutions", "*********");
                client.Connected += Client_Connected;
                client.Disconnected += Client_Disconnected;
                client.Authenticated += Client_Authenticated;
                client.MessageSent += Client_MessageSent;
                Console.WriteLine("Send Message");
                client.Send(message);
                Console.WriteLine("Disconnect");
                client.Disconnect(true);
            }

            Console.ReadLine();
        }

        private static void Client_MessageSent(object sender, MessageSentEventArgs e)
        {
            Console.WriteLine("MessageSent");
        }

        private static void Client_Authenticated(object sender, AuthenticatedEventArgs e)
        {
            Console.WriteLine("Authenticated");
        }

        private static void Client_Disconnected(object sender, DisconnectedEventArgs e)
        {
            Console.WriteLine("Disconnected");
        }

        private static void Client_Connected(object sender, ConnectedEventArgs e)
        {
            Console.WriteLine("Connected");
        }
    }
}

And this throw the same exception like this one in NLog. the exception is in client.Connect("smtp.gmail.com", 587, true); So the problem is in the MailKit connect. In other project which using System.Net.Mail everything is working fine and the mail is sent successful. I'm starting them on same machine, same environment just change the startup point of console application to test (so the connectivity is not a problem):

using System;
using System.Net;
using System.Net.Mail;
using System.Net.Mime;
using System.Threading;
using System.ComponentModel;
namespace SendSimpleMail
{
    public class Program
    {
        static bool mailSent = false;
        private static void SendCompletedCallback(object sender, AsyncCompletedEventArgs e)
        {
            // Get the unique identifier for this asynchronous operation.
            String token = (string)e.UserState;

            if (e.Cancelled)
            {
                Console.WriteLine("[{0}] Send canceled.", token);
            }
            if (e.Error != null)
            {
                Console.WriteLine("[{0}] {1}", token, e.Error.ToString());
            }
            else
            {
                Console.WriteLine("Message sent.");
            }
            mailSent = true;
        }
        public static void Main()
        {
            // Command-line argument must be the SMTP host.
            SmtpClient client = new SmtpClient("smtp.gmail.com", 587);
            client.EnableSsl = true;
            client.UseDefaultCredentials = false;
            client.Credentials = new NetworkCredential("tfs.gettaxsolutions", "***********");
            // Specify the email sender.
            // Create a mailing address that includes a UTF8 character
            // in the display name.
            MailAddress from = new MailAddress("[email protected]", "GTS");
            // Set destinations for the email message.
            MailAddress to = new MailAddress("[email protected]", "Me");
            // Specify the message content.
            MailMessage message = new MailMessage(from, to);
            message.Body = "This is a test email message sent by an application. ";
            // Include some non-ASCII characters in body and subject.
            string someArrows = new string(new char[] { '\u2190', '\u2191', '\u2192', '\u2193' });
            message.Body += Environment.NewLine + someArrows;
            message.BodyEncoding = System.Text.Encoding.UTF8;
            message.Subject = "test message 1" + someArrows;
            message.SubjectEncoding = System.Text.Encoding.UTF8;
            // Set the method that is called back when the send operation ends.
            client.SendCompleted += new
            SendCompletedEventHandler(SendCompletedCallback);
            // The userState can be any object that allows your callback 
            // method to identify this send operation.
            // For this example, the userToken is a string constant.
            string userState = "test message1";
            client.SendAsync(message, userState);
            Console.WriteLine("Sending message... press c to cancel mail. Press any other key to exit.");
            string answer = Console.ReadLine();
            // If the user canceled the send, and mail hasn't been sent yet,
            // then cancel the pending operation.
            if (answer.StartsWith("c") && mailSent == false)
            {
                client.SendAsyncCancel();
            }
            // Clean up.
            message.Dispose();
            Console.WriteLine("Goodbye.");
        }
    }
}

I can't find what is the issue with MailKit. The settings looks like identical. Do you have some idea what can be a problem? Is it bug or have some problem in my settings?

MailKit have to send email successful

ASP.NET Core 2.2, MailKit 2.1.3

Answer

An commercial developer picture An commercial developer · Mar 27, 2019

I just partly-solved a very similar problem merely a few minutes ago; what I learned may help you.

In the case I have, there was reliably working code for MailKit to send from application with target of NET Core 2.1.

Recently I updated all the Nuget packages, thinking it was good practice to do this. Then I later discovered that my working SMTP send code had suddenly stopped working and it was reporting identical error to what you have experienced.

With this situation I checked all kinds of problems with smtp server, firewall, etc., until I remembered the Nuget update, began experimenting and eventually downgraded MailKit to 2.0.0. The send code began working again once MailKit had the version downgrade.

I have not pinpointed the exact location and mechanism of failure but have developed some confidence that (in the case I have been working on) the MailKit version used is directly involved. For today it's restored to working on the MailKit 2.0.0 downgrade and there is more research to be done to take it beyond that status.