Skip to main content
 首页 » 编程设计

c#之通过 Gmail SMTP 发送电子邮件无限期挂起而没有错误

2024年01月13日31rubylouvre

在我的 ASP.NET MVC 5 应用程序中,我主要使用电子邮件 (System.Net.Mail) 进行帐户身份验证。直到最近它都运行良好,我不知道发生了什么。据我所知,我没有更改任何与电子邮件相关的内容,哪怕是轻微的更改。

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

我已将其设置为使用 Google 应用程序密码,这是一项要求(否则会出现安全错误)。它似乎甚至没有谷歌那么远,因为the new app password hasn't been used .

我已经尝试了 TLS 端口和 SSL 端口。上次我让它工作是使用 TLS。

网络配置:

<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); 
        } 
    } 
} 

用法:

public class TestController : BaseController 
{ 
    public async Task<ActionResult> Test() 
    { 
        await Email.SendAsync("TEST", "test", "anaddress@gmail.com"); 
        return View(); // Never reaches this point 
    } 
} 

请您参考如下方法:

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

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