Orchard Harvest 2015 – ASP.NET MVC 6 Tag Helpers

Taylor Mullen was here to introduce the tag helpers that are going to be added to ASP.NET MVC 6, basically to replace HTML helpers. Tag helpers are html tag-like bits of C# code. Because they are essentially C#, you can get all the benefits of the IDE, such as IntelliSense and refactoring.

Out of the box, there will be tag helpers for forms, labels, inputs, that understand additional attributes. For example, <label asp-for=”Email”> will behave like @Html.LabelFor(m => m.Email).

The <environment> tag can hide or show parts of the page based on environment variables such as debug mode.

A common observation is that these tag helpers are doing on the server side what Angular does on the client side.

Tag helper source code can already be found in the MVC source code repo:
https://github.com/aspnet/Mvc/tree/dev/src/Microsoft.AspNet.Mvc.TagHelpers

To begin using tag helpers in all views, they can be added to _ViewImports.cshtml with a few using and @AddTagHelpers directives.

In order to build a tag helper, all you need to do is implement ITagHelper. This interface has an Order read-only property, and a ProcessAsync method that does the actual work.

public class EmailTagHelper: TagHelper {
  public string MailTo {get;set;}
  public override async Task ProcessAsync(TagHelperContext context, TagHelperOutput output) {
    output.TagName = "a";
    var email = MailTo + "@contoso.com";
    output.Attributes["href"] = "mailto:" + email;
output.Content.SetContent(MailTo);

return base.ProcessAsync(context, output); } }

This can then be used as follows:

<email mail-to="support"><email/>

Next, Taylor showed how to build a markdown tag helper. This one uses the contents of the tag as the input for the markdown. Because Razor is now fully asynchronous, he needs to get that contents using await context.GetChildContent().

After that, Taylor showed how view components can implement something similar to Orchard’s shapes, using tag helpers for nicer markup. His tag helper is getting IViewComponentHelper as a constructor-injected dependency, and then using that to invoke his shape-like view component. He also had to do property injection for his view context. The whole thing is a little more complex than Orchard’s shapes, but he does get full IntelliSense on the tag helper. It also makes it possible to have arbitrary C# expressions in attribute values. The added complexity involved looks like it could easily be fixed with a good base class.

Taylor then showed how to change his markdown tag helper into a tag attribute helper, so that you can do <ul markdown> and have the contents of the tag be fed into the markdown parser using a [HtmlTargetElement(“*”, Attributes(“markdown”)] attribute.

If you want to hide a property from the tag helper, you can use [HtmlAttributeNotBound].

Because of the way tag helpers are architected, as bits of C# that enrich the view code, it is possible to have more than one tag helper targeting the same HTML element. Taylor illustrated that by applying a Bold and the markdown tag helper that he made before. This explains why the tag helper interface has an Order property.

UPDATE: the video is online.

No Comments