All About Tag Helpers In ASP.NET Core 2.0

This time rather than jumping directly into the topic, first, let's have a look at the Login form code which you must have definitely seen while working on an MVC application.

  1. <section id="loginForm">  
  2.             @using (Html.BeginForm("Login", "Account", new { ReturnUrl = ViewBag.ReturnUrl }, FormMethod.Post, new { @class = "form-horizontal"role = "form" }))  
  3.             {  
  4.                 @Html.AntiForgeryToken()  
  5.                 <h4>Use a local account to log in.</h4>  
  6.                 <hr />  
  7.                 @Html.ValidationSummary(true, "", new { @class = "text-danger" })  
  8.                 <div class="form-group">  
  9.                     @Html.LabelFor(m => m.Email, new { @class = "col-md-2 control-label" })  
  10.                     <div class="col-md-10">  
  11.                         @Html.TextBoxFor(m => m.Email, new { @class = "form-control" })  
  12.                         @Html.ValidationMessageFor(m => m.Email, "", new { @class = "text-danger" })  
  13.                     </div>  
  14.                 </div>  
  15.                 <div class="form-group">  
  16.                     @Html.LabelFor(m => m.Password, new { @class = "col-md-2 control-label" })  
  17.                     <div class="col-md-10">  
  18.                         @Html.PasswordFor(m => m.Password, new { @class = "form-control" })  
  19.                         @Html.ValidationMessageFor(m => m.Password, "", new { @class = "text-danger" })  
  20.                     </div>  
  21.                 </div>  
  22.                 <div class="form-group">  
  23.                     <div class="col-md-offset-2 col-md-10">  
  24.                         <div class="checkbox">  
  25.                             @Html.CheckBoxFor(m => m.RememberMe)  
  26.                             @Html.LabelFor(m => m.RememberMe)  
  27.                         </div>  
  28.                     </div>  
  29.                 </div>  
  30.                 <div class="form-group">  
  31.                     <div class="col-md-offset-2 col-md-10">  
  32.                         <input type="submit" value="Log in" class="btn btn-default" />  
  33.                     </div>  
  34.                 </div>  
  35.                 <p>  
  36.                     @Html.ActionLink("Register as a new user", "Register")  
  37.                 </p>  
  38.                 @* Enable this once you have account confirmation enabled for password reset functionality  
  39.                     <p>  
  40.                         @Html.ActionLink("Forgot your password?", "ForgotPassword")  
  41.                     </p>*@  
  42.             }  
  43. </section>  

What do you think about the above code snippet?

Indeed, it works alright, but there are a few problems with this. The major problem is that it's a bit messy and difficult to read due to excessive use of @. So, now that we have understood the problem; what is the solution? Here come  Tag Helpers to our rescue. Let's quickly have a look at the code generated by the ASP.NET Core framework for the same functionality:
  1. <section>  
  2.             <form asp-controller="Account" asp-action="Login" method="post">  
  3.                 <h4>Use a local account to log in.</h4>  
  4.                 <hr />  
  5.                 <div asp-validation-summary="All" class="text-danger"></div>  
  6.                 <div class="form-group">  
  7.                     <label asp-for="Input.Email"></label>  
  8.                     <input asp-for="Input.Email" class="form-control" />  
  9.                     <span asp-validation-for="Input.Email" class="text-danger"></span>  
  10.                 </div>  
  11.                 <div class="form-group">  
  12.                     <label asp-for="Input.Password"></label>  
  13.                     <input asp-for="Input.Password" class="form-control" />  
  14.                     <span asp-validation-for="Input.Password" class="text-danger"></span>  
  15.                 </div>  
  16.                 <div class="form-group">  
  17.                     <div class="checkbox">  
  18.                         <label asp-for="Input.RememberMe">  
  19.                             <input asp-for="Input.RememberMe" />  
  20.                             @Html.DisplayNameFor(m => m.Input.RememberMe)  
  21.                         </label>  
  22.                     </div>  
  23.                 </div>  
  24.                 <div class="form-group">  
  25.                     <button type="submit" class="btn btn-default">Log in</button>  
  26.                 </div>  
  27.                 <div class="form-group">  
  28.                     <p>  
  29.                         <a asp-page="./ForgotPassword">Forgot your password?</a>  
  30.                     </p>  
  31.                     <p>  
  32.                         <a asp-page="./Register" asp-route-returnUrl="@Model.ReturnUrl">Register as a new user</a>  
  33.                     </p>  
  34.                 </div>  
  35.             </form>  
  36. </section>  

