通过Gmail SMTP发送电子邮件无限期挂起而不会出现错误

时间:2017-12-11 04:31:18

标签: c# asp.net asp.net-mvc email

在我的ASP.NET MVC 5应用程序中,我使用电子邮件(SendAsync)主要用于帐户身份验证。它直到最近都运作良好,我不知道发生了什么。据我所知,我没有改变任何与电子邮件有关的内容。

当我尝试进入控制器中的<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> 调用时,它会将控制权转移回无限期挂起的浏览器。最后,我必须停止并重新启动应用程序池才能访问任何页面,这需要几分钟(通常几乎可以立即重新启动)。

我已将其设置为使用Google应用密码,这是一项要求(否则会收到有关安全性的错误)。自the new app password hasn't been used以来,它似乎甚至无法达到谷歌。

我已尝试过TLS端口以及SSL端口。上次我开始工作是使用TLS。

Web.config:

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

用法:

        html, body {
            height: 100%;
            width:100%;
            margin: 0;
        }

#container {
  position: relative;
 min-height: 100%; 
  overflow: hidden;
  background-color: #645384;
}

#container:after { 
  content: '';
  position: absolute;
    padding-bottom: 141.42136%;
  left: 30%;
  width: 100%;
  background-color: #f37638;
  -webkit-transition: all 1s;
  -moz-transition: all 1s;
  transition: all 1s;
  -webkit-transform: rotate(45deg);
  -moz-transform: rotate(45deg);
  transform: rotate(45deg);
}

5 个答案:

答案 0 :(得分:1)

OP在这里。正如一些答案所暗示的那样,我的代码没有任何问题。如果没有重新测试,我不知道下面哪个更改了,但是这是使用Gmail SMTP必须具备的功能

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

答案 1 :(得分:0)

请注意Documentation并查看 Gmail SMTP服务器部分下的 Gmail发送限制。

您的代码看起来很好,我唯一看到的是您启用了SSL,但使用了为“TLS”设置的端口,因此使用SSL方法的用户将会遇到问题。

除此之外,没有任何东西出现在眼睛上。

答案 2 :(得分:0)

只有TLS端口587对我有用,但是EnableSsl设置为true

我还为我的Google帐户启用了不太安全的应用访问权限:

https://myaccount.google.com/u/2/lesssecureapps

答案 3 :(得分:-1)

有从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>

<强>的.cs

var smtp = new SmtpClient(); // no other code. 
var msg = CreateEmailMessage();
//I use try... catch
try{
   smtp.Send(msg);
   //return true; //if it is a separate function
}
catch(Exception ex){
   //return false; 
   //use ex.Message (or deeper) to send extra information
}

请注意,除username以外的发件人外,Gmail不具备此功能。如果您希望收件人回答其他地址,请使用

msg.ReplyToList.Add(new MailAddress(email, publicName));

答案 4 :(得分:-1)

这更容易。确保添加相关的名称空间。请记住,这是使用gmail smtp地址完成的。它从电子邮件提供商变为电子邮件提供商这段代码对我很有用..

using System.IO;
using System.Net.Mail;
using System.Net;

public void sendmail()
{
    string emailFrom = "SENDING GMAIL ADDRESS HERE";
    string subject = " SUBJECT HERE";
    string body = "MESSAGE BODY HERE";
    MailMessage maile = new MailMessage(emailFrom, "RECIEVERS EMAIL ADDRESS", subject, body);
    SmtpClient client = new SmtpClient("smtp.gmail.com",587);
    client.Credentials = new System.Net.NetworkCredential("SENDING GMAIL ADDRESS HERE", "SENDERS GMAIL PASSWORD HERE");
    client.EnableSsl = true;
    try
    {
        client.Send(maile);
    }
    catch(Exception e)
    {
        MessageBox.Show("" + e);
    }
}