0

我编写了下面的程序来向该表中的演示用户发送 HTML 电子邮件:

在此处输入图像描述

我只想发送一封电子邮件并列出每个客户的所有信息。目前,如果客户有 10 本书逾期,那么根据表结构,客户将收到 10 封电子邮件,因为每笔图书借阅都是单独的记录。

例如:

亲爱的 Jim Carey: 以下书籍到期:

  1. 如何修理汽车
  2. 詹姆斯邦德回归

有没有一种方法可以让每个客户只发送一封电子邮件,但在电子邮件中列出每个项目。例如列出所有到期的书籍?

Fox 示例:使用上表发送一封电子邮件,Jim Carey 将收到 2 封电子邮件,而不是 1 封。我想只发送一封,但列出两本到期的书。

class Program
{
static DataSet dtProfile = Database.AcquireData();
static DataTable table = dtProfile.Tables[0];

static string CustFName;
static string CustLName;
static string CheckoutDate;
static string DueDate;
static string BookName;

public static void SendEmail()
{
    foreach (DataRow row in table.Rows)
    {
     CustFName = row["CustFName"].ToString();
     CustLName = row["CustLName"].ToString();
     CheckoutDate = row["CheckoutDate"].ToString();
     DueDate = row["DueDate"].ToString();
     BookName = row["BookName"].ToString();          
     string body = PopulateBody(CustFName, CustLName, CheckoutDate, DueDate, BookName);<br />
     SendHtmlFormattedEmail("Email", "Subject", body);
    }
}

public static string PopulateBody(string custFName, string custLName,
    string checkoutDate, string dueDate, string bookName)
{
    string body = string.Empty;

    using (StreamReader reader = 
        new StreamReader(Path.GetFullPath(@"Z:\folder\email.html")))
    {
        body = reader.ReadToEnd();
    }
    body = body.Replace("{#First Name#}", custFName);
    body = body.Replace("{#Last Name#}",  custLName);
    body = body.Replace("{#Checkout Date#}", checkoutDate);
    body = body.Replace("{#Due Date#}",  dueDate);
    body = body.Replace("{#Book Name#}", bookName);

    return body;
}

public static void SendHtmlFormattedEmail(string recepientEmail, string subject, string body)
{
    using (MailMessage mailMessage = new MailMessage())
    {
      mailMessage.From = new MailAddress(ConfigurationManager.AppSettings["UserName"]);
      mailMessage.Subject = subject;
      mailMessage.Body = body;
      mailMessage.IsBodyHtml = true;
      mailMessage.To.Add(new MailAddress(recepientEmail));
      SmtpClient smtp = new SmtpClient();
      smtp.Host = ConfigurationManager.AppSettings["Host"];
      smtp.EnableSsl = Convert.ToBoolean(ConfigurationManager.AppSettings["EnableSsl"]);
      System.Net.NetworkCredential NetworkCred = new System.Net.NetworkCredential();
      NetworkCred.UserName = ConfigurationManager.AppSettings["UserName"];
      NetworkCred.Password = ConfigurationManager.AppSettings["Password"];
      smtp.UseDefaultCredentials = true;
      smtp.Credentials = NetworkCred;
      smtp.Port = int.Parse(ConfigurationManager.AppSettings["Port"]);
      smtp.Send(mailMessage);
    }
}

static void Main(string[] args)
{
    SendEmail();
}

}
4

2 回答 2

1

为每个电子邮件地址创建一个电子邮件数据集合。然后遍历各个地址并发送电子邮件。

class Program
{
    static DataSet dtProfile = null; //Database.AcquireData();
    static DataTable table = dtProfile.Tables[0];

