2013-11-01 21 views
0

我寫了下面的程序來發送HTML電子郵件的演示用戶在該表中列出的數據表中的數據的多個部分:如何使用可變

enter image description here

我想只發送一個電子郵件,列出每個客戶的所有信息。目前,如果客戶有10本逾期預訂,那麼客戶將根據表結構獲得10封電子郵件,因爲每本圖書貸款都是單獨的記錄。

例如:

親愛的金·凱瑞: 下面的書籍(S)是由於:

  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(); 
} 

} 
+1

在爲每一個而不是做一個發送電子郵件 取一個字符串,並保持加起來的書籍列表。然後在您生成該人員未完成的圖書清單後致電發送電子郵件。 – logixologist

+0

好吧看着你的代碼,可能無法正常工作....嗯 – logixologist

回答

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(); 
    } 

} 
+0

我已經用示例表更新了這個問題。嘗試了您的建議,並將所有用戶放在一封電子郵件中。謝謝。 – Asynchronous

+0

對不起,我誤解了這個問題。我已經更新了答案,每個客戶只發送一封電子郵件。 – Jason

+0

這是kool Jason:我仍然收到兩本單獨的電子郵件內容。這就像電子郵件正文爲每本書重複自我。我的模板只是一個基本的HTML。因此,我不想有多個電子郵件正文,我只是想列出,到期日期以及借用的到期日和借閱日期。 *請參閱問題更新。 – Asynchronous

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());