.NET Framework 3.0 introduced a feature called extension methods. This allows you to add your custom methods to existing objects in .NET Framework. In this example, I'll show you how to generically create HTML table from DataTable object on the server, without a line of HTML code. The code from this article is available for download.
What do we want to create?
Let's say that we store the list of our favorite blogs in database and that we want this list to display on a page (in this example we'll store our blogs in XML file). For each blog we store its name and URL. We want this to be displayed in styled HTML table on the client.
<?xml version="1.0" encoding="utf-8"?>
<pages>
<Page Title="Janko at warp speed" Url="http://www.jankoatwarpspeed.com" />
<Page Title="Lionheart" Url="http://msforge.net/bolgs/milica/" />
<Page Title="Notequ's Blog" Url="http://msforge.net/bolgs/notequ/" />
<Page Title="Brain.WriteLine();" Url="http://msforge.net/bolgs/paki/" />
</pages>
The table should look like this:
How to do that?
There are a numerous ways to do this, of course, but we'll do this using extension method. We can extend any .NET Frameworks object, but for this example we'll extend DataTable object. For this example it is important to know a basic structure of DataTable object. Each DataTable object consists of a collection of DataRow objects and each DataRow object consists of a collection of DataCell objects.
Ok, now, let's create a new static class and call it Extensions.cs. We'll place all extension methods in this class. Now let's create a static method called ToHtmlTable and create DataTable parameter with prefix "this". Now this is the key point. This is not an actual parameter - it just tells that this method is an extension to the type DataTable.
public static string ToHtmlTable(this DataTable table)
Now when we did that we can create our method for generating HTML markup. Let's review the following code:
public static string ToHtmlTable(this DataTable table)
{
StringBuilder sb = new StringBuilder();
sb.AppendLine("<table class=\"styledTable\" cellspacing=\"0\">");
sb.AppendLine("<tr>");
for (int i = 0; i <= table.Columns.Count - 1; i++)
{
sb.AppendLine("<td class=\"styledTableHeader\">" +
table.Columns[i].ColumnName + "</td>");
}
sb.AppendLine("</tr>");
for (int i = 0; i <= table.Rows.Count - 1; i++)
{
sb.AppendLine("<tr>");
for (int j = 0; j <= table.Columns.Count - 1; j++)
{
if (i % 2 == 0)
sb.AppendLine("<td class=\"styledTableRow\">" +
table.Rows[i][j].ToString() + "</td>");
else
sb.AppendLine("<td class=\"styledTableAltRow\">" +
table.Rows[i][j].ToString() + "</td>");
}
sb.AppendLine("</tr>");
}
sb.AppendLine("<table>");
return sb.ToString();
}
Our task is to iterate through DataTable, to create table row element for each record in DataTable, and table cell element for each cell in DataRow object. We can do this in 3 simple steps:
- We use StringBuilder because it is much more efficient than string type. We first define table element and assign it a CSS class called "styledTable". This class will be defined in external CSS file inside the project. This way browser will know how to render each element.
- Next, we iterate through DataTable columns, create a row (TR element) that will act as a header and assign it a CSS class "styledTableHeader".
- Finally, we iterate through rows and columns using two nested loops, and create a HTML row element for each record in DataTable and HTML cell element for each cell in DataRow object. Even rows will have "styledTableRow" CSS class, and each non-even row will have "styledTableRowAlt" CSS class implemented. This way we can have different alternating row style.
And our extension method is completed. We can now move on to a web page. Like I said before in this article, there is no a single line of HTML code, so we'll leave our page source blank. All we have to do is to read our data source (XML file in our case) and render it somewhere on the page. Let's take a look at the code below:
protected void Page_Load(object sender, EventArgs e)
{
DataSet ds = new DataSet();
ds.ReadXml(Server.MapPath("~/blogs.xml"));
Response.Write(ds.Tables[0].ToHtmlTable());
}
We first fill DataSet object with XML data. By doing this DataSet object will automatically create a DataTable object. All we have to do now is to call our .ToHtmlTable method and render it on the page using Response.Write method. Personally, I never use Response.Write, but it serves the purpose in this example. In real project, you can render objects in some control like Panel or DIV.
At the end, we have to define CSS classes that will style our table. For this example I created a simple table design:
.styledTable
{
font-family:Arial, Sans-Serif;
color:#959A60;
font-size:12px;
border: solid 1px #000000;
}
.styledTable td
{
padding:10px;
}
.styledTableHeader
{
background-color:#000000;
color:#ffffff;
font-weight:bold;
}
.styledTableRow
{
}
.styledTableAltRow
{
background-color:#FFFFCD;
color:#5D603D;
}
Is there a room for improvement?
Certainly. The table we created is nothing more than a static report. To add some functionality, you can play a little bit more with extension methods. You can, for example, use a regular expression to examine the string in each cell, and if it is a URL, you can place that string inside HTML anchor (A element). In some other cases, which are very common for web applications, you can add another column with a "View" anchor that will redirect to a specific page and pass an ID through query strings.
Summary
You saw how easy it is to create controls on the server that can be styled with CSS classes. In some cases this might be a good solution for creating HTML markup.
To learn more about DataTable and related objects be sure to read this article:
To learn more about extension methods read following articles:
Share your ideas on how this code can be improved or extended. Feel free to download the code for this article.