Отправлять почту с помощью Gmail SMTP с помощью MailKit SMTP Client в .NET core 2.2 у меня не работает - PullRequest
1 голос
/ 27 марта 2019

Я использую цель NLog для отправки журнала на некоторые электронные письма, используя smtp.google.com:587 SMTP-сервер.Когда я использую стандартную библиотеку System.Net.Mail.SmtpClient, она работает без проблем, но при использовании MailKit выдает ошибку:

Ошибка отправки почты.Исключение:> System.Net.Internals.SocketExceptionFactory + ExtendedSocketException (10061): .Не может быть установлено соединение, потому что целевая машина активно отказала ему.> [:: ffff: 173.194.76.108]: 587

Я добавил одно решение с двумя консольными проектами.Один использует MailKit, а другой - System.Net.Mail.Все параметры параметров выглядят одинаково, но в 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", "tfs.gettaxsolutions@gmail.com"));
            message.To.Add(new MailboxAddress("Me", "info@gettaxsolutions.com"));
            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");
        }
    }
}

И это выдает то же исключение, что и в NLog.исключение находится в client.Connect ("smtp.gmail.com", 587, true);Так что проблема в подключении MailKit.В другом проекте, который использует System.Net.Mail, все работает нормально, и почта отправляется успешноЯ запускаю их на той же машине, в той же среде, просто изменив точку запуска консольного приложения для тестирования (чтобы не было проблем с подключением):

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("tfs.gettaxsolutions@gmail.com", "GTS");
            // Set destinations for the email message.
            MailAddress to = new MailAddress("info@gettaxsolutions.com", "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.");
        }
    }
}

Я не могу найти, в чем проблемаMailKit.Настройки выглядят одинаково.У вас есть идея, в чем может быть проблема?Это ошибка или какая-то проблема в моих настройках?

MailKit должен успешно отправлять электронную почту

ASP.NET Core 2.2, MailKit 2.1.3

Ответы [ 3 ]

1 голос
/ 28 марта 2019

Я просто частично решил очень похожая проблема всего несколько минут назад;то, что я узнал, может вам помочь.

В моем случае был надежно рабочий код для отправки MailKit из приложения с целью NET Core 2.1.

НедавноЯ обновил все пакеты Nuget, думая, что это хорошая практика.Затем я обнаружил, что мой работающий код отправки SMTP внезапно перестал работать , и он сообщал об ошибке, идентичной той, которую вы испытали.

В этой ситуации я проверил все виды проблем с сервером SMTP., брандмауэр и т. д., пока я не вспомнил об обновлении Nuget, начал экспериментировать и в конечном итоге понизил MailKit до 2.0.0.Код отправки снова начал работать после того, как у MailKit было понижение версии.

Я не указал точное местоположение и механизм сбоя, но приобрел некоторую уверенность в том, что (в случае, над которым я работал), используемая версия MailKit напрямую задействована.На сегодняшний день он восстановлен для работы над понижением MailKit 2.0.0, и предстоит еще больше исследований, чтобы вывести его за пределы этого статуса.

0 голосов
/ 28 марта 2019

Я изменил код подключения к этому:

client.ServerCertificateValidationCallback = (s, c, h, e) => true; client.Connect ("smtp.gmail.com", 587, SecureSocketOptions.StartTlsWhenAvailable);

Так что чисто, что будет использовать Tls, когда доступно. Проверка сертификата отключена. Он отлично работает в MailKit 2.0.7, но тот же код в 2.1.3 продолжает выдавать ошибку в описании проблемы. Не знаю почему. Может быть, есть какая-то ошибка во всех последних версиях (2.1.x)?

0 голосов
/ 28 марта 2019

Часть проблемы заключается в том, что порт SMTP 587 не поддерживает SSL.Вам нужно передать false в качестве аргумента useSsl.

Порт 587 использует STARTTLS (который MailKit будет использовать автоматически, если сможет).

Если вы хотите больше контроля, используйте ConnectМетоды [Async], которые принимают SecureSocketOptions значение перечисления.

При использовании методов Connect [Async], которые принимают логический аргумент, true является эквивалентом SecureSocketOptions.SslOnCOnnect и false является эквивалентом SecureSOcketOptions.StartTlsWhenAvailable.

Тем не менее, основная часть проблемы, по-видимому, связана с ошибкой в ​​новом коде соединения Socket MailKit.Начиная с MailKit 2.1.x, MailKit начал использовать Socket.BeginConnect (string host, int port, ...) вместо Socket.Connect (IPAddress address, int port), что позволило базовой реализации .NET преобразовать имя хоста в соответствующий IPAddress и разрешить отмену.К сожалению, это, кажется, сломало вещи для некоторых людей (почему?).

Я снова обновил MailKit, чтобы вернуться к разрешению имен хостов в список IP-адресов (используя Dns.GetHostAddresses[Async]) и циклически перебирая каждый из них.IPAddress, пока не сможет успешно подключиться.Это исправление будет доступно в MailKit> = 2.1.4.До этого вы можете установить через myget feed на https://www.myget.org/feed/mimekit/package/nuget/MailKit

...