k80sg
k80sg

Reputation: 2473

C# + Append DataTable row to html email template

I have a DataTable of records which I need to append as information to my Email template htm. Currently what I am doing here works fine but that is if I only have 1 row of record. How can I go about appending the htm template such that I can have multiple postings in the email

e.g Sample Email Screen (Assuming my DataTable returns 3 rows of record):

Dear Sir, your daily car posting results:

Image
Toyota
Cambry
$10000

Image
Honda
GT
$10000

Image
Nissan
Sunny
$10000

Loop DataTable row:

 for (int i = 0; i < dt.Rows.Count; i++)
                {
                    DataRow dr = dt.Rows[i];

                    primaryImage = dr["PrimaryImage"].ToString();
                    email = dr["Email"].ToString();
                    postTitle = dr["Model"].ToString();
                    model = dr["Model"].ToString();
                    askingPrice = dr["AskingPrice"].ToString();

                    var mail = new Email();
                    mail.IsBodyHtml = true;
                    mail.MailAddresses = email;
                    mail.MailSubject = "Test";

                    mail.HtmFileName = "Email.htm";
                    var dict = new Dictionary<string, string>
                                   {
                                       {"<%PrimaryImage%>", primaryImage },
                                       {"<%PostTitle%>", postTitle},
                                       {"<%Model%>", model},
                                       {"<%AskingPrice%", askingPrice}
                                   };
                    mail.Dict = dict;

                    MailMessage mailMessage;
                    mailMessage = mail.CreateMailMessage();
                    Email.Send(mailMessage, 3, 3000, true);
                    }
                }

Create Mail Message:

public MailMessage CreateMailMessage()
        {
            MailMessage mail = new MailMessage();
            mail.IsBodyHtml = IsBodyHtml;
            mail.From = new MailAddress("[email protected]", "xxx");
            mail.Bcc.Add(MailAddresses);
            mail.Subject = MailSubject;
            string body = "";
            string filePath =
               HttpContext.Current.Server.MapPath("~/" + ConfigurationManager.AppSettings["TEMPLATES"] + "/");

            if (File.Exists(filePath + HtmFileName))
            {
                FileStream f = new FileStream(filePath + HtmFileName, FileMode.Open);
                StreamReader sr = new StreamReader(f);
                body = sr.ReadToEnd();
                foreach (var pair in Dict)
                {
                    body = body.Replace(pair.Key, pair.Value);
                }
                f.Close();
            }

            mail.Body = body;
            mail.DeliveryNotificationOptions = DeliveryNotificationOptions.OnSuccess |
                                               DeliveryNotificationOptions.OnFailure;
            return mail;
        }

Portion of the Email.htm template:

<body>
    <form id="form1" runat="server">
        <div style="border: thin solid #E1E1E1; background-color: #F0F0F0; margin-bottom: 10px; padding-top: 3px; padding-bottom: 3px; padding-left:5px;">
            Postings
        </div>
        <div>
             <a><img src="<%PrimaryImage%>"/></a> 
            <br/><br/>
             Sell Post Title: <%PostTitle%>
            <br/><br/>
            Model: <%Model%>
            <br/><br/>
            Asking Price: <%AskingPrice%>
        </div>
    </form>
</body>

Upvotes: 0

Views: 2401

Answers (2)

Sameer
Sameer

Reputation: 3173

@M.S : There must be some condition on the basis of which you will decide which attribute goes to which td. You can wrap up this logic in some method and generate a class name. Below is a way how you generate a classname on the basis of rownum.

var className="" ;
var rowNum=0;       
foreach (var entry in dataTable)
    {
        className=GetClassName(rowNum)
        innerHtml += "<tr>";
        innerHtml += "<td class='"+ className +"'>" + entry.PrimaryImage + "</td> ";
        innerHtml += "</tr>";
        rowNum++;
    }

public static string GetClassName(int rowCount)
{
    switch (rowCount)
    {
        case 1:
            return "class1";
        case 2:
            return "class2";
        case 3:
            return "class3";
        default:
            return "unassignedClass";
    }
}

Upvotes: 2

Sameer
Sameer

Reputation: 3173

I have always used HtmlAgilityPack to prepare htmlcontent and achieve things like this.

 private string PrepareHtmlContent(List<DataRow> dataTable)
    {

        var htmlDocument = new HtmlDocument();
        var html = EmailTemplates.GetTemplate("yourTemplate");
        htmlDocument.LoadHtml(html);
        var recordsContainerNode = htmlDocument.GetElementbyId("dataTable");

        if (recordsContainerNode != null)
        {
            var innerHtml = "";

            foreach (var entry in dataTable)
            {

                innerHtml += "<tr>";

                innerHtml += "<td>" + entry.PrimaryImage + "</td> ";
                innerHtml += "<td>" + entry.Model + "</td> ";
                innerHtml += "<td>" + entry.AskingPrice + "</td> ";
                innerHtml += "</tr>";
            }


            recordsContainerNode.InnerHtml = innerHtml;
        }

     using (var stringWriter = new StringWriter())
        {
            htmlDocument.Save(stringWriter);
            return stringWriter.GetStringBuilder().ToString();
        }
 }

And your template should be sth like this

<body> <form id="form1" runat="server"> <div style="border: thin solid #E1E1E1; background-color: #F0F0F0; margin-bottom: 10px; padding-top: 3px; padding-bottom: 3px; padding-left:5px;"> Postings </div> <table> <thead> </thead> <tbody id="dataTable"> </tbody> </table> </form> </body>

Upvotes: 0

Related Questions