【问题标题】:Gmail fails to respond with MailKitGmail 无法使用 MailKit 响应
【发布时间】:2023-03-08 11:10:02
【问题描述】:

我正在使用 ASP.NET Core 并使用 MailKit 来实现电子邮件功能。我之前用的方法已经不行了。

我有一个 SmtpOptions.cs 类:

public class SmtpOptions
    {
        public string Server { get; set; } = "smtp.gmail.com";  //Gmail limited to 2000 emails per day
        public int Port { get; set; } = 465; //default for SSL using GMail
        public string User { get; set; } = "myEmail@gmail.com"; //must match server domain
        public string Password { get; set; } = "myPwd";
        public bool UseSsl { get; set; } = true; //gmail requires SSL
        public bool RequiresAuthentication { get; set; } = true; //gmail requires authentication
        public string PreferredEncoding { get; set; } = string.Empty;
    }

和 EmailSender.cs 类:

 public class EmailSender
    {
        public EmailSender()
        {
        }

        public async Task SendEmailAsync(
            SmtpOptions smtpOptions,
            string to,
            string from,
            string subject,
            string plainTextMessage,
            string htmlMessage,
            string replyTo = null)
        {
            if (string.IsNullOrWhiteSpace(to))
            {
                throw new ArgumentException("no to address provided");
            }

            if (string.IsNullOrWhiteSpace(from))
            {
                throw new ArgumentException("no from address provided");
            }

            if (string.IsNullOrWhiteSpace(subject))
            {
                throw new ArgumentException("no subject provided");
            }

            var hasPlainText = !string.IsNullOrWhiteSpace(plainTextMessage);
            var hasHtml = !string.IsNullOrWhiteSpace(htmlMessage);
            if (!hasPlainText && !hasHtml)
            {
                throw new ArgumentException("no message provided");
            }

            var m = new MimeMessage();

            m.From.Add(new MailboxAddress("", from));
            if (!string.IsNullOrWhiteSpace(replyTo))
            {
                m.ReplyTo.Add(new MailboxAddress("", replyTo));
            }
            m.To.Add(new MailboxAddress("", to));
            m.Subject = subject;

            //m.Importance = MessageImportance.Normal;
            //Header h = new Header(HeaderId.Precedence, "Bulk");
            //m.Headers.Add()

            BodyBuilder bodyBuilder = new BodyBuilder();
            if (hasPlainText)
            {
                bodyBuilder.TextBody = plainTextMessage;
            }

            if (hasHtml)
            {
                bodyBuilder.HtmlBody = htmlMessage;
            }

            m.Body = bodyBuilder.ToMessageBody();

            using (var client = new SmtpClient())
            {
                await client.ConnectAsync(
                    smtpOptions.Server,
                    smtpOptions.Port,
                    smtpOptions.UseSsl)
                    .ConfigureAwait(false);

                // Note: since we don't have an OAuth2 token, disable
                // the XOAUTH2 authentication mechanism.
                client.AuthenticationMechanisms.Remove("XOAUTH2");

                // Note: only needed if the SMTP server requires authentication
                if (smtpOptions.RequiresAuthentication)
                {
                    await client.AuthenticateAsync(smtpOptions.User, smtpOptions.Password)
                        .ConfigureAwait(false);
                }

                await client.SendAsync(m).ConfigureAwait(false);
                await client.DisconnectAsync(true).ConfigureAwait(false);
            }

        }

        public async Task SendMultipleEmailAsync(
            SmtpOptions smtpOptions,
            string toCsv,
            string from,
            string subject,
            string plainTextMessage,
            string htmlMessage)
        {
            if (string.IsNullOrWhiteSpace(toCsv))
            {
                throw new ArgumentException("no to addresses provided");
            }

            if (string.IsNullOrWhiteSpace(from))
            {
                throw new ArgumentException("no from address provided");
            }

            if (string.IsNullOrWhiteSpace(subject))
            {
                throw new ArgumentException("no subject provided");
            }

            var hasPlainText = !string.IsNullOrWhiteSpace(plainTextMessage);
            var hasHtml = !string.IsNullOrWhiteSpace(htmlMessage);
            if (!hasPlainText && !hasHtml)
            {
                throw new ArgumentException("no message provided");
            }

            var m = new MimeMessage();
            m.From.Add(new MailboxAddress("", from));
            string[] adrs = toCsv.Split(',');

            foreach (string item in adrs)
            {
                if (!string.IsNullOrEmpty(item)) { m.To.Add(new MailboxAddress("", item)); ; }
            }

            m.Subject = subject;
            m.Importance = MessageImportance.High;

            BodyBuilder bodyBuilder = new BodyBuilder();
            if (hasPlainText)
            {
                bodyBuilder.TextBody = plainTextMessage;
            }

            if (hasHtml)
            {
                bodyBuilder.HtmlBody = htmlMessage;
            }

            m.Body = bodyBuilder.ToMessageBody();

            using (var client = new SmtpClient())
            {
                await client.ConnectAsync(
                    smtpOptions.Server,
                    smtpOptions.Port,
                    smtpOptions.UseSsl).ConfigureAwait(false);

                // Note: since we don't have an OAuth2 token, disable
                // the XOAUTH2 authentication mechanism.
                client.AuthenticationMechanisms.Remove("XOAUTH2");

                // Note: only needed if the SMTP server requires authentication
                if (smtpOptions.RequiresAuthentication)
                {
                    await client.AuthenticateAsync(
                        smtpOptions.User,
                        smtpOptions.Password).ConfigureAwait(false);
                }

                await client.SendAsync(m).ConfigureAwait(false);
                await client.DisconnectAsync(true).ConfigureAwait(false);
            }

        }

    }

