使用ASP.NET MVC发送500封电子邮件:限制

时间:2014-12-18 15:06:25

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

我正在尝试从ASP.NET MVC 4 Web应用程序向客户发送500封电子邮件。我只是使用类似下面的foreach循环。大约50个周期后,我得到一个通用异常,说无法发送邮件。我相信我正在处理限制我的Web应用程序的限制 MS Exchange设置。如何简单地实施限制以绕过这些限制?

感谢。

foreach (var toAddress in addresses)
{
   var message = new MailMessage(fromAddress, toAddress)
   {
      Subject = subject,
      Body = body
   };

   message.IsBodyHtml = isHtml;

   try
   {
      using (var client = new SmtpClient())
      {
         client.Send(message);
      }
   }
   catch (Exception ex)
   {
      Debug.WriteLine("Cannot send e-mail to " + message.To + Environment.NewLine +
                      "Subject: " + subject + Environment.NewLine +
                      "Body: " + body + Environment.NewLine + 
                      "Exception: " + ex.Message);
   }
}

3 个答案:

答案 0 :(得分:2)

我会查看Quartz.NET并使用服务发送电子邮件。就排队而言,可能会查看简单的文件存储或数据库。

如果您使用类似Thread.Sleep的内容,请记住,您将从呈现最终输出中阻止服务器(例如,如果通过表单提交触发,则生成的视图将不会显示电子邮件已发送)。通过使用像quartz这样的库,您可以在卸载电子邮件发送时保持服务器对请求的响应。

此外,作为参考,还有另一篇关于在不拖动UX的情况下执行昂贵操作的帖子。这可以找到here,{IMHO}是TheCodeKing最相关的答案。

答案 1 :(得分:1)

如果您使用的是Exchange 2010或更高版本,则会有一个RecipientRateLimit限制策略参数,该参数指定用户可以在24小时内处理的收件人数限制。如果您想要绕过此限制,则需要更改发送这些消息的用户的限制策略,请参阅http://www.slipstick.com/exchange/limit-number-of-internet-messages-user-can-send/

干杯 格伦

答案 2 :(得分:0)

我们的场景是使用本地MS Exchange Server 2010的远程Web应用程序,目前唯一可行的解​​决方案如下。每10秒钟使用20-30条消息块,我可以向客户发送我想要的自定义电子邮件数量,而无需触及MS Exchange Sever 2010配置(需要数小时的培训)。此外,所有内容都记录在TXT文件中,以确保实际发送消息。我还建议使用MS Exchange Tracking Log Explorer工具来检查是否发送了哪些消息。

private void SendBulkEmail(List<KeyValuePair<Customer, Order>> customerList, MailAddress sender, string subject, string body, bool isHtml, string fileNamePrefix)
{
    const int chunkSize = 20;

    string rootPath = Server.MapPath("~");

    string path = Path.GetFullPath(Path.Combine(rootPath, "Logs"));

    string fileName = CommonUtils.GetLogFileName(path, fileNamePrefix);

    int len = customerList.Count;

    TextWriter tw = new StreamWriter(fileName);

    int chunkCount = (len / chunkSize) + 1;
    int remainder = len % chunkSize;

    for (int j = 0; j < chunkCount; j++)
    {
       int start = j * chunkSize;
       int end = start + chunkSize;

       if (j == chunkCount - 1)
       {
           end = start + remainder;
       }

       SmtpClient client = new SmtpClient();

       for (int i = start; i < end; i++)
       {
           Customer customer = customerList[i].Key;

           Guid userGuid = new Guid(customer.UserId.ToString());
           MembershipUser membershipUser = Membership.GetUser(userGuid);

           string memberUsername = membershipUser.UserName;
           string memberEmail = membershipUser.Email;

           SendMessage(sender, recipient, subject, body, tw, client, context);

       }

       client.Dispose();

       Thread.Sleep(10000); // 10 seconds

       tw.WriteLine("Completed chunk #" + j);
   }

   tw.Close();
 }

public static void SendEmail(MailAddress fromAddress, MailAddress toAddress, string subject, string body, TextWriter tw, SmtpClient smtpClient)
{
    MailMessage message = new MailMessage(fromAddress, toAddress)
    {
       Subject = subject,
       Body = body
    };

    try
    {
       smtpClient.Send(message);

       if (tw != null)
       {
          tw.WriteLine("\"" + toAddress + "\",");
       }
    }
    catch (Exception ex)
    {
       if (tw != null)
       {
          tw.WriteLine(toAddress + ": " + ex.Message + " " + ex.InnerException.Message);
       }

       Debug.WriteLine("Cannot send e-mail to " + toAddress + ", " + "Exception: " + ex.Message + (ex.InnerException != null ? ", " + ex.InnerException.Message : string.Empty));
    }
}