Tag Helpers in ASP.NET Core MVC

Tag Helpers in ASP.NET Core MVC

In this article, I will discuss Tag Helpers in ASP.NET Core MVC Applications with Examples. Tag helpers are one of the new features introduced in ASP.NET Core MVC. Please read our previous article discussing How to Create Custom HTML Helpers in ASP.NET Core MVC Applications. As part of this article, we will discuss the following pointers.

  1. What are Tag Helpers in ASP.NET Core MVC?
  2. Key Characteristics of Tag Helpers in ASP.NET Core MVC
  3. Types of Tag Helpers in ASP.NET Core MVC
  4. Built-in Tag Helpers Type in ASP.NET Core MVC
  5. How to Use Tag Helpers in ASP.NET Core MVC?
  6. Example to Understand Built-in Tag Helpers in ASP.NET Core MVC
  7. Generating Links using Tag Helpers in ASP.NET Core MVC Application
  8. Understanding Anchor Tag Helper in ASP.NET Core MVC
What are Tag Helpers in ASP.NET Core MVC?

Tag Helpers in ASP.NET Core MVC allow us to write HTML-like code that is closely associated with C# backend code. They simplify the process of generating HTML elements in views. Tag Helpers are useful because they allow you to keep your HTML clean and readable while still providing powerful data-binding and server-side logic capabilities directly within your views.

Types of Tag Helpers in ASP.NET Core MVC:

ASP.NET Core MVC has two main types of Tag Helpers: Built-in Tag Helpers and Custom Tag Helpers. Both types of Tag Helpers contribute to simplifying the process of generating HTML elements in views, but they serve different purposes.

Built-in Tag Helpers:

These Tag Helpers are provided by default as part of the ASP.NET Core framework. They cover common scenarios and tasks, such as generating links, creating forms, showing validation messages, etc. Some examples of built-in Tag Helpers include:

  • <a asp-controller=”Home” asp-action=”Index”>Link</a>: Generates a link with a URL that’s generated by routing based on the specified controller and action.
  • <img src=”~/images/pic.jpg” asp-append-version=”true” />: Generates a <img> tag with a cache-busting query string to ensure the latest version of the image is fetched.
  • <form asp-controller=”Account” asp-action=”Login” method=”post”>…</form>: Generates a form element with the appropriate action attribute for the specified controller and action.
  • <input asp-for=”Username” />: Generates an input field with attributes based on the model property specified by asp-for.
Custom Tag Helpers:

Custom Tag Helpers allow us to encapsulate complex UI logic and generate HTML output based on our application’s requirements. They are defined by extending the TagHelper class and overriding its methods. 

To create a custom Tag Helper, we need to define a class that derives from the TagHelper base class and override the Process/ProcessAsync method to generate the desired HTML output. You can then use your custom Tag Helper in your Razor views by referencing it with the appropriate HTML-like syntax.

Note: In this article, I will give an overview of Built-in Tag Helpers, and in our upcoming articles, I will discuss How to Create Custom Tag Helpers

Built-in Tag Helpers Type in ASP.NET Core MVC:

In ASP.NET Core MVC, several built-in HTML Tag Helpers cover common HTML elements and scenarios. These tag helpers simplify generating HTML markup while still allowing you to incorporate server-side logic. Here are some of the types of HTML Tag Helpers available:

Anchor Tag Helpers (<a>):

These tag helpers generate hyperlinks. You can use them to create links to different actions, controllers, or URLs. Examples include:

<a asp-controller="Home" asp-action="Index">Home</a>
<a asp-controller="Home" asp-action="Details" asp-route-id="42">Details</a>
Form Tag Helpers (<form>):

These tag helpers generate HTML forms. They help create forms that post data to actions in your controllers. Examples include:

<form asp-controller="Account" asp-action="Login" method="post">
<!-- form fields -->
</form>
Image Tag Helper (<img>):

This tag helper generates image elements with the appropriate src attribute. You can use it to include images in your views. Example:

<img src="~/images/pic.jpg" alt="Picture">
Input Tag Helpers (Various Input Elements):

These tag helpers generate various types of input elements such as text boxes, checkboxes, radio buttons, etc. Examples include:

<input asp-for="Name" />
<input asp-for="IsAdmin" type="checkbox" />
Cache Tag Helpers (<cache>):

These help cache portions of your views to improve performance by reducing the need to recompute content on every request. Example:

<cache>
<!-- Content to be cached -->
</cache>
Localization Tag Helpers:

These help render content based on the current culture and provide localized strings. Example:

