Skip navigation

HTML Helpers

How ASP.NET MVC pages generate HTML for the browser

CoreCoder

LANGUAGES: C#

ASP.NET VERSIONS: 3.5 | MVC

HTML Helpers

How ASP.NET MVC pages generate HTML for the browser

By Dino Esposito

Any web page is made of an HTML string that browsers interpret and render graphically. Source code for a static web page consists of plain HTML literals. A dynamic web page, which goes through a second layer of abstraction, typically is written in an intermediate markup language that some runtime environment translates into plain HTML. For example, ASP.NET web pages are written in a made-to-measure markup language saved to ASPX files. The syntax of the ASPX markup language allows you to include HTML literals, along with comments and references to ASP.NET server controls.

ASP.NET server controls are ad hoc components that are instantiated on the server and, when properly configured either declaratively or programmatically, end up emitting plain HTML for the browser. An ASP.NET server control is not simply an HTML generator. An ASP.NET server control participates in the whole page lifecycle and is notified of any lifecycle event such as Init, Load and PreRender that occurs at the page level. In addition, a server control can fire its own events to the container page. Many server controls only fire events that contain the logic for a postback event. For example, the Button control fires the Click event to the host page. By handling the button's Click event, the page author can execute any logic related to the user's clicking. In addition, ASP.NET server controls take advantage of the page's viewstate and use it to persist their own internal state across successive requests.

ASP.NET server controls are one of the primary aspects that characterize the ASP.NET Web Forms model. Earlier this spring, Microsoft released ASP.NET MVC 1.0 a new ASP.NET programming framework that I've covered widely in this column. Unlike Web Forms, ASP.NET MVC has a completely decoupled view engine that acts as a plain HTML generator. Each ASP.NET MVC application is allowed to use a view engine of choice and can employ any sort of syntax to express the requested shape of HTML.

The standard view engine of an ASP.NET MVC application is still based on a subset of the Web Forms rendering engine. This means that you can still use ASP.NET server controls, but only as HTML generators, with no support for postback events and viewstate. In version 1.0, ASP.NET MVC doesn't formalize a rich model for components capable of producing HTML. However, as long as you employ the default view engine you can rely on HTML helpers. Let's find out more.

What's an HTML Helper, Anyway?

The typical view of an ASP.NET MVC application that uses the default rendering engine is an ASPX file made of HTML literals, code blocks and, optionally, server controls. The final goal of the file is to be the template for the HTML to return to the browser. In code blocks, you can have any .NET executable code that does any required calculation and outputs expected HTML.

How would you output, say, an HTML input element with some of the attributes set to calculated values? In classic ASP.NET, you would use a TextBox control and set (or have set) corresponding properties programmatically. A TextBox control is still a valid option in ASP.NET MVC; however, it is more of a workaround than a direct, clean solution.

ASP.NET MVC is designed to give page authors total control over any generated HTML literals. The TextBox, as well as any other server control, is sort of a black box whose generated HTML cannot be fully controlled. An HTML helper is a static method on a system class that outputs an HTML string based on the provided input data. In a way, an HTML helper is a simplified and lightweight version of an ASP.NET server control tailor-made for ASP.NET MVC. An HTML helper has no viewstate, no postbacks, no page lifecycle and events; it consists of a standard HTML template that is filled with custom data.

Standard HTML Helpers

A number of predefined HTML helpers are included with the ASP.NET MVC framework. You can use them to emit the markup for the most common elements, including text boxes, drop-down lists, links and forms. You won't find anything to render more sophisticated pieces of HTML such as tables, grids and pagers. However, the extensibility of the framework triggered a number of open-source projects aimed at making additional HTML helpers available. You'll find custom HTML helpers at www.codeplex.com/MVCContrib.

At the end of the day, an HTML helper is just an extension method created for the system-provided System.web.Mvc.HtmlHelper class. Figure 1 shows the typical implementation of an HTML helper that renders a check box.

public static string CheckBox(this HtmlHelper htmlHelper, string name, bool isChecked)

{

return htmlHelper.CheckBox(name, isChecked, null);

}

Figure 1: Implementation of a CheckBox helper

As you can see, the helper adds a new method named CheckBox to the system's HtmlHelper class. The CheckBox method receives a few arguments that will be used internally to generate an appropriate HTML string. In the sample code (Listing 1), the HTML helper receives the name of the check box and a Boolean value indicating whether or not the element is checked. The following fragment illustrates how to use the check box helper in the view of an ASP.NET MVC page:

<% =Html.CheckBox("CheckBox1", true) %>

The HTML output in the page will look like the following:

Figure 2 lists the predefined HTML helpers available in ASP.NET MVC.

Helper Type Description
CheckBox Input Returns the HTML string for a check box input element
Hidden Input Returns the HTML string for a hidden input element
Password Input Returns the HTML string for a password input element
RadioButton Input Returns the HTML string for a radio button input element
TextBox Input Returns the HTML string for a text input element
BeginForm Form Returns a MvcForm object that represents a HTML form
EndForm Form Void method, closes the pending tag
ActionLink Link Returns the HTML string for an HTML link
DropDownList Select Returns the HTML string for a drop-down list
ListBox Select Returns the HTML string for a list box
TextArea TextArea Returns the HTML string for a text area
ValidationMessage Validation Returns the HTML string for a validation message
ValidationSummary Validation Returns the HTML string for a validation summary message
RenderPartial User controls Returns the HTML incorporated in a user control

Figure 2: Predefined HTML helpers

Feeding HTML Helpers

