Get Started with ASP.NET MVC TagHelpers

Tag HelperWe are almost to the BETA cycle of ASP.NET vNext, and I’ve been following the ASP.NET team’s development on GitHub.  If you didn’t know already, the all-star developers at Microsoft are cranking away on the next version of ASP.NET in a completely open-source model.One of the cool new features set to be released with the next version is a significant addition to the HTML Helper model that we currently have in MVC 5, and its called TagHelpers.

Currently, when editing an MVC view, if I want to use an HTML helper to construct a label and give it the CSS class of “caption” I need to write the following syntax:

@Html.Label("FirstName", "First Name:", new {@class="caption"})

That’s kind of ugly. No, that’s really ugly.  I mean, consider how the intellisense of Visual Studio works:  the @Html.Label is identified in the razor syntax as c-sharp code.  The next two arguments are text, so no assistance is given to the developer as they write those arguments.  The final argument is an anonymous object to set attributes on the label element.  To sweeten the pot, class is a reserved keyword in c-sharp and in order to output a CSS class attribute we need to further escape the property name with an @ symbol.  The name of the class is text, so no intellisense help is given there either.

Boring!  Lame… of no help to me as a developer.

Now consider syntax like this:


Well, now things are much more interesting.  Instead of using a c-sharp magic string to craft a “for” attribute, the editor can assist us by identifying that is coming from the model and giving us a list of potential property names that could be used.  The class attribute can be handled by the new Visual Studio HTML editor and provide intellisense for all CSS classes referenced by the current view.

Brilliant!  That is much more like a developer is thinking.

A Real Tag Helper – Kendo UI Core Datepicker

Jeff and Steve Smith hard at work

Jeff and Steve Smith hard at work

I wanted to take a real dive into this topic, so I wrote a simple tag helper for the Kendo UI Datepicker.  This is a simple textbox that provides a full calendar for a date selection experience.  It also validates the information keyed in to ensure it is a valid date.

You should know, I wrote this sample at the Microsoft MVP Summit’s ASP.NET Hackathon.  I
had the authors of the framework sitting in the same room as me, and was able to reference them for assistance. I’m sharing their insight in the following demo.

My goal with this exercise was simple:  provide a custom tag in Razor syntax that could be used to create a datepicker text edit box.  I’ll assume for this initial sample that the Kendo UI Core libraries have already been added to an ASP.NET vNext web project with Bower and are available on the view I am testing with.  In a future blog post, I’ll remove this assumption.

Step 1 – Define the Tag Helper class

A Tag Helper is just another c-sharp class that inherits from the abstract Microsoft.AspNet.Razor.TagHelpers.TagHelper class.  This abstract class contains two virtual methods for you: Process and ProcessAsync.  You can choose which of the two to implement based on whether you want your tag helper to be async or not.  For the purposes of this datetimepicker, I chose synchronous operations:

public class DateTimePickerTagHelper : TagHelper {

  public override void Process(TagHelperContext context, TagHelperOutput output) {

  }

}

The two arguments for the Process method (and they are the same in the ProcessAsync method) deliver information about the tag and its attributes on the view, and receive information you want to set on the output to be delivered to the view.

Next thing to do for this tag is to assign a custom tag name for razor to look for to identify the developer intends to trigger this helper.  This is accomplished by assigning a TagNameAttribute with an argument indicating the name of the element to be used.

I also added a ContentBehaviorAttribute to my class to indicate that I will be replacing the content of the tag in the razor view with the new content I am specifying in this class:

[TagName("kDatePicker")]
[ContentBehavior(ContentBehavior.Replace)]
public class DateTimePickerTagHelper : TagHelper

Step 2 – Attributes are Properties

Next feature for me to add is to capture configuration information from the attributes on the tag in the razor view.  I want to enable this syntax:

  <kDatePicker id="myDatePicker" value="11/17/2014" 
                  startview="year" depth="month" 
                  format="mm/dd/yyyy" />

To capture these attributes in my tag helper, I simply allocate string-typed properties for each of the attributes.  There is some desire to make these strongly typed, so that an enum or date type can be forced into each of the attributes.  This would also assist developers with intellisense in Visual Studio. Enums are already supported as a property type, and their values need to be fully-qualified with no intellisense support yet.  Hopefully that featureset will be implemented in the beta release cycle…

Step 3 – Format the Output

The last step is to format the output of the tag helper in the Process (or ProcessAsync) method. This is accomplished by using the TagHelperOutput parameter to craft your content appropriately.

In my case, I want to output an input tag and a script block as sibling elements.  If I wanted to output a parent element with a collection of child elements, I can set the tag name for that parent element using the TagName property on the output object.  Since I will be outputting a pair of sibling elements, I will set the TagName to the empty string which removes the parent element from my output.

I then build up the content that I want to output as a string and set it on the Content property of the output.  It’s that simple.  In my case, my Process method looks like this:

public override void Process(TagHelperContext context, TagHelperOutput output)
{

    output.TagName = "";

    var sb = new StringBuilder();

    sb.AppendFormat("",
        ID, Value);

    // Script
    sb.Append(""); 
    output.Content = sb.ToString();
 }

Cool... I output a standard input tag and then a script block to transform the input into a Kendo UI date picker.

Step 4 - Using the TagHelper

In my page that I want to use the tag helper on, I need to add a directive to indicate to the view engine that I have tag helpers that I want to use with this view. After adding a reference from my web project to the class library containing my tag helper, I simply add this directive to the top of the page:

@addtaghelper "KendoUI.TagHelpers"

Where KendoUI.TagHelpers is the assembly name that my DateTimePickerTagHelper lives in. When I add this syntax to my razor view:
EDIT: Corrected from namespace to assembly name

  <kDatePicker id="myDatePicker" value="11/17/2014" 
                  startview="year" depth="month" 
                  format="mm/dd/yyyy" />

I get the following appearance on my page:

KendoUI Date Picker

In my next post, I'll show you some tricks to help you get more of your JavaScript automated in your MVC project and how to build another Tag Helper from Kendo UI Core.