ASP.NET 5 news - Tag Helpers

by DotNetNerd 11. December 2015 11:17

Xplat has been the big topic around ASP.NET 5, but to be honest it does not matter that much for many of us. Sure it is always nice to have options, but if you work in a Microsoft shop or at an enterprise who see them selves as based on Microsoft technologies, then that is not likely to change - and why should it? The good news is that taking the framework and tooling apart to enable these options also brings a more aligned and flexible architecture, that solves some of the issues with eg. build setups that we have today. With that said, xplat is not all that ASP.NET 5 is about.

Tag helpers is a new concept, which aimes at removing some of the ugly constructs that we use today in Razor views, and enable a more declarative approach. Basically tag helpers allow us to hook into custom to tags and attributes and apply logic where they are used. An obvious usecase, which is often seen in demoes, is making attributes where we can specify which controller and action a form posts to like this.

<form asp-controller="Account" asp-action="Login">

Along with removing the funky construct of a using statement around a call to a helper method, this new way of wiring up the form also takes care of injecting an anti forgery token. So in one swoop it makes the markup more readable and brings us a small step toward being more secure by default.

Personally I am often a bit sceptical about these kinds of abstractions, because they often tend to get complicated and hard to debug for real world scenarios. The good news with tag helpers is that they are in them selves quite simple. Simple as in you can implement your own by inheriting the TagHelper class and overriding a single method called Process, or its counterpart ProcessAsync. Binding html attributes to properties on the implementing class is done by convention, but it is no more magic than model binding, which is a pretty well known concept by now - and if you don't like the convention, the attribute name can be specified using an attribute. Lets see how that looks.


[HtmlTargetElement("HelloWorld", TagStructure= TagStructure.NormalOrSelfClosing)]
public class HelloWorldTagHelper : TagHelper
{
    public string Name { get; set; }

    public override async Task ProcessAsync(TagHelperContext context, TagHelperOutput output)
    {
        output.Content.AppendEncoded($"Hello {Name}");
    }
}

With this in place all we need to do is register the taghelper in the _ViewImports.cshtml file.

@addTagHelper "*, MyFancyProject"

And the it can be used like this from any Razor view.

<HelloWorld name="John"></HelloWorld>

This is of course just showing the bare minimum, but we could easilly build something usable from this. If for instance we need a tag helper that would allow us to use markdown inside the view, it could simply read in the html content inside the tag, use a library to convert the markdown to html and replace the content with the html.

[HtmlTargetElement("Markdown", TagStructure= TagStructure.NormalOrSelfClosing)]
public class MarkdownTagHelper : TagHelper
{
    public override async Task ProcessAsync(TagHelperContext context, TagHelperOutput output)
    {
        var childContent = await context.GetChildContentAsync();
        var content = childContent.GetContent();

        output.SuppressOutput();
        output.Content.AppendEncoded(CommonMark.CommonMarkConverter.Convert(content));
    }
}

And with just those few lines of code we now have a basic but working markdown tag.

<Markdown>**This rocks!**</Markdown>

I think this is really a nice and powerful addition to APS.NET and Razor, but as with a lot of technologies I see a potential for developers to come up with a tangled mess, if they start (ab)using this to try and make yet another kind of web components. So for me it will be interesting to see how people will use it in real life, but I do hope if will be with an emphasis on the postfix "Helpers".

Who am I?

My name is Christian Holm Diget, and I work as an independent consultant, in Denmark, where I write code, give advice on architecture and help with training. On the side I get to do a bit of speaking and help with miscellaneous community events.

Some of my primary focus areas are code quality, programming languages and using new technologies to provide value.

Microsoft Certified Professional Developer

Microsoft Most Valuable Professional

Month List