Writing HTML

When you need to write well-formed HTML, the .NET framework can assist you. Rather than creating strings, you can use an instance of the HtmlTextWriter class to help format the data correctly. While you can use an HtmlTextWriter directly—and you might do that if you were writing a custom control and needed to render the HTML for the control—you would normally let the controls call the HtmlTextWriter for you. In other words, you typically use an HtmlTextWriter indirectly.

For example, suppose you want to write a table of values, where each cell needs to be formatted differently according to the value. Negative values are red, positive values are black, text labels are blue, and so on. I'll show you two examples in this section.

Before you look at the code, here's some information about the HtmlTextWriter class. It has methods to write elements and attributes, and it has fields for every part of the HTML elements and attributes. For example, the class defines fields for the left and right angle brackets that start and end elements; for the equal sign between attributes; for single and double quotes; for the default tab character; for the slash character, and so on. It also defines methods for writing HTML. The class uses a StringWriter that writes to a StringBuilder to output the results. For example, to write the tag <table align="center">, you could use the following:

//create a StringBuilder with an initial size of 3000 bytes using System.Text;

StringBuilder sb = new StringBuilder(3000); HtmlTextWriter htw = new HtmlTextWriter

(new StringWriter(sb)); htw.WriteBeginTag("table"); htw.WriteAttribute("align","center"); htw.Write(htw.TagRightChar);

Other methods let you render a complete tag, write a string, or add style attributes. While you can probably see that writing this code would improve the accuracy of complex HTML, it isn't particularly palatable for writing a simple tag.

OK, on to the code. The first example shows how you can format the HTML yourself. The second example creates an HtmlTextWriter instance, creates an HtmlTable control, fills the table with data, and then tells the table to render. Note that it's both easier to read and easier to write robust HTML when you let the HtmlTextWriter format the HTML for you.

Both examples create a table containing positive and negative numbers and strings using a two-dimensional object array as the source data (see Figure 10.4).

