C# 通过Gmail SMTP发送电子邮件会无限期挂起,不会出错

C# 通过Gmail SMTP发送电子邮件会无限期挂起,不会出错,c#,asp.net,asp.net-mvc,email,C#,Asp.net,Asp.net Mvc,Email,在我的ASP.NET MVC 5应用程序中,我使用电子邮件(System.NET.Mail)主要用于帐户身份验证。直到最近,它一直运作良好,我不知道发生了什么。据我所知,我没有改变任何事情,即使是和电子邮件有点关系 当我尝试在控制器中执行SendAsync调用时,它会将控制权转移回浏览器,并无限期挂起。最终,我不得不停止并重新启动应用程序池来访问任何页面,这需要几分钟的时间(通常几乎可以立即打开) 我已设置为使用谷歌应用程序密码,这是一项要求(否则,您会在安全性方面出错)。从那时起,它似乎甚至没

在我的ASP.NET MVC 5应用程序中,我使用电子邮件(
System.NET.Mail
)主要用于帐户身份验证。直到最近,它一直运作良好,我不知道发生了什么。据我所知,我没有改变任何事情,即使是和电子邮件有点关系

当我尝试在控制器中执行
SendAsync
调用时,它会将控制权转移回浏览器,并无限期挂起。最终,我不得不停止并重新启动应用程序池来访问任何页面,这需要几分钟的时间(通常几乎可以立即打开)

我已设置为使用谷歌应用程序密码,这是一项要求(否则,您会在安全性方面出错)。从那时起,它似乎甚至没有谷歌那么远

我尝试了TLS端口和SSL端口。上一次我用TLS让它工作

Web.config:

<configuration>
  <appSettings>
    <add key="SmtpUsername" value="email@gmail.com" />
    <add key="SmtpPassword" value="AppPassword" />
    <add key="SmtpSender" value="email@gmail.com" />
    <add key="SmtpHost" value="smtp.gmail.com" />
    <add key="SmtpPort" value="587" /> <!-- SSL: 465, TLS: 587 -->
    <add key="SmtpEnableSsl" value="true" />
  </appSettings>
</configuration>

电子邮件代码:

public class EmailClient : SmtpClient
{
    public EmailClient()
    {
        UseDefaultCredentials = false;
        Host = WebConfigurationManager.AppSettings.Get("SmtpHost");
        Port = int.Parse(WebConfigurationManager.AppSettings.Get("SmtpPort"));
        EnableSsl = bool.Parse(WebConfigurationManager.AppSettings.Get("SmtpEnableSsl"));
        Credentials = new NetworkCredential(WebConfigurationManager.AppSettings.Get("SmtpUsername"),
                                            WebConfigurationManager.AppSettings.Get("SmtpPassword"));
        DeliveryMethod = SmtpDeliveryMethod.Network;
        Timeout = 30000; // Waiting 30 seconds doesn't even end the "loading" status
    }
}

public class EmailMessage : MailMessage
{
    private bool isBodyHtml = true;

    public EmailMessage(string subject, string body, string recipients)
        : base(WebConfigurationManager.AppSettings.Get("SmtpSender"), recipients, subject, body)
    {
        IsBodyHtml = isBodyHtml;
    }

    public EmailMessage(string subject, string body, IEnumerable<string> recipients)
        : base(WebConfigurationManager.AppSettings.Get("SmtpSender"), string.Join(",", recipients), subject, body)
    {
        IsBodyHtml = isBodyHtml;
    }
}

public static class Email
{
    /// <param name="recipients">Comma-delimited list of email addresses</param>
    public static async Task SendAsync(string subject, string body, string recipients)
    {
        using (EmailMessage msg = new EmailMessage(subject, body, recipients))
        using (EmailClient client = new EmailClient())
        {
            await client.SendMailAsync(msg);
        }
    }

