Writing your own Html Helpers for the ASP.NET MVC Framework

Anyone who’s dipped a toe in the ASP.NET MVC Framework will have encountered Html Helpers. These remove the need to drop large chunks of code into your markup to generate common elements that can’t be hard-coded by giving you the means to use small chunks of code instead. Which is better.

For example, if you have the framework scaffold a “List” view template for you, by default you’ll get Edit and Details links for each item in the Model. The end result looks something like this:

Best Microsoft MCTS Training – Microsoft MCITP Certification at Certkingdom.com

OK, admit it: How many of you when you first saw this sort of thing in the MVC Framework threw up your hands, said “It’s ASP all over again” and ran away screaming? Trust me, it’s really not that bad. The helper methods solve the problem of producing markup from the Model or other dynamic content, and actually remove the need to inject a lot of code into the markup (which would be uncomfortably like the bad old days with ASP, at least as many people wrote it) by wrapping it up in a compact bundle.

The output generated at runtime from the fragment above is gloriously simple and uncluttered. For example:

(In this case I based my view on a PeopleController. The links will invoke the Edit and Details Actions respectively for the item with Id=1).

It needs to be stressed that these extensions are not controls: they are as their name implies helper methods that generate vanilla markup based on any arguments you supply them. They have in themselves no page lifecycle, no state and certainly no event model. In some ways they could be compared with macros.

The output of most HTML Helpers is simply a string containing markup. The same is true of course of server controls, but with HTML Helpers the markup produced is not the kind that makes View Source the stuff of nightmares. This is because generating a string of HTML is all they do, so there is no need for hidden elements or script to enable a complex relationship between the generated markup and things that happen on the server.

Additionally, because they are not controls, it follows that they are not composite controls, so you are not confronted with markup containing element ids longer than a sentence by Marcel Proust.

So how do you write your own?

First you need to have a basic understanding of Extension Methods – if you don’t know what extension methods are then clearly you’ve wasted your life and there’s nothing I can do for you (Oh come on, that was a joke, so no sulking – extension methods are defined in the Visual Studio and .NET Framework glossary this way “A static method that can be invoked by using instance method syntax. In effect, extension methods make it possible to extend existing types and constructed types with additional methods”).

A typical HTML Helper is an extension method applied to the View’s instance of the HtmlHelper class. Consequently if you’re using C# your method signature will typically start with something like “(this HtmlHelper htmlHelper”, followed by any other parameters required.

For my example I’m going to create an HTML Helper that generates a list of Technorati tags surrounded by a DIV element and preceded by the words “Technorati tags: “. Technorati tags are described here.

I’m assuming a scenario where your MVC application is something like a blog or a CMS where it is useful to have posts or articles accompanied by tags, and consequently your model will include a property such as “TagList”, representing a comma-delimited list of tags (if you want anything more structured it probably makes more sense to use fixed categories).

So, our HTML Helper will need to take a Model property which for any given instance might contain something such as this: “rambling, arrant nonsense” and output HTML like this:

(I know there’s more you’d probably want to include, and I’ll come to that shortly).

To build the markup my first impulse was to use an HtmlTextWriter in conjunction with a StringWriter, but the TagBuilder object provided with the MVC Framework has some useful characteristics that we can take advantage of to good effect.

Here’s the first version:

In this case I’ve used TagBuilders to create the anchor tags, aggregated the results with a StringBuilder and placed the results in the InnerHtml property of an outer TagBuilder for the DIV.

Note also that I’ve used the HtmHelper object’s AttributeEncode and Encode methods .

The problem with the HTML this code produces (which I showed earlier) is that it is effectively sealed: if you want to apply CSS styling to it or manipulate it with jQuery you’re out of luck.

We could of course supply hard-coded id and class values for the DIV, but you know in your belly (ewww…) that that’s a bad idea, and it would of course mean that anyone using this helper would need to see its output or examine the code to know what element id or CSS class they should be referring to. It’s much better to let the developer specify these values when they’re using your helper extension.

Rather than supplying parameters for “id” and “class” and then adding others that you realise you’ve forgotten, there is a pattern used by the built-in helper methods that you can refer to.  So I’ll overload my extension method to support two versions of an htmlAttributes parameter, one an object and the other a dictionary:

This is where the TagBuilder really comes into its own: we can use the MergeAttributes method of the TagBuilder to add attributes from the dictionary into its collection of attributes, and these are then rendered with the rest of the element.

The attributes themselves can be specified using object initaliser syntax, so (again assuming C#) I can add an id and a style to my DIV this way:

This gives us the following HTML:

But you probably don’t want to use inline styles, instead you want to use a class defined in an external CSS file so designers won’t snub you at parties (ignoring for now the fact that developers don’t get invited to the same parties as designers). And here’s where we run into one of those “Why is life never simple?” issues – “class” is a C# keyword, and is not allowed in an object initialiser in C#. Which in this particular case is a bit of a shame.

You can of course use “Class” instead, but if you’re like me you’ll recoil at the thought of upper case in attribute names (and justifiably worry about XHTML compliance). My solution was decidedly hacky but it works (although I addressed “class” directly rather than taking a more general approach). I threw in “_class” as well for good measure.

In this case the attribute is still specified as “Class” or even the doesn’t-mean-anything “_class”, but is then replaced in the TagBuilder’s attribute collection by the preferred “class”. You are welcome of course to use a better approach.

The end result is a TechnoratiTagList HTML Helper that not only happily generates the appropriate HTML from our tag list string but is also acceptably addressable and stylable, while still producing vanilla HTML without any bloat.

Leave a Reply

Your email address will not be published. Required fields are marked *