【问题标题】:SMTP via .Net C# Web application - second email not sending on production serverSMTP 通过 .Net C# Web 应用程序 - 第二封电子邮件未在生产服务器上发送
【发布时间】:2013-11-15 00:35:43
【问题描述】:

我们有一个通过 SMTP 发送电子邮件的 C# ASP.Net 项目。
我们有一个正常的密码恢复周期,发送了两封电子邮件。 第一个有恢复密码的访问码,第二个返回一个临时密码。

当用户请求丢失密码时,始终会收到此电子邮件。 然后用户点击电子邮件中的链接,输入代码并发送第二封电子邮件。始终会收到第一封电子邮件。

在我们的开发环境中总是会收到第二封电子邮件,但在我们部署的版本中只是间歇性地收到。 (网络驱动服务器)

第二封电子邮件使用相同的邮件配置。它是一个邮件消息对象,我们在其中调用 send 方法。我们没有收到任何错误消息。我们认为它可能被视为垃圾邮件,但...... 有什么想法吗?

电子邮件在单独的线程上运行。两封邮件是异步发送的。

电子邮件 web.config 设置为:

<mailSettings>
      <smtp deliveryMethod="Network" from="info@mysite.com">
        <network host="smtp.webhost.co.nz"
                     defaultCredentials="false"
                     enableSsl="true"
                     password="password"
                     port="587"
                     userName="info@mysite.com"/>
     </smtp>
    </mailSettings>

代码如下:

public bool SendEMailTempPass(string EmailRecipients, string Subject, string Body, bool isHTML = true)
        {
            try
            {
                var sendMailThreadPass = new Thread(() =>
                {
                    System.Net.Configuration.SmtpSection smtpSettings = new System.Net.Configuration.SmtpSection();
                    System.Net.Mail.SmtpClient smtp = new System.Net.Mail.SmtpClient();//settings.Smtp.Network.Host);
                    string strFrom = ConfigurationManager.AppSettings["Mailto"];
                    MailMessage mailObj = new MailMessage(strFrom, EmailRecipients, Subject, Body);
                    mailObj.IsBodyHtml = isHTML;
                    smtp.SendCompleted += new SendCompletedEventHandler(PassChangeEmail_SendCompleted);

                    smtp.SendAsync(mailObj, null);
                });

                sendMailThreadPass.Start();

            }
            catch (Exception ex)
            {
                ErrorMessage = ex.Message;
                return false;
            }
            ErrorMessage = "";
            return true;
        }

        void PassChangeEmail_SendCompleted(object sender, AsyncCompletedEventArgs e)
        {
            if (e.Cancelled)
            { }
            else if (e.Error != null)
            {
                ErrorMessage = e.Error.ToString();
                EmailStatus = 0;
            }
            else
            {
                ErrorMessage = "";
                SuccessMessage = "Thank you.  We will be in touch!";
                EmailStatus = 1;
            }
        }

这就是它的调用方式:

string body = PassResetEmail.PopulateBodyPassReset(this.Name + " " + this.Lastname,                                                                               LinkURL,PicURL, NewPassword, strPassResetEmailTemplate);

PassResetEmail.SendEMailTempPass(this.Email, "Change your temporary password", body, true);

我用 google 帐户对其进行了测试,我们遇到了同样的问题:第一封电子邮件被发送,第二封邮件很少通过。

关于在哪里看或看什么有什么想法吗?

起初我们认为它可能是某种垃圾邮件过滤器,但对于两个不同的提供商来说似乎是一样的。

另一件事是它可以在我们的本地环境中完美运行,即使使用相同的邮件提供商设置。

任何想法都将不胜感激!

谢谢!

【问题讨论】:

  • 实际发送电子邮件的代码在哪里?你调试过它,它是否成功执行发送,没有任何异常?
  • 谢谢,我已经添加了电子邮件例程。感谢您的帮助!

标签: c# multithreading smtp asynchronous


【解决方案1】:

SendAsync 掩盖实际错误时遇到问题 - 我不记得确切的场景,但我使用 ThreadPool 将其替换为我自己的异步调用:

将您对smtp.SendAsync(mailObj, null);的呼叫替换为

ThreadPool.QueueUserWorkItem(SendEmail, new EmailPair { Client = client, Email = message });

您需要以下帮助程序类和发送电子邮件的实际方法:

public class EmailPair
{
    public SmtpClient Client { get; set; }
    public MailMessage Email { get; set; }
}

public static void SendEmail(object state)
{
    var pair = (EmailPair) state;
    try
    {
        pair.Client.Send(pair.Email);
    }
    catch (Exception e)
    {
        Log.Error(e);
    }
}

您确实需要记录 e 的所有异常(确保 e.InnerException 已正确记录,以便您查看发生了什么)

您可能需要让您友好的网络人员参与进来,看看他是否能看到邮件服务器的实际情况。

【讨论】:

  • 非常感谢伙计。这解决了这个问题。作为记录,smtp.SendAsync 有什么问题?这让我精神崩溃!干杯
  • @DataAnalyst1 我快速浏览了SendAsync 的源代码——它绝对不像我想象的那么简单;因此我不知道为什么错误报告与同步调用不同。
猜你喜欢
  • 2018-10-17
  • 1970-01-01
  • 2022-01-09
  • 2014-01-11
  • 1970-01-01
  • 2012-03-21
  • 1970-01-01
相关资源
最近更新 更多