    /// <param name="recipients">Collection of email addresses</param>
    public static async Task SendAsync(string subject, string body, IEnumerable<string> recipients)
    {
        using (EmailMessage msg = new EmailMessage(subject, body, recipients))
        using (EmailClient client = new EmailClient())
        {
            await client.SendMailAsync(msg);
        }
    }
}
公共类EmailClient:SmtpClient
{
公共电子邮件客户端()
{
UseDefaultCredentials=false;
Host=WebConfigurationManager.AppSettings.Get(“SmtpHost”);
Port=int.Parse(WebConfigurationManager.AppSettings.Get(“SmtpPort”);
enablesl=bool.Parse(WebConfigurationManager.AppSettings.Get(“smtpenablesl”);
凭据=新网络凭据(WebConfiguration Manager.AppSettings.Get(“SmtpUsername”),
WebConfigurationManager.AppSettings.Get(“SmtpPassword”);
DeliveryMethod=SmtpDeliveryMethod.Network;
超时=30000;//等待30秒甚至不会结束“加载”状态
}
}
公共类EmailMessage:MailMessage
{
private bool isBodyHtml=true;
公共电子邮件(字符串主题、字符串正文、字符串收件人)
:base(WebConfiguration Manager.AppSettings.Get(“SmtpSender”)、收件人、主题、正文)
{
IsBodyHtml=IsBodyHtml;
}
公共电子邮件(字符串主题、字符串正文、IEnumerable收件人)
:base(WebConfigurationManager.AppSettings.Get(“SmtpSender”)、string.Join(“,”,recipients)、subject、body)
{
IsBodyHtml=IsBodyHtml;
}
}
公共静态类电子邮件
{
///以逗号分隔的电子邮件地址列表
公共静态异步任务SendAsync(字符串主题、字符串正文、字符串收件人)
{
使用(EmailMessage msg=新的EmailMessage(主题、正文、收件人))
使用(EmailClient=new EmailClient())
{
等待client.SendMailAsync(msg);
}
}
///收集电子邮件地址
公共静态异步任务SendAsync(字符串主题、字符串正文、IEnumerable收件人)
{
使用(EmailMessage msg=新的EmailMessage(主题、正文、收件人))
使用(EmailClient=new EmailClient())
{
等待client.SendMailAsync(msg);
}
}
}
用法:

public class TestController : BaseController
{
    public async Task<ActionResult> Test()
    {
        await Email.SendAsync("TEST", "test", "anaddress@gmail.com");
        return View(); // Never reaches this point
    }
}
公共类TestController:BaseController
{
公共异步任务测试()
{
等待Email.SendAsync(“测试”,“测试”,”anaddress@gmail.com");
return View();//永远不会到达这一点
}
}

从ASP.NET发送电子邮件有一种标准方式

web.config

  <system.net>
    <mailSettings>
      <smtp deliveryMethod="Network">
        <network defaultCredentials="false" enableSsl="true" host="smtp.gmail.com" password="password" port="587" userName="user@gmail.com"/>
      </smtp>
    </mailSettings>
  </system.net>
请注意,除了
用户名
之外,Gmail不会将发件人排除在外。如果你想让你的收件人回复另一个地址,那么使用

msg.ReplyToList.Add(new MailAddress(email, publicName));
请注意,并查看Gmail SMTP服务器部分下的Gmail发送限制。

您的代码看起来很好,我看到的唯一一件事是您正在启用SSL,但使用了为“TLS”指定的端口,因此将使用SSL方法的用户将遇到问题


除此之外,什么也看不见

OP在这里。正如一些答案所暗示的,我的代码没有问题。我不确定我在没有重新测试的情况下更改了以下哪项,但这是您必须使用Gmail SMTP的内容:

  • 使用TLS端口587
  • 将SmtpClient.EnableSsl设置为
    true
  • 为Google帐户启用MFA,并为
    SmtpClient.Credentials
    使用应用程序密码。我需要启用MFA来创建应用程序密码

是的,上限是2000。我有很多。是的,它是TLS端口,但SSL端口也不工作。它被设置为TLS端口,并且在上次工作时启用了SSL。我不知道发生了什么。我没有投反对票,但也许是因为你没有回答问题?问题是“为什么这不起作用?”而不是“有其他方法存储设置吗?”。再说一次,我不能代表其他人说话,但这肯定不比Selaka的更糟,Selaka的投票结果更高。
msg.ReplyToList.Add(new MailAddress(email, publicName));