ASP.NET Nuggets – Tag Helpers

In ASP.NET Core 1.0 MVC (Previously referred to as MVC 6) they’ve introduced Tag Helpers, which replaces the old Html Helpers. The idea is that we can create standard Html markup but still have the ability to allow the server to “enrich” this markup without being too obtrusive.

The old way (Html Helpers)

Let’s say we need to create a form, that posts data to the Save action on a PatientController. We have an html form, a label and input TextBox:

using (Html.BeginForm("Save", "Patient", FormMethod.Post, new { @class = "form-control", data_extraInfo = "myextrainfo" }))
   @Html.LabelFor(x => x.Name, "First Name", new { @class = "control-label" })
   @Html.EditorFor(x => x.Name, new { htmlAttributes = new { @class = "form-control" } })

Here’s some more code. We have 2 different anchor tags, the first being incorrect and the second correct. The right thing that should happen is to create a link saying “Go Back”, which will call the GoBack action on the PatientController with PatientID as a parameter.

@Html.ActionLink("Go Back", "GoBack", "Patient", new { PatientID = Model.ID })

@Html.ActionLink("Go Back", "GoBack", "Patient", new { PatientID = Model.ID }, null)

There are several difficulties with this code above:

  1. We have no idea how exactly how the html actually renders (have to run and inspect).
  2. The closing form tag is a curly brace and in a large page, it’s difficult to tell if the curly brace we see closes the form or is it actually to close a `loop` or `if` statement.
  3. Simple Html attributes need to be created anonymous types (not transparent).
  4. Since anonymous Html attributes are C# anon types, some attributes conflict with reserved C# keywords (such as class has to become @class).
  5. If we want some data-dash attributes for our client-side code to use, we have to use underscores as we can’t use dashes in C# variables.
  6. The `LabelFor`, expects htmlAttributes parameter, so we say `new { @class = “…” }`, but the `EditorFor` expects additionalViewData, so we’d have nest the Html attributes like this `new { htmlAttributes = new { @class = “…” } }`. Certainly this is a very error-prone approach.
  7. In the 2nd code snippet we can see how adding the null parameter at the end makes the action link behave correctly. This is because the first uses a different overload that actually omits the controller and so the “Patient” string actually is incorrectly passed through as `RouteData` and the `RouteData` as `HtmlAttributes` (so easy to get it wrong as it compiles fine).

The new way (Tag Helpers)


Html Helpers get the work done, but there’s now a much more efficient way. Here’s the same result using Tag Helpers:

<form asp-controller="Patient" asp-action="Save" method="post" class="form-control" data-extraInfo="myextrainfo">
   <label asp-for="Name" class="control-label">First Name</label>
   <input asp-for="Name" class="form-control" />

And here’s the action link using Tag Helpers:

<a asp-controller="Patient" asp-action="GoBack" asp-route-PatientID="@Model.PatientID">Go Back</a>

You’ll notice in the above 2 snippets, we’ve simply written standard Html Markup and the server enriched parts prefixed with asp-. Introducing Tag Helpers has helped us overcome all 7 of the difficulties mentioned earlier.

The beauty of Tag Helpers is that they’re truly WYSIWYG (What you see is what you get). Now we have the benefit of enriching our Html with server code, but still just write Html.


Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )


Connecting to %s