<localized asp-culture="en-US">Hello!</localized>
Environment Tag Helper:

This tag helper conditionally renders content based on the hosting environment. It can be useful for including different content for development and production environments.

Partial Tag Helper:

This tag helper renders a partial view within another view. It’s useful for breaking down complex views into smaller components.

View Component Tag Helper:

This tag helper renders a view component within a view. View components are similar to partial views but offer more encapsulation and flexibility.

How to Use Tag Helpers in ASP.NET Core MVC?

Using Tag Helpers in ASP.NET Core MVC is relatively straightforward. Here’s a step-by-step guide on how to use Tag Helpers in your ASP.NET Core MVC application:

  1. Create a New ASP.NET Core MVC Project: If you haven’t already, create a new ASP.NET Core MVC project using your preferred development tools.
  2. Add Views and Controllers: Set up your controllers and views as needed for your application.
  3. Understand Built-in Tag Helpers: Familiarize yourself with the built-in Tag Helpers provided by ASP.NET Core. These include helpers for generating links, forms, images, and more.
  4. Using Built-in Tag Helpers: To use a built-in tag helper, include the appropriate HTML-like syntax in your Razor views.
Example to Understand Built-in Tag Helpers in ASP.NET Core MVC:

Let us understand how to use built-in tag helpers with an example from an ASP.NET Core MVC application. So, create a new ASP.NET Core Application named TagHelpersDemo using the Model-View-Controller Project template. To make the Built-in Tag Helpers available for all views of our application, we need to import them inside the _ViewImports.cshtml file using the @addTagHelper directive, as shown below.

@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers

The line @addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers is a directive that brings in a set of Tag Helpers from the specified assembly, making them available to the view in which the directive is declared. Let’s break this down for clarity:

  • @addTagHelper: This is the directive used to add Tag Helpers to a view. Tag Helpers enable server-side code to participate in creating and rendering HTML elements in Razor files. 
  • *: The asterisk (*) is a wildcard character that specifies that all Tag Helpers from the given assembly should be available for the view. This means you don’t have to add each Tag Helper individually; instead, you can include them all at once with this wildcard.
  • AspNetCore.Mvc.TagHelpers: This specifies the assembly containing the Tag Helpers you are adding to your view. Microsoft.AspNetCore.Mvc.TagHelpers is the assembly that comes with ASP.NET Core MVC and provides a set of built-in Tag Helpers for common tasks like creating forms, links, loading scripts, etc. By adding this assembly, you get access to these helpers, which can make your Razor views more readable and easier to maintain by reducing the amount of explicit HTML and JavaScript code you need to write.
Generating Links using Tag Helpers in ASP.NET Core MVC Application:

Let us understand this with an example. First, create a class file named Student.cs within the Models folder. Once you create the Student.cs class file, then copy and paste the following code into it. As you can see, this is a very simple Student Model having only five properties holding the Student ID, Name, Branch, Section, and Gender.

namespace TagHelpersDemo.Models
{
    public class Student
    {
        public int StudentId { get; set; }
        public string? Name { get; set; }
        public string? Branch { get; set; }
        public string? Section { get; set; }
        public string? Gender { get; set; }
    }
}
Modifying Home Controller:

Modify the HomeController as shown below. Here, we have created two action methods. To simplify things and keep the focus on Tag helpers, we have hard-coded the required student data using the action method. The Index action method returns a list of students to the view, whereas the Details action method takes the student ID as a parameter and returns that student information to the view.

using TagHelpersDemo.Models;
using Microsoft.AspNetCore.Mvc;

namespace TagHelpersDemo.Controllers
{
    public class HomeController : Controller
    {
        private List<Student> listStudents;
        public HomeController()
        {
            //Create a List of Students
            //In Real-Time, you will get the data from the database
            listStudents = new List<Student>()
            {
               new Student() { StudentId = 101, Name = "James", Branch = "CSE", Section = "A", Gender = "Male" },
               new Student() { StudentId = 102, Name = "Smith", Branch = "ETC", Section = "B", Gender = "Male" },
               new Student() { StudentId = 103, Name = "David", Branch = "CSE", Section = "A", Gender = "Male" },
               new Student() { StudentId = 104, Name = "Sara", Branch = "CSE", Section = "A", Gender = "Female" },
               new Student() { StudentId = 105, Name = "Pam", Branch = "ETC", Section = "B", Gender = "Female" }
            };
        }
        public ViewResult Index()
        {
            //Pass the Student List to the View to make the view as a Strongly Typed View
            return View(listStudents);
        }