在函数调用中使用:

public async void ContactMessage(string title, string message, string toEmail)
        {
            string thisMessage = "No Message Provided";
            if (!String.IsNullOrEmpty(message)) { thisMessage = message; } //in case empty form
            string thisTitle = title;
            //create email objects
            EmailSender emailSender = new EmailSender();
            SmtpOptions smtpOptions = new SmtpOptions(); //default settings ok
            string fromEmail = smtpOptions.User;

            string subjectLine = "Message Title";

            await emailSender.SendEmailAsync(smtpOptions, toEmail, fromEmail, subjectLine, thisMessage, "");
        }

如前所述,此方法以前有效,但现在我的 Gmail 无法响应。我已经检查并启用了 IMAP 和 POP。

具体的例外情况如下: "System.Net.Internals.SocketExceptionFactory.ExtendedSocketE‌​xception: '连接尝试失败,因为连接方在一段时间后没有正确响应,或建立连接失败,因为连接主机没有响应'"

此代码尚未部署,但在测试环境中导致此错误。移动到不同的防火墙系统会导致错误“Mailkit.Security.Authentication;MailKit 身份验证太弱”

使用 Yahoo! 进行测试smtp 允许上面的代码工作,所以看起来 Mailkit 和 Gmail 之间的兼容性已经改变。使用 Gmail 的适当 Mailkit 配置是什么?

【问题讨论】:

  • 如果它以前有效,现在无效,并且您没有更改代码或 gmail 设置的任何内容,您不认为您应该联系谷歌支持吗? StackOverflow 用于编程相关问题,您甚至没有提供您得到的确切错误
  • 对不起,如果我不够清楚。这是代码重用的一个实例;它以前在 WebForms 应用程序中工作,但现在我正在尝试它 asp.net core MVC。我在这里问是因为我是 ASP.NET Core 的新手,并且认为这可能与框架之间的差异有关。确切的例外是:“System.Net.Internals.SocketExceptionFactory.ExtendedSocketException: '连接尝试失败,因为连接方在一段时间后没有正确响应,或者建立连接失败,因为连接的主机没有响应'”跨度>
  • 最好更新答案中的异常,并不是每个人在阅读您的问题时都会阅读每一条评论。还有太多信息丢失了,是在本地测试时还是在部署后发生的?您的 Webform 应用程序是否仍然使用完全相同的代码运行? WinForms 也运行在 .NET Framework 上,而 ASP.NET Core 默认运行在 .NET Core 上。运行面向 .NET Framework 的 ASP.NET Core 2.0 时是否会发生同样的错误?
  • 可能是防火墙问题什么的。

标签: asp.net asp.net-core mailkit


【解决方案1】:

电子邮件帐户设置未配置为允许使用安全性较低的应用程序。两种解决方案是:

1) 在 EmailSender.cs 类中获取 OAuth 2.0 凭据,或者 2) 更改电子邮件帐户设置以允许安全性较低的应用程序

更多详情请访问: How to send email by using MailKit?

【讨论】:

    【解决方案2】:

    一般来说,当你收到一个 AuthenticationException 说 AUTH 机制太弱时,这意味着客户端尝试使用 PLAIN 或 LOGIN 机制,而服务器只允许通过 SSL 使用这些机制。

    确保在启用 SSL 的情况下连接到端口 465 或使用 SecureSocketOptions.StartTls 作为第三个参数在端口 587 上连接。

    【讨论】:

      猜你喜欢
      • 2018-06-15
      • 1970-01-01
      • 2015-01-29
      • 2020-03-02
      • 2020-05-18
      • 2015-12-24
      • 1970-01-01
      • 2016-11-16
      • 2018-12-07
      相关资源
      最近更新 更多