The above code looks much cleaner. Isn’t it? If it looks interesting to you, we should learn more about it.

What are Tag Helpers?

Tag Helpers are classes written in C# but are attached to HTML elements in order to run server-side code from Razor view. In other words, view created in HTML has its presentation logic defined in C#, which is ultimately executed on the web server. Examples of common built-in Tag Helpers are Anchor tag, Environment tag, Cache tag, etc. Understood ... Not Understood ... Confused? 

No worries. As we proceed further, things will be much clearer.

Using Tag Helpers

So, how do we go about using Tag Helpers? In order to use the inbuilt or custom Tag Helpers, one has to first reference Tag Helper library named Microsoft.AspNetCore.Mvc.TagHelpers. It can also be taken from Nuget. Once referenced, import it using @AddTagHelper directive as shown below inside _ViewImports.cshtml,

  1. @addTagHelper *,Microsoft.AspNetCore.Mvc.TagHelpers  
In the above line, all the Tag helpers will be imported which are mentioned in 'Microsoft.AspNetCore.Mvc.TagHelpers' assembly. As mentioned in my previous article, whatever is referenced/imported inside _ViewImports.cshtml will be available for all the views. If you don't want any of your views to use globally imported Tag Helpers, you can use @removeTagHelper in the respective view.

Where can I use Tag Helpers?

The majority of Tag Helper use cases fall into one of these categories: 1) Take existing HTML elements and customize their output 2) Define totally new elements with custom or not output, i.e. Environment

Creating Custom Tag Helpers

Now we have a basic idea of what Tag Helper is, so how about creating our own Tag Helper. Let's go ahead and quickly create our own Tag Helper step by step. I'll take a very simple scenario, in which we will introduce a simple tag named 'Appreciate' which will take the value as a person name's and it will be displayed on the screen.

Create a new class named AppreciateTagHelper and add the code as shown below,
  1. public class AppreciateTagHelper: TagHelper {  
  2.     private  
  3.     const string appreciationText = "Great work";  
  4.     public string PersonName {  
  5.         get;  
  6.         set;  
  7.     }  
  8.     public override async Task ProcessAsync(TagHelperContext context, TagHelperOutput output) {  
  9.         output.TagName = "Appreciation";  
  10.         string message = $ "{appreciationText}, {PersonName}";  
  11.         var attribute = new TagHelperAttribute(name: "Label", value: message);  
  12.         output.Attributes.Add(attribute);  
  13.         output.Content.SetContent(message);  
  14.     }  
  15. }  
Next is to import the newly created Tag Helper and that can be done by adding a line in _ViewImports.cshtml file as shown below,
  1. @addTagHelper *,CustomTagHelper  
Then last is to update the respective view and the code for that is:
  1. <appreciate person-name="Shweta"></appreciate>  
We are all set with our custom Tag Helper and now it's time to view it in a browser. Quickly run the application and verify the output. You will be able to see the output as shown below:

 

Takeaways

  1. One has the benefit of getting away from the @ symbol in Razor view and the code looks cleaner, and is more maintainable and readable.
  2. Tag Helpers are not a replacement for HTML helpers.

References

  1. Tag Helpers VS HTML Helpers
  2. Tag Helpers in ASP.NET Core
Hope you enjoyed learning about Tag Helpers.