Although an HTML helper is a fairly simple component, it still incorporates some logic. The helper logic is fed by method parameters. Each helper method has its own set of parameters based on the expected behavior. The CheckBox helper accepts two parameters the name of the check box and its checked status. The CheckBox helper counts the following overloads:

public static string CheckBox(this HtmlHelper htmlHelper,

string name);

public static string CheckBox(this HtmlHelper htmlHelper,

string name, bool isChecked);

public static string CheckBox(this HtmlHelper htmlHelper,

string name, IDictionary htmlAttributes);

public static string CheckBox(this HtmlHelper htmlHelper,

string name, object htmlAttributes);

public static string CheckBox(this HtmlHelper htmlHelper,

string name, bool isChecked, IDictionary htmlAttributes);

In addition to specific parameters, you can configure all HTML helpers using an explicit list of HTML attributes. Any attributes in the list will appear in the rendered markup for the element. You can indicate HTML attributes in either of two ways via a dictionary or an object. The dictionary is a key/value collection where the key indicates the name of the HTML attribute. You can express the value through any .NET object. The real value saved in the markup, though, is whatever string expression comes out of the Convert.ToString function applied to the value.

You also can store HTML attributes in a custom .NET object. In this case, values are retrieved via reflection by looking at the public properties of the custom object. Names of public properties should match HTML attributes for the target HTML element. Typically, you choose this option when you want to use an object initializer, as follows:

<% = Html.CheckBox("CheckBox1", new { @checked="checked", value="on"} )%>

Because in C# checked is a recognized keyword, you're required to prefix it with @ to instruct the compiler to ignore that instance of the string. The preceding code results in a check box that is checked and has a value of "on."

A check box is just a button with no syntax element to specify a descriptive text and a check box without an attached label is not helpful. In ASP.NET Web Forms, the CheckBox control silently emits a

<% = Html.CheckBox("CheckBox1") %>

Adding the

Finally, HTML helpers are tightly coupled with some ASP.NET MVC data containers such as ViewData. Suppose your view contains the following:

<% = Html.CheckBox("CheckBox1") %>

And suppose also that the controller's method that triggers the view adds an item to ViewData with a matching ID.

public ActionResult About()

{

ViewData["CheckBox1"] = "true";

return View();

}

In this case, the check box is rendered in a checked state as set in ViewData.

More on the CheckBox Helper

The CheckBox HTML helper deserves mention of a peculiarity that often goes unnoticed. When you invoke CheckBox(), the helper doesn't render only an element; it also emits a hidden input element with the same ID as the check box, as Figure 3 shows.

Figure 3: The real output of the CheckBox HTML helper

More interestingly, the hidden input element, except for the ID, has a fixed layout (see example below). That is, for every checkbox a hidden element is generated with an ID that matches the ID of the checkbox. Besides the ID, the structure of the hidden input field always looks the same, regardless of the attributes of the check box.

What's the purpose of this element? Check box elements work differently from most HTML input elements. When browsers post the content of a form, only check boxes that are currently checked are appended to the body of the request. In particular, a key is added to the body that equals the name of the input element and a value is added that matches the value property of the element. A check box that is unchecked is ignored during the post stage. In ASP.NET Web Forms, the IsChecked property of the CheckBox control contains all the logic to handle the selection of the element. In ASP.NET MVC, adding a hidden text box makes it easier to determine whether a check box was originally included in the page that was unchecked when the post occurred.

What happens when you use Request.Form["CheckBox1"] from either the controller or a view's code block? If the check box was unchecked, then Request.Form["CheckBox1"] references the hidden field and returns false. If the check box was checked, then Request.Form["CheckBox1"] returns the string "true,false." It's up to you to parse the string and ensure it contains the substring "true."

However, if you're using the default model binder, and binding to a complex object like an Order, then the "true,false" string is resolved for you by the binder. Otherwise, either you do your own parsing or switch back to an old-style but equally effective and manual markup. Using the default binder means you have a controller method such as the following:

public ActionResult Save(Order order)

{

if (order.IsConfirmed)

ViewData["Status"] = "Confirmed";

else

ViewData["Status"] = "[Being processed]";

return View();

}

The default binder simply creates an instance of the Order class where properties are mapped to any posted data that matches the pattern parameter.PropertyName. In other words, the parameter "order" receives data from any input element named order.PropertyName, such as order.IsConfirmed.

<% = Html.CheckBox("order.IsConfirmed")%>

I'll cover model binders in a future column.

Simple Help

HTML helpers are plain markup generators that save developers some work in the creation of web views. Like classic ASP.NET server controls, HTML helpers incorporate some logic and produce HTML as a result. Like classic ASP.NET server controls, HTML helpers offer a simplified programming interface for developers. However, HTML helpers are much simpler than server controls. They have no event model and generate no viewstate. In this article, I examined the general characteristics of helpers and focused on one of them the CheckBox helper. In an upcoming column, I'll cover other predefined helpers and show how to create custom HTML helpers. Stay tuned!

Dino Esposito ([email protected]) is an architect at IDesign and specializes mainly in ASP.NET, AJAX and RIA solutions. Dino co-authored the best-seller Microsoft .NET: Architecting Applications for the Enterprise (Microsoft Press, 2008) and the just-released twin book Microsoft ASP.NET and AJAX: Architecting web Applications (Microsoft Press, 2009).

Hide comments

Comments

  • Allowed HTML tags: <em> <strong> <blockquote> <br> <p>

Plain text

  • No HTML tags allowed.
  • Web page addresses and e-mail addresses turn into links automatically.
  • Lines and paragraphs break automatically.
Publish