    public static void SendEmail()
    {
        // Create the dictionary to hold the email data for each individual email. This allows us 
        // to group all of the books due for an individual together.  We will use the email address
        // as the key for the dictionary instead of CustomerID in case the user has given us two
        // different email addresses.
        Dictionary<string, List<DataRow>> emailList = new Dictionary<string, List<DataRow>>();

        // Iterate over the dataset and populate the dictionary
        foreach (DataRow row in table.Rows)
        {
            // grab the email address, will be the key for the dictionary
            string email = row["Email"].ToString();

            // if we haven't processed a row for this email yet, initialize the entry for it
            if (!emailList.ContainsKey(email))
            {
                emailList.Add(email, new List<DataRow>());
            }

            // add the datarow for the overdue book for the email
            emailList[email].Add(row);
        }

        // Now, craft and send an email for each unique email address in the list
        foreach (string email in emailList.Keys)
        {
            // create a string builder to build up the body of the email
            StringBuilder body = new StringBuilder();
            body.Append("<html>");
            body.Append("<body>");

            // assume the first/last name will be the same for each row, so just get the
            // name information from the first row to build the opening line of the email
            DataRow firstRow = emailList[email][0];
            body.AppendFormat("<p>Dear {0} {1}:  The following book(s) are due:</p>", firstRow["FName"].ToString(), firstRow["LName"].ToString());
            body.Append("<ol>");

            // now just add a line item for each book
            foreach (DataRow row in emailList[email])
            {
                body.AppendFormat("<li>{0}</li>", row["BookName"].ToString()); 
            }

            // close up your html tags
            body.Append("</ol>");
            body.Append("</body>");
            body.Append("</html>");

            // finally, send the email
            SendHtmlFormattedEmail(email, "Overdue Books", body.ToString());
        }
    }

    public static void SendHtmlFormattedEmail(string recepientEmail, string subject, string body)
    {
        using (MailMessage mailMessage = new MailMessage())
        {
            mailMessage.From = new MailAddress(ConfigurationManager.AppSettings["UserName"]);
            mailMessage.Subject = subject;
            mailMessage.Body = body;
            mailMessage.IsBodyHtml = true;
            mailMessage.To.Add(new MailAddress(recepientEmail));
            SmtpClient smtp = new SmtpClient();
            smtp.Host = ConfigurationManager.AppSettings["Host"];
            smtp.EnableSsl = Convert.ToBoolean(ConfigurationManager.AppSettings["EnableSsl"]);
            System.Net.NetworkCredential NetworkCred = new System.Net.NetworkCredential();
            NetworkCred.UserName = ConfigurationManager.AppSettings["UserName"];
            NetworkCred.Password = ConfigurationManager.AppSettings["Password"];
            smtp.UseDefaultCredentials = true;
            smtp.Credentials = NetworkCred;
            smtp.Port = int.Parse(ConfigurationManager.AppSettings["Port"]);
            smtp.Send(mailMessage);
        }
    }

    static void Main(string[] args)
    {
        SendEmail();
    }

}
于 2013-11-02T01:22:22.390 回答
0

使用 Jason Young 的示例,但稍作修改以分隔每个不同客户的电子邮件。

string lastCustId = "none";
foreach (DataRow row in table.Rows)
{
    if (!lastCustId.Equals("none") && !row["CustId"].ToString().Equals(lastCustId))
    {
        // Different customer's record, fire off the email to previous one
        SendHtmlFormattedEmail("Email", "Subject", body.ToString());
        lastCustId = row["CustId"].ToString();
    }
    // Build email for current customer
    CustFName = row["CustFName"].ToString();
    CustLName = row["CustLName"].ToString();
    CheckoutDate = row["CheckoutDate"].ToString();
    DueDate = row["DueDate"].ToString();
    BookName = row["BookName"].ToString();          
    body.AppendLine(PopulateBody(CustFName, CustLName, CheckoutDate, DueDate, BookName, template));
    // not sure what your template looks like, but this would be whatever
    // markup or text you would want separating your book details
    body.AppendLine("<br>");        
}
// Finally send email to the last customer in above loop
SendHtmlFormattedEmail("Email", "Subject", body.ToString());
于 2013-11-02T06:01:05.060 回答