        public ViewResult Details(int Id)
        {
            //Fetch the Student Details
            var studentDetails = listStudents.FirstOrDefault(std => std.StudentId == Id);

            //Pass the Student model to the View to make the view as a Strongly Typed View
            return View(studentDetails);
        }
    }
}

Creating Details View:

Create a view named Details.cshtml within the Views=>Home folder, then copy and paste the following code.

@model TagHelpersDemo.Models.Student
@{
    ViewBag.Title = "Student Details";
    Layout = "~/Views/Shared/_Layout.cshtml";
}

<div class="row m-3">
    <div class="col-sm-8">
        <div class="card">
            <div class="card-header text-center">
                <h1>@Model?.Name</h1>
            </div>

            <div class="card-body text-center">
                <h4>Studnet ID : @Model?.StudentId</h4>
                <h4>Branch : @Model?.Branch</h4>
                <h4>Section : @Model?.Section</h4>
                <h4>Gender : @Model?.Gender</h4>
            </div>
            <div class="card-footer text-center">
                <a href="#" class="btn btn-primary">Back</a>
            </div>
        </div>
    </div>
</div>
Modifying Index View:

Now, in the index view, we have to provide the View button as a link. When we click the View button, we need to display the Student Details. For example, we need to generate the following hyperlink. The number 101 is the ID of the student whose details we want to view.

/home/details/101

There are many different methods for generating a link in the ASP.NET Core MVC Application. Let’s discuss all the possible options, and then we will discuss why we should use Tag Helper over others.

Method 1: Using HTML Element:

In this case, we need to use the anchor tag, and in the href attribute, we need to specify the path of the details action method along with the student id like <a href=”/home/details/@student.StudentId”>View</a>. So, modify the Index action method of the Home Controller as follows.

@model List<TagHelpersDemo.Models.Student>
@{
    ViewBag.Title = "Student List";
    Layout = "~/Views/Shared/_Layout.cshtml";
}

<div class="table-responsive">
    <table class="table">
        <thead>
            <tr>
                <th>ID</th>
                <th>Name</th>
                <th>View</th>
            </tr>
        </thead>
        <tbody>
            @foreach (var student in Model)
            {
                <tr>
                    <td>@student.StudentId</td>
                    <td>@student.Name</td>
                    <td><a href="/home/details/@student.StudentId" class="btn btn-primary">View</a></td>
                </tr>
            }
        </tbody>
    </table>
</div>

With the above changes in place, run the application and navigate to the Root URL or Home/Index URL. You should see the following page on the web browser.

Tag Helpers in ASP.NET Core MVC Applications with Examples

Once you click on the View button, it will execute the Details action method of the Home Controller by passing the Student ID value 101, and hence, you will see the following Details view of the Home Controller showing the Student details.

Tag Helpers in ASP.NET Core MVC Applications with Examples

Method 2: Using HTML Helpers

Using HTML Helper methods, we can also generate the link. In this case, we need to use the ActionLink Helper method to generate the link like @Html.ActionLink(“View”, “Details”, “Home”, new {id = student.StudentId}).

Here, the parameter View is nothing but the link text; the second parameter Details is the Action method name; the third parameter Home is the controller’s name, and the fourth parameter is object routeValues, which specifies the id parameter value. So, modify the Index.cshtml view of the Home Controller as follows to use the HTML Helper Method to generate the link.

@model List<TagHelpersDemo.Models.Student>
@{
    ViewBag.Title = "Student List";
    Layout = "~/Views/Shared/_Layout.cshtml";
}

<div class="table-responsive">
    <table class="table">
        <thead>
            <tr>
                <th>ID</th>
                <th>Name</th>
                <th>View</th>
            </tr>
        </thead>
        <tbody>
            @foreach (var student in Model)
            {
                <tr>
                    <td>@student.StudentId</td>
                    <td>@student.Name</td>
                    <td>@Html.ActionLink("View","Details","Home", new {id = student.StudentId})</td>
                </tr>
            }
        </tbody>
    </table>
</div>

With the above changes in place, run the application and see if everything is working as expected.

Method 3: Using Tag Helpers:

To use Tag Helpers, first, we need to import the @addTagHelper directive in the _ViewImport.cshtml file. We also add the model namespace using the @using directive. So, modify the _ViewImport.cshtml file as shown below, which you can find within the Views folder.

@using TagHelpersDemo
@using TagHelpersDemo.Models
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers

With these changes in place, you can now access the types defined with the above-using namespace throughout the application without re-specifying the namespace and all the tag helpers you can access from all the views. Next, modify the Index view of the Home Controller as shown below. Here, we are using Tag Helpers.

