无法从.NET发送电子邮件

时间:2014-05-29 13:15:59

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

我正在用C#,MVC 4,.NET 4重写一个Access程序。从我的Access程序中,我可以发送300多封没有问题的电子邮件。这是从循环中调用的相关代码:

Set objMessage = CreateObject("CDO.Message")
objMessage.From = FromEmail

If DebugMode Then
    objMessage.To = DebugEmail
Else
    objMessage.To = EmailStr
End If
If Not IsNull(BCCEmail) Then
    objMessage.bcc = BCCEmail
End If
objMessage.subject = subject
objMessage.HTMLbody = Message
objMessage.Configuration.Fields.Item _
("http://schemas.microsoft.com/cdo/configuration/sendusing") = 2
'Name or IP of Remote SMTP Server
objMessage.Configuration.Fields.Item _
("http://schemas.microsoft.com/cdo/configuration/smtpserver") = SMTPServerAddress
'Server port (typically 25)
objMessage.Configuration.Fields.Item _
("http://schemas.microsoft.com/cdo/configuration/smtpserverport") = SMTPPort

objMessage.Configuration.Fields.Update

objMessage.Send

在我的MVC应用程序中,我遇到了各种各样的问题。有时没有收到电子邮件。有时约有300封电子邮件被收到。有时只收到大约20封电子邮件。在所有情况下都会发送电子邮件(根据代码)但从未将所有电子邮件都收到我的电子邮件客户端。这是我的MVC 4程序的代码:

       using (DatabaseContext dbContext = new DatabaseContext())
        {
            IList<Customer> customers = dbContext.Customers.Where(c => c.sendEmail == true).OrderBy(c => c.boxNumber).ToList();
            Setting setting = dbContext.Settings.First();

            SmtpClient smptClient = new SmtpClient();
            //smptClient.Timeout = 1000 * 200;  // setting the timeout to 200 seconds.
            DateTime batchTimeStamp = DateTime.Now;

            Customer customer;
            for (int i = 0; i < customers.Count; i++ )
            {
                customer = (Customer)customers[i];
                MailMessage emailMessage = new MailMessage();

                setEmailRecipients(customer, ref emailMessage);

                if (!String.IsNullOrEmpty(setting.bccEmail))
                    emailMessage.Bcc.Add(new MailAddress(setting.bccEmail));

                emailMessage.Subject = "Box #" + customer.boxNumber + ".  " + setting.emailSubject;
                emailMessage.Body = setting.emailBody;
                try
                {
                    smptClient.Send(emailMessage);
                }
                catch (SmtpException smtpEx)
                {
                    Debug.WriteLine(smtpEx, "EmailError");
                    Thread.Sleep(1000 * 100);   // wait for 100 seconds
                    i--; // backup the counter so the same email is resent
                    continue;
                }

                customer.sendEmail = false;  // Clear the customer's email sent flag

                EmailHistory history = new EmailHistory();
                history.sentTo = customer.email;
                history.boxNumber = customer.boxNumber;
                history.sentOn = DateTime.Now;
                history.batchTimeStamp = batchTimeStamp;
                dbContext.EmailHistories.Add(history);

                dbContext.SaveChanges();

                //if (i % 5 == 0 && i > 0)
                //    Thread.Sleep(1000 * 20);    // sleep to 20 seconds.

            }
        }

我完全难过了。有人能告诉我为什么我的C#代码不起作用吗?

编辑:我想我发现了问题。我调用了一个“using”子句在循环中实例化我的SmtpClient对象。因此,SmtpClient被实例化,然后针对每封电子邮件销毁。我认为一遍又一遍地实例化SmtpClient就像这样一个禁忌但它有效。有谁知道为什么?

2 个答案:

答案 0 :(得分:2)

我不确定这是真正的原因,但你有一个潜在的无限循环:

catch (SmtpException smtpEx)
{
    Debug.WriteLine(smtpEx, "EmailError");
    Thread.Sleep(1000 * 100);   // wait for 100 seconds
    i--; // backup the counter so the same email is resent
    continue;
}

如果输入错误导致异常(例如错误的电子邮件地址?),并且这些输入不会从循环变为循环,那么这将无限循环。

答案 1 :(得分:1)

您的web.config文件是否设置正确?有关良好的工作示例,请参阅ScottGu's blog

  <system.net>
    <mailSettings>
      <smtp from="test@foo.com">
        <network host="smtpserver1" port="25" userName="username" password="secret" defaultCredentials="true" />
      </smtp>
    </mailSettings>
  </system.net>

从设计的角度来看,您可能希望看到将业务逻辑(包括电子邮件和数据库保存)移动到服务中(例如使用Web API),以便它在一个单独的进程中运行网站。这种层分离还将提高代码的可扩展性和可测试性。