[]|L| 1jL-lr m> urhif * ni ¡ill 1 n>n. ITiaili (jj iyi ... ^ J I

iiiLn ijiir wxi mtonitt RIHL manJlij w «HillmWitir

Figure 10.4: Custom HTML versus HtmlTextWriter: two table examples

Listing 10.6 shows the code. The Web Form ch10-7.aspx creates some randomized data when it loads and then calls the two subroutines showTable1 and showTable2 that create the tables.

Listing 10.6: Create Table Comparison: Custom HTML versus HtmlTextWriter (ch10-7.aspx.cs)

public class ch10 7 : System.Web.UI.Page {

private void Page Load(object sender, System.EventArgs e) { Object[,] arrData = getRandomData(); showTable1(arrData); showTable2(arrData);

private Object[,] getRandomData() { String[] strings= {

"Row 1", "Row 2", "Row 3", "Row 4", "Row 5"}; Object[,] values = new Object[5,5]; int aValue;

for (i = 0; i < 5; i++) { for (j = 0; j < 5; j++) { if (j == 4) {

aValue = rand.Next(-1000, 1000); values[i, j] = aValue;

return values;

private void showTable1(Object[,] values) { int i, j;

Response.Write("<h3>This table was written " +

"with HTML created by hand.</h3>"); Response.Write("<table align=\"center\"" +

"border=\"1\">"); for (i = 0; i <= values.GetUpperBound(0); i++) { Response.Write("<tr>");

for (j = 0; j <= values.GetUpperBound(1); j++) { switch (values[i, j].GetType().Name) { case "String" :

Response.Write("<td style=\"color:" + "blue; background: lightyellow\">" + values[i, j] + "</td>"); break; case "int32" :

if ((int) values[i, j] < 0) { Response.Write("<td " +

"style=\"color: red;" + "background:lightyellow\">" + values[i, j] + "</td>");

else if ((int) values[i,j] >= 0) { Response.Write("<td " +

"style=\"color: black\">" + values[i, j] + "</td>");

break;

Response.Write("</table><br>");

private void showTable2(Object[,] values) { HtmlTable tbl = new HtmlTable(); StringBuilder sb = new StringBuilder(3000); StringWriter sw = new StringWriter(sb); HtmlTextWriter htw = new HtmlTextWriter(sw); int i, j; HtmlTableRow row; HtmlTableCell cell; tbl.Border = 1; tbl.Align = "center";

Response.Write("<h3>This table was written with " +

"HTML created by an HtmlTextWriter</h3>"); for (i = 0; i <= values.GetUpperBound(0); i++) { row = new HtmlTableRow(); tbl.Rows.Add(row);

for (j = 0; j <= values.GetUpperBound(l); j++) { cell = new HtmlTableCell(); switch (values[i, j].GetType().Name) { case "String" :

cell.Attributes.Add("style",

"color:blue; background:lightYellow"); break; case "int32" :

if ((int) values[i, j] < 0) { cell.Attributes.Add("style", "color:red; " + "background:lightYellow");

else if ((int) values[i, j] >= 0) { cell.Attributes.Add("style", "color:black; " + background:white");

break;

cell.innerText = values[i, j].ToString(); row.Cells.Add(cell);

tbl.RenderControl(new HtmlTextWriter(sw));

Response.Write(sb.ToString());

#region Web Form Designer generated code override protected void OnInit(EventArgs e) {

// CODEGEN: This call is required by the ASP.NET

InitializeComponent(); base.OnInit(e);

/// Required method for Designer support - do not modify /// the contents of this method with the code editor. /// </summary>

private void InitializeComponent() {

this.Load += new System.EventHandler(this.Page Load);

#endregion

The code is rather long because of the code-intensive process for writing HTML, but the code to write the HTML in the showTable1 and showTable2 methods is fairly straightforward. Dealing with the data isn't quite as simple.

Creating random data in .NET is simple: Use the Random class. The Random class seeds itself automatically with a time-based value when you create a new instance. For ex-VB readers, you don't need to use Randomize and supply a value, as was necessary in earlier versions of VB to initialize the randomization engine.

Random rand = new Random();

To get random values from the Random object, use the Next method, which returns the next random number in a series. An overloaded version (used in Listing 10.6) returns a number between the parameters lowerBound and upperBound. For example, the following line returns a number between

-1000 and 1000.

Because one way to create a two-dimensional table with data is to store that data in a two-dimensional array, the getRandomData method fills an array with the random values and returns the array. The array isn't an array of simple numbers; it's a two-dimensional array of objects. Items 1 through 4 are integers, but every fifth item in the array is a string.

private Object[,] getRandomData() { String[] strings= {

"Row 1", "Row 2", "Row 3", "Row 4", "Row 5"}; Object[,] values = new Object[5,5]; int aValue;

for (i = 0; i < 5; i++) { for (j = 0; j < 5; j++) { if (j == 4) {

aValue = rand.Next(-1000, 1000); values[i, j] = aValue;

return values;

One problem is that the Page_Load method doesn't know the bounds of the array—that's defined inside the getRandomData method. When you don't know the bounds of a multidimensional array, you can pass it by placing commas between the array subscripts and leaving the subscripts blank.

private void showTable2(Object[,] values) {// code here}

To write the data, though, you need to know the data type because the object type determines the formatting. One way is to use the GetType.Name method. The code uses this to differentiate integer (Int32) values from String values.

switch (values[i, j].GetType().Name) { case "String" :

// output a formatted string break; case "Int32" :

// output a formatted number break;

The ASP.NET server controls render themselves using an HtmlTextWriter. When you need to write HTML at runtime, it's much easier to work with the HTML controls and set properties and methods— especially when you need to change things—than it is to work with the raw HTML. Of course, you aren't limited to tables—you can use any HTML control from the toolbox in a similar manner. So you can see the difference, spend a little time comparing the handwritten HTML code output from the showTable1 method with the HtmlTextWriter-generated code from the showTable2 method. The output from both methods is identical, but the code in the second method is (in my opinion) easier to maintain.

Was this article helpful?

0 0

Post a comment