Tag Helpers are a new addition in ASP.NET Core MVC, they are used to perform defined transformations on HTML elements. With Tag Helpers you can enable server-side code to participate in creating and rendering the HTML elements in Razor files.
Tag Helpers are of 2 types:
First you will look into Built-In tag helpers then I will explain how to create your own Custom Tag Helper.
Start by creating a new ASP.NET Core Web Application in your Visual Studio. Name this application as TagHelpers. Select the Empty Template, framework as .NET Core and version as ASP.NET Core 3.1.
Change the Startup.cs class content as highlighted by the code below:
using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Http; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; namespace TagHelpers { public class Startup { public void ConfigureServices(IServiceCollection services) { services.AddControllersWithViews(); } public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } else { app.UseExceptionHandler("/Home/Error"); app.UseHsts(); } app.UseHttpsRedirection(); app.UseStaticFiles(); app.UseRouting(); app.UseEndpoints(endpoints => { endpoints.MapControllerRoute( name: "default", pattern: "{controller=Home}/{action=Index}/{id?}"); }); } } }
Create a Models folder in the root of the application and add class called Products.cs to it. The code of this class is given below.
using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; namespace TagHelpers.Models { public class Product { public string Name { get; set; } public float Price { get; set; } public int Quantity { get; set; } } }
Now add a new class file called Repository.cs class inside the Models folder with the code given below:
using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; namespace TagHelpers.Models { public interface IRepository { IEnumerable<Product> Products { get; } void AddProduct(Product newProduct); } public class ProductRepository : IRepository { private List<Product> products = new List<Product> { new Product { Name = "Men Shoes", Price = 99.99F, Quantity= 100}, new Product { Name = "Women Shoes", Price = 199.99F, Quantity= 200}, new Product { Name = "Children Games", Price = 299.99F, Quantity= 300}, new Product { Name = "Coats", Price = 399.99F, Quantity= 400}, }; public IEnumerable<Product> Products => products; public void AddProduct(Product newProduct) { products.Add(newProduct); } } }
The repository.cs has an IRepository Interface which contains two members –
The repository.cs class also has a ProductRepository class that implements the IRepository Interface. The work of the ProductRepository is to provide with a repository (in-memory storage) of product to the application.
Go to the Startup class and registers the repository as a service using the singleton life cycle. This will help controllers to fetch the products from the repository without creating it’s object. This feature is known as Dependency Injection which I have explain you in details in the Dependency Injection Tutorial.
The changes which you need to make in the Startup class is highlighted in the below code:
using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Http; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using TagHelpers.Models; namespace TagHelpers { public class Startup { public void ConfigureServices(IServiceCollection services) { services.AddSingleton<IRepository, ProductRepository>(); services.AddControllersWithViews(); } public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { // keep it unchanged } } }
Create a Controllers folder in the root of your application and add an Empty Controller to it, name it as HomeController.
Change the HomeController code as shown below:
using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using Microsoft.AspNetCore.Mvc; using TagHelpers.Models; namespace TagHelpers.Controllers { public class HomeController : Controller { private IRepository repository; public HomeController(IRepository repo) { repository = repo; } public IActionResult Index() { return View(repository.Products); } } }
Notice the constructor which takes an IRepository object. The dependency injection feature will automatically create the object of the ProductRepository class when the HomeController is initiated.
This is done because I registered the ProductRepository class, as a service using the singleton life cycle, in the ConfigureServices method, there I told ASP.NET Core to automatically provide the object of the ProductRepository class whenever some code calls for creating an object of IRepository interface.
The Index Action simply returns the IEnumerable property that contains all the products in the repository.
Create a Views folder in the root of your application for keeping your View files. Inside this folder add the following 2 files:
1. _ViewStart.cshtml
@{
Layout = "_Layout";
}
2. _ ViewImports.cshtml
@using TagHelpers.Models
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
The @addTagHelper provides Built-In Tag Helpers, defined in an assembly called Microsoft.AspNetCore.Mvc.TagHelpers, available in the application.
I have also imported the TagHelpers.Models namespace so that I don’t have to import it on my views everytime.
Create a Shared folder inside the Views folder and inside this folder add _ Layout.cshtml file. Change the code of the file with the highlighted code as shown below:
<!DOCTYPE html> <html> <head> <meta name="viewport" content="width=device-width" /> <title>@ViewBag.Title</title> <link rel="stylesheet" asp-href-include="lib/bootstrap/css/bootstrap.min.css" /> </head> <body> <div class="container-fluid"> @RenderBody() </div> </body> </html>
Notice I have added the reference of bootstrap.css file in the head section of the layout. I have also given a bootstrap class to the div like class="container-fluid"
.
Create another folder called Home inside the Views folder. Next add Index View to this Home folder with contents as given below:
@model IEnumerable<Product> <table class="table table-sm table-bordered"> <thead class="bg-dark text-white"> <tr> <th>Name</th> <th>Price</th> <th>Quantity</th> </tr> </thead> <tbody> @foreach (var product in Model) { <tr> <td>@product.Name</td> <td>@product.Price</td> <td>@product.Quantity</td> </tr> } </tbody> </table>
You may remember that the Index action of the Home controller returns an IEnumerable type that contains all the products in the repository. Therefore in this view I have declared my Model as IEnumerable type. Then I am simply showing all the products in an HTML table.
Notice the code inside the tbody where I am looping through all the products to create a separate tr element for each of them.
The CSS classes used inside the table and thead are Bootstrap classes for giving them text color, border and background color.
Run your application and you will see all products displayed by the View. See the below image:
I hope this introductory tutorial has given you some insights in to the topic of Tag Helpers. Now you are ready to implement Tag Helpers so check the next tutorial on Tag Helpers – Built-In Tag Helpers in ASP.NET Core.
Share this article -