@model List<TagHelpersDemo.Models.Student>
@{
    ViewBag.Title = "Student List";
    Layout = "~/Views/Shared/_Layout.cshtml";
}

<div class="table-responsive">
    <table class="table">
        <thead>
            <tr>
                <th>ID</th>
                <th>Name</th>
                <th>View</th>
            </tr>
        </thead>
        <tbody>
            @foreach (var student in Model)
            {
                <tr>
                    <td>@student.StudentId</td>
                    <td>@student.Name</td>
                    <td>
                        <a asp-controller="Home"
                           asp-action="Details"
                           asp-route-id="@student.StudentId">View</a>
                    </td>
                </tr>
            }
        </tbody>
    </table>
</div>

Now, run the application, and it should work as expected.

Understanding Anchor Tag Helper in ASP.NET Core MVC:

The Anchor Tag Helper in ASP.NET Core creates the standard HTML anchor (<a … ></a>) tag by adding attributes such as:

  • asp-controller: It is used to specify the controller to target based on the routing system. If you omitted this, then the controller of the current view is used by default.
  • asp-action: It is used to specify the Action method to target based on the routing system. If you omit this attribute, the action rendering the current view is the default.
  • asp-route-{value}: It specifies the additional segment value for the URL. For example, asp-route-id provides value for the ‘id’ segment.

The value of the rendered anchor element’s “href” attribute is determined by the values of these “asp-“ attributes. As the name says, asp-controller specifies the controller’s name, whereas asp-action specifies the name of the action name. Similarly, the asp-route-{value} attribute includes route data in the generated href attribute value. {value} can be replaced with route parameters such as id, name, etc. Let us have a look at the following image for a better understanding.

Tag Helpers in ASP.NET Core MVC Applications

As you can see in the above image, manually generating the links is much easier than using HTML Helpers or Tag Helpers. So why should we use HTML helpers or Tag Helpers instead of manually generating these links in ASP.NET Core?

Why should we use Tag Helpers over manually generating these links in ASP.NET Core?

In ASP.NET Core MVC, Tag Helpers generate links based on the application routing templates. That means if we change routing templates in the future, the links generated by tag helpers will automatically reflect those changes. So, the generated links work as expected without any trouble.

On the other hand, if we have hard-coded the URL paths manually, we need to change the code wherever we have hard-coded the path in our application when the application routing templates change. Let’s understand this with an example. The following is the Main method of the Program class of our application.

namespace TagHelpersDemo
{
    public class Program
    {
        public static void Main(string[] args)
        {
            var builder = WebApplication.CreateBuilder(args);

            // Add services to the container.
            builder.Services.AddControllersWithViews();

            var app = builder.Build();

            // Configure the HTTP request pipeline.
            if (!app.Environment.IsDevelopment())
            {
                app.UseExceptionHandler("/Home/Error");
                // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
                app.UseHsts();
            }

            app.UseHttpsRedirection();
            app.UseStaticFiles();

            app.UseRouting();

            app.UseAuthorization();

            app.MapControllerRoute(
                name: "default",
                pattern: "{controller=Home}/{action=Index}/{id?}");

            app.Run();
        }
    }
}

As you can see in the above code, currently, we have the route template pattern as {controller=Home}/{action=Index}/{id?}.

Generating Link Manually: We can generate the link manually using the following code by hard-coding the URL paths as /Home/Details.

<a href=”/Home/Details/@student.StudentId”>View</a>

Generating Link using Tag Helper: In the following code, we generate the link using anchor tag helper.

<a asp-controller=”Home” asp-action=”Details” asp-route-id=”@student.StudentId”>View</a>

As you can see with Tag Helper, we have not hardcoded the URL paths. Here, we only specify the controller and action name, route parameters, and their values. When the tag helpers are executed on the server, they automatically look at the route templates and generate the correct URLs.

Here, both the techniques generate the same URL path, i.e. (/Home/Details/101), and it also works with the current route template, i.e. ({controller=Home}/{action=Index}/{id?})

Now, let us change the routing template as shown below. Notice here the route template pattern. We have added the string literal “dotnet”.

Tag Helpers in ASP.NET Core MVC

So, with the above changes in place, manually generating the link will not work if you run the application, whereas the link generating with Tag Helpers will work as expected.

In the next article, I will discuss the Image Tag Helper in ASP.NET Core MVC Application. In this article, I try to explain the basics of Tag Helpers in an ASP.NET Core MVC Application with examples. I hope you enjoy this article.

Leave a Reply

Your email address will not be published. Required fields are marked *