RenderControl(), it isn’t just for page output

April 1st, 2008

This was originally posted on vanslaars.com in December of 2006.

In browsing through the unanswered posts on the asp.net forums, I came across an interesting question… somebody wanted to know how you would put the output from a GridView control in an email… since all of the ASP.NET Server controls end up producing html content, and the best way(actually the only way that I know of) to put a table into an email is with html, why not use the same mechanism for both? So how are controls rendered? Through their RenderControl method of course. This is actually a pretty simple task to accomplish and I found that there was more code to create temporary data than there was to actually embed the output in the email. So let’s take a look at the code:

protected void SendGrid()
{
MailMessage msg = newMailMessage();
msg.To.Add(<EMAIL HERE>);
msg.From = newMailAddress(<EMAILHERE>);
msg.Subject = "Testing";
msg.IsBodyHtml = true;
msg.Body = "<h1>Start Of Message</h1>";
msg.Body += GetGridHtml();
msg.Body += "<hr/>End of message";
SmtpClient mailServer = newSmtpClient("<MAIL SERVER ADDRESS>");
NetworkCredential mailLogin = newNetworkCredential("<USER NAME>",
"<PASSWORD>");
mailServer.Credentials = mailLogin;
mailServer.Send(msg);
}

private string GetGridHtml()
{
//Setup the gridview object
  GridView gv = new GridView();
gv.DataSource = CreateDataTable();
gv.DataBind();
StringWriter writer = new StringWriter();
HtmlTextWriter htmlWriter = newHtmlTextWriter(writer);
gv.RenderControl(htmlWriter);
return writer.ToString();
}

private DataTable CreateDataTable()
{
DataTable tbl = newDataTable();
tbl.Columns.Add("FirstName",typeof(string));
tbl.Columns.Add("LastName", typeof(string));
tbl.Columns.Add("Age", typeof(int));

DataRow row1 = tbl.NewRow();
row1["FirstName"] = "Bob";
row1["LastName"] = "Jones";
row1["Age"] = 32;

DataRow row2 = tbl.NewRow();
row2["FirstName"] = "Sally";
row2["LastName"] = "Smith";
row2["Age"] = 41;

DataRow row3 = tbl.NewRow();
row3["FirstName"] = "Jane";
row3["LastName"] = "Doe";
row3["Age"] = 26;

tbl.Rows.Add(row1);
tbl.Rows.Add(row2);
tbl.Rows.Add(row3);

return tbl;
}

The “CreateTableData” method is strictly to create some sample data to use as the datasource for the GridView control so we won’t focus on that, you could obviously use any valid datasource for your GridView. The “SendGrid” method is responsible for sending the email, to use this code you will need to enter the email information including the mail server and authentication information. This method also makes a call to “GetGridHtml” which is responsible for creating the GridView, binding the data to it and ultimately returning the Html output for the control. You’ll notice that once the new GridView is instantiated and DataBound, a StringWriter object is created and passed to the contructor for our HtmlTextWriter. RenderControl uses our HtmlTextWriter to load the rendered html to the underlying StringWriter and we use the StringWriter’s ToString method to return our html. The resulting html body for the email will contain an html table complete with column headings data from our datasource.

Another approach would be to loop through your datasource and create a standard html table, but with this approach we can take advantage of the internals of the GridView control, cutting down on code and making it much easier to make changes to the table structure directly through the datasource. I have a couple more ideas for RenderControl beyond page output that I will be posting in the near future. I’d be interested to hear of any other creative uses for RenderControl that you might have.. if you have anything you would like to share, feel free to leave a comment.

[Slashdot] [Digg] [Reddit] [del.icio.us] [Facebook] [Technorati] [Google] [StumbleUpon]

Andrew .NET, ASP.NET , , , ,

  1. No comments yet.
  1. No trackbacks yet.