Built-In Tag Helpers in ASP.NET Core

Built-In Tag Helpers in ASP.NET Core

Built-In Tag Helpers are pre-built in the Core Framework and are used internally by the Razor. They perform common tasks like creating forms, showing validation messages, binding elements with Model, etc. In this section I am going to discuss about the Tag Helpers for Form, Input, Select, Label, Anchor, Text Area elements, CSS, JS and Cache.

If you haven’t read my last tutorial on Tag Helpers then I strongly recommend you to read it now – Introduction to Tag Helpers

Tag Helper for the Form Element

Form Tag Helpers help them to target the correct Action method based on the application’s routing configuration.

The built in Tag Helpers for the Form Element that are used for generation the action attribute are:

Method Description
asp-controller Used for specifying the controller to target based on routing system.
If omitted then the controller of the current view is used.
asp-action Used for specifying the Action method to target based on the routing system.
If omitted then the action rendering the current view is used.
asp-route-* Used for specifying the additional segment value for the URL.
Eg asp-route-id is used to provide value for the ‘id’ segment.
asp-route Used for specifying the name of the route to target for generating action attribute
asp-area Used for specifying the name of the area to target.
asp-antiforgery Generates a hidden Request Verification Token to prevent cross-site request forgery.
It is used with the [ValidateAntiForgeryToken] attribute in the HTTP Post action method.

It’s time to use these Form Tag Helpers in our application. So create a new view inside ‘Views/Home’ folder and name it ‘Create’. Add the below code to it:

@model Product

@{
    ViewData["Title"] = "Create";
}

<h2>Create</h2>

<form method="post" asp-controller="Home" asp-action="Create">
    <div class="form-group">
        <label for="Name">Name:</label>
        <input class="form-control" name="Name" />
    </div>
    <div class="form-group">
        <label for="Price">Price:</label>
        <input class="form-control" name="Price" />
    </div>
    <div class="form-group">
        <label for="Quantity">Quantity:</label>
        <input class="form-control" name="Quantity" />
    </div>
    <button type="submit" class="btn btn-primary">Add</button>
</form>

In the View I created a Form element. Notice the use of asp-controller=”Home” and asp-action=”Create” Tag Helpers to create the action attribute of the form.

The ‘Form’ has the method of type ‘post’ so that means when the form will be submitted then the ‘Create’ Action method of type HttpPost will be invoked. So go to the Home Controller and add the 2 Create actions, one for HttpGet and the Other for HttpPost.

The Code for these 2 Actions are 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
    {
        // Removed for clarity

        public ViewResult Create()
        {
            return View();
        }

        [HttpPost]
        public IActionResult Create(Product product)
        {
            repository.AddProduct(product);
            return RedirectToAction("Index");
        }
    }
} 

Remember to apply [HttpPost] attribute to the action of type Post. Actions without [HttpPost] attributes are of HttpGet type by default.

I have applied the HTML for attribute on the label elements. It specifies the element with the label is bound to.

The Input elements have been given names – ‘Name’, ‘Price’ & ‘Quantity’. These are the names of the properties of the Model Class ‘Product.cs’. By giving them these names MVC will automatically bind the parameter of the HttpPost Create Action method (i.e. public IActionResult Create(City city)) with these values.

Now run your application and go to the URL – ‘/Home/Create’ where you will see the form. Inspect the Form element in your browser and you will see the action attribute created as /Home/Create.

This is shown by the Image given below:

form action tag helper

Next fill the create form and click the ‘Add’ button (see the below image).

create form

You will find a new product is added to the repository with values you gave in the form. You will be redirected to the Index View which will show your recently added product at the last in the product list.

See the image below:

recently added product

Note: Since the Create View form’s action attribute is invoking none other than itself only therefore there is no need to apply asp-action and asp-controller tag helpers.

The below code works just great:

<form method="post">
....
</form>

asp-antiforgery Tag Helper

The asp-antiforgery Tag Helper Generates a hidden Request Verification Token to prevent cross-site request forgery (CSRF). When you use this attribute in your Form element, then Core MVC does two things:

1) Adds a security token in a hidden input element to the form.
2. Adds a cookie to the response.

The application will process the request only if it contains both the cookie and the hidden value from the form, which the malicious site cannot access, and hence CSRF is prevented.

To use this feature add the tag helper – asp-antiforgery=”true” to the form element and add the attribute [ValidateAntiForgeryToken] in the Action method.

Go to the Create View and add the asp-antiforgery attribute to the form:

@model Product

@{
    ViewData["Title"] = "Create";
}

<h2>Create</h2>

<form method="post" asp-controller="Home" asp-action="Create" asp-antiforgery="true">
    // removed for clarity
</form>

Next add the [ValidateAntiForgeryToken] attribute on the HttpPost version of the Create Action method:

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
    {
        // removed for clarity

        [HttpPost]
        [ValidateAntiForgeryToken]
        public IActionResult Create(Product product)
        {
            repository.AddProduct(product);
            return RedirectToAction("Index");
        }
    }
}

Re-run your application and check the HTML code generated for the Create View. You will find the hidden input field created inside the form element and it contains the security token as shown by the image given below:

security token

Now in the Developer Tools window, go to the ‘Application’ tab then click ‘Cookies’ on the left panel. You will see the anti-forgery cookie created by Core MVC and it will be sent to the controller along with the response (see below image).

antiforgery cookie

In the Controller’s action the applied attribute ([ValidateAntiForgeryToken]) will automatically validate this cookie and security token.

Tag Helper for the Label Elements

The Label element has only one Tag Helper which is asp-for. It is used to set the ‘for’ attribute and the ‘contents’ of the label element. To test this change the ‘Create’ View to as shown in the highlighted code below:

@model Product

@{
    ViewData["Title"] = "Create";
}

<h2>Create</h2>

<form method="post" asp-controller="Home" asp-action="Create" asp-antiforgery="true">
    <div class="form-group">
        <label asp-for="Name"></label>
        <input class="form-control" name="Name" />
    </div>
    <div class="form-group">
        <label asp-for="Price"></label>
        <input class="form-control" name="Price" />
    </div>
    <div class="form-group">
        <label asp-for="Quantity"></label>
        <input class="form-control" name="Quantity" />
    </div>
    <button type="submit" class="btn btn-primary">Add</button>
</form>

Now when you inspect the page source html you will find see these label code are:

<label for="Name">Name</label>
<label for="Price">Price</label>
<label for="Quantity">Quantity</label>

The asp-for Tag Helper does 2 things:
1. Sets the ‘for’ attribute of the label to the Model property name.
2. Sets the content of the labels to the Name of the Model Property.

Tag Helper for Input Element

The Input element has a very useful Built-In Tag Helpers which is ‘asp-for’:

  • asp-for : This tag helper sets the name, Id, type and Value attributes of the Input element.

Now Go to the ‘Create’ View and use the ‘asp-for’ tag helper for the input elements as shown in the below code:

@model Product

@{
    ViewData["Title"] = "Create";
}

<h2>Create</h2>

<form method="post" asp-controller="Home" asp-action="Create" asp-antiforgery="true">
    <div class="form-group">
        <label asp-for="Name"></label>
        <input class="form-control" asp-for="Name" />
    </div>
    <div class="form-group">
        <label asp-for="Price"></label>
        <input class="form-control" asp-for="Price" />
    </div>
    <div class="form-group">
        <label asp-for="Quantity"></label>
        <input class="form-control" asp-for="Quantity" />
    </div>
    <button type="submit" class="btn btn-primary">Add</button>
</form>

Run your application and request the ‘/Home/Create’ URL. Then check the HTML source of the Input elements. You will find the HTML of these Input elements now contains name, Id, type and Value attributes, as given in the below code:

<input class="form-control" type="text" id="Name" name="Name" value="" />
<input class="form-control" type="text" id="Price" name="Price" value="" />
<input class="form-control" type="number" id="Quantity" name="Quantity" value="" />

The Price and the Quantity Input element have additional attributes added to them. These are ‘data-val’, ‘data-val-number’, ‘data-val-required’. These are used for doing server side validation. I will teach you about them in the Model Validation Tutorial. So ignore them for the time being.

You will find the Name and Price Input controls are of type ‘text’ but the Quantity Input control has the type ‘number’. The reason is because the Core MVC provides the ‘type’ to the Input controls based on the Model Property Types.

The below table tells about the how the different types are given:

Model Type Type attribute for Input Element
byte, sbyte, int, uint, short, ushort, long, ulong Number
float, double, decimal text
string text
bool checkbox
DateTime datetime

Note: The asp-for Tag Helper when applied to a text area sets its id and name to that of the specified Model Property.

Tag Helper for the Select Element

There are 2 Built-In Tag Helpers for the Select Element. These are given by this table:

Name Description
asp-for Sets the id and name attribute of the Select Element to the Model Property name.
asp-items Specifies the source of values for the option elements contained inside the Select Element.

Let change the ‘Create’ View’s quantity input to select as shown below:

<div class="form-group">
    <label asp-for="Quantity"></label>
    <select class="form-control" asp-for="Quantity">
        <option disabled selected value="">Select Quantity</option>
        <option>50</option>
        <option>100</option>
        <option>150</option>
        <option>200</option>
    </select>
</div>

Now check the HTML code created for the select element in the browser. You will see the created code containing the ‘id’ and ‘value’ attribute set as ‘Quantity’. See the below code:

<select class="form-control" id="Quantity" name="Quantity">
    <option disabled="" selected="" value="">Select Quantity</option>
    <option>50</option>
    <option>100</option>
    <option>150</option>
    <option>200</option>
</select>

The Core MVC framework is very intelligent, when you bind the select control with the Model Value then you will see the corresponding select value being automatically selected. To check this, add an ‘Edit’ Action to the Home Controller. This action will return the last added record from the repository. The action method code is:

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
    {
        // removed for clarity

        public ViewResult Edit() => View("Create", repository.Products.Last());
    }
}

Now run your application and go to Create action URL (‘/Home/Create’). Give it name as ‘Pants’, Price as ‘88’ and Quantity as ‘150’. Now add it to the repository by clicking the add button.

See the below image:

adding new product

Now bind this last added product to the Create View by going to the URL – ‘/Home/Edit’. You will clearly see the Quantity is selected as ‘150’ in the Select control.

Check the HTML source created for the select element and notice the selected attribute (selected=”selected”) applied to the option that contains 150th value, as shown by the below code:

<select class="form-control" id="Quantity" name="Quantity">
    <option disabled="" selected="" value="">Select Quantity</option>
    <option>50</option>
    <option>100</option>
    <option selected="selected">150</option>
    <option>200</option>
</select>

This shows the intelligence of the Core MVC framework.

’asp-items’ Tag Helper

The asp-items Tag Helper is used to specify the source of values for the option elements contained inside the Select Element. This helps to generate the option elements from the data in some data source.

Change the ‘Create’ View’s quantity select element code to:

<select class="form-control" asp-for="Quantity" asp-items="ViewBag.Quantity">
    <option disabled selected value="">Select a Country</option>
</select>

I specified a ViewBag.Quantity data source for the ‘asp-items’. Now I will also have to change the Create and Edit action methods. So do the changes as shown by the code below:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using TagHelpers.Models;
using Microsoft.AspNetCore.Mvc.Rendering;

namespace TagHelpers.Controllers
{
    public class HomeController : Controller
    {
        // removed for clarity

        public ViewResult Create()
        {
            ViewBag.Quantity = new SelectList(repository.Products.Select(c => c.Quantity).Distinct());
            return View();
        }

        public ViewResult Edit()
        {
            ViewBag.Quantity = new SelectList(repository.Products.Select(c => c.Quantity).Distinct());
            return View("Create", repository.Products.Last());
        }
    }
}

The ViewBag.Quantity property is set to a SelectList object that is populated with the unique values for the Quantity property in the repository.

The SelectList object resided inside the Microsoft.AspNetCore.Mvc.Rendering namespace.

Run your application and request the ‘/Home/Create’ or ‘/Home/Edit’ URLs and you will find the option elements are created from the ViewBag.Quantity data source.

Tag Helpers for Data Cache

Data Cache is an in-memory cache for caching contents to speed up view rendering. You can keep a content of a View in cache element like:

<cache>
Some Content
</cache>

Go to the _Layout.cshtml file and add the cache element for caching the current time in hours-minutes-seconds like shown below:

<!DOCTYPE html>

<html>
<head>
    <meta name="viewport" content="width=device-width" />
    <title>@ViewBag.Title</title>
    <link href="/lib/bootstrap/dist/css/bootstrap.css" rel="stylesheet" />
</head>
<body>
    <div class="container-fluid">
        <div class="bg-info text-warning">
            <cache>
                Date Time: @DateTime.Now.ToString("HH:mm:ss")
            </cache>
        </div>
        @RenderBody()
    </div>
</body>
</html>

Now run your application and you will see the current time displayed on the top. Shown by the image given below:

caching current time

Now refresh the page and you will notice the time in hours, minutes and seconds remains the same. This is because the time is cached.

Some important Tag Helpers for the Cache Element are given below:

Name Description
expires-on Specify an absolute time in datetime value at which the cache expires.
expires-after Specifies the relative time in TimeSpan value at which the cache to expire.
expires-sliding Sliding time is the period since the last usage.
So this tag helper specifies the sliding time in TimeSpan value.
vary-by-query Specifies the query string key that will be used to manage,
the different versions of the cache contents.
vary-by-cookie Specifies the cookie name that will be used to manage
the different versions of the cache contents.
vary-by Specifies a key to manage different versions of cache contents.
Using the ‘expires-after’ Tag Helper

Change the cache code in the _Layout.cshtml view to use the expires-after tag helper:

<cache expires-after="@TimeSpan.FromSeconds(20)">
    Date Time: @DateTime.Now.ToString("HH:mm:ss")
</cache>

This means now the cache expires after 20 seconds time.

Using the ‘expires-on’ Tag Helper

Now change the cache code in the _Layout.cshtml view to use the expires-on tag helper:

<cache expires-on="@DateTime.Parse("2050-01-01")">
    Date Time: @DateTime.Now.ToString("HH:mm:ss")
</cache>

This time the cache is cached until the year 2050.

Using the ‘expires-sliding’ Tag Helper

Now change the cache code in the _Layout.cshtml view to use sliding time expiry:

<cache expires-sliding="@TimeSpan.FromSeconds(20)">
    Date Time: @DateTime.Now.ToString("HH:mm:ss")
</cache>

This will make the cache to expire in 20 second time from the last used time.

To check it keep on reloading the page every 2 second you will see the same time. Now wait for 20 seconds and then reload, and this time you will see the new time. This is because the cache expired in 20 seconds time from the last reload time.

Using the ‘vary-by’ Tag Helper

The vary-by Tag Helper is used to specify a key to manage different versions of cache contents.

Change the cache element on the _Layout.cshtml view as:

<cache expires-sliding="@TimeSpan.FromSeconds(10)" vary-by="@ViewContext.RouteData.Values["action"]">
    Date Time: @DateTime.Now.ToString("HH:mm:ss")
</cache>

This means the cache contents are made based on current action. Since we have 3 actions – ‘Index, Edit and Create’, so 3 versions of cache will be created (1 for each action method).

The expire-sliding attributes set the sliding expiry time for these versions.

Tag Helpers for Anchor Tag

There are many Built-In Tag Helpers for the Anchor Tag which are used to create href attribute with target URL of the anchor tag, and based on the routing system.

The table below lists some of the important Tag Helpers for the Anchor tag:

Name Description
asp-controller Specifies the controller the URL will target.
asp-action Specifies the action the URL will target.
asp-area Specifies the area the URL will target.
asp-fragment Specifies the URL fragment (appearing after ‘#’ character)
as-route Specifies the route name the URL will target.
asp-route-* Specifies the additional value for the URL to target.
Example asp-route-id=”10″ provide the value 10 to the id segment of the route.

Go to the Index View and create an ‘anchor link’ for the Create View as shown in the code 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>
<a asp-action="Create" class="btn btn-dark">Create</a>

This will create a link:

<a class="btn btn-dark" href="/Home/Create">Create</a>

I did not provide the asp-controller tag helper because the Create View is in the same Controller the URL targets.

If you use the asp-route-* tag helper in the Index view like:

<a asp-action="Create" asp-route-id="20" class="btn btn-dark">Create</a> 

Then the link formed will be:

<a class="btn btn-dark" href="/Home/Create/20">Create</a>

Tag Helpers for JavaScript Files

The Built-In Tag Helpers for the JavaScript files are used for managing inclusion and exclusion of JavaScript files from the Views.

Some important Tag Helpers for the JavaScript Files are:

Name Description
asp-src-include Specifies the JavaScript files to be included in the View.
asp-src-exclude Specifies the JavaScript files to be excluded from the View.
asp-append-version Specifies the query string to be applied to the JavaScript
file path whenever the contents of the file changes.
This is used for Cache Busting

asp-fallback-src-include Specifies the JavaScript file to include if there is some problem
with the Content Delivery Network.
asp-fallback-src-exclude Specifies the JavaScript file to exclude if there is some problem
with the Content Delivery Network.
asp-fallback-test Specifies a fragment of JavaScript that will be used to determine
whether the JavaScript is correctly loaded
from the Content Delivery Network.

You can also use set of wildcards to create pattern for matching files. These patterns can be used with asp-src-include, asp-src-exclude, asp-fallback-src-include and asp-fallback-src-exclude.

The Common patterns are:

Pattern Example Description
? JS/myscript?.js Matches single patter excluding ‘/’. The example on the left matches ‘JS/myscript1.js’, ‘JS/myscriptZ.js’, ‘JS/myscripts.js’, etc
* JS/*.js Matches any number of characters except ‘/’. The example given on the left side matches ‘JS/myscript.js’, ‘JS/validate.js’, ‘JS/js123.js’, etc
** JS/**.js Matches any number of characters including ‘/’. The example given on the left side matches ‘JS/Validate/myscript.js’, ‘JS/jQuery/validate.js’, ‘JS/js123.js’, etc

The patterns are very helpful because through them they make sure that the files are included in the View even if:

1. The files are removed.
2. The file names are changed.

Including JS files on the View

Let us include a ‘bootstrap.js’ file in the _Layout.cshtml. The location of the file is wwwroot/lib/bootstrap/dist/js/bootstrap.js.

The location is shown in the image below:

bootstrap js location

You will notice that there are 4 JS files in the same location:

1. bootstrap.js
2. bootstrap.bundle.js
3. bootstrap.js.map
4. bootstrap.min.js

Now go to the layout file and add the asp-src-include tag helper as shown in the code below:

<!DOCTYPE html>

<html>
<head>
    <meta name="viewport" content="width=device-width" />
    <title>@ViewBag.Title</title>
    <link href="/lib/bootstrap/dist/css/bootstrap.css" rel="stylesheet" />
    <script asp-src-include="/lib/bootstrap/dist/**/*.js"></script>
</head>
<body>
...
</body>
</html>

Run your application and inspect the generated Html Source Code. You will find 4 JS files added to the View:

<head>
    <meta name="viewport" content="width=device-width">
    <title></title>
    <link href="/lib/bootstrap/dist/css/bootstrap.css" rel="stylesheet">
    <script src="/lib/bootstrap/dist/js/bootstrap.js"></script>
    <script src="/lib/bootstrap/dist/js/bootstrap.bundle.js"></script>
    <script src="/lib/bootstrap/dist/js/bootstrap.bundle.min.js"></script>
    <script src="/lib/bootstrap/dist/js/bootstrap.min.js"></script>
</head>

The ‘asp-src-include’ Tag helper generates the script tag for files that matches the pattern.

If you want only the ‘bootstrap.bundle.js’ file included, then use the following matching pattern:

<script asp-src-include="/lib/bootstrap/dist/**/*bundle.js"></script>

Excluding JS Files from the View

The asp-src-exclude tag helper is used to exclude files from the View.

Now this time use the below code in the layout View. This will remove all the ‘slim’, ‘min’ & ‘bundle’ JavaScript files from adding to the View.

<script asp-src-include="/lib/bootstrap/dist/**/b*.js"
        asp-src-exclude="**.slim.*,**.min.*,**.bundle.*">
</script>

Run your application and check the HTML source code created. You will find only the ‘bootstrap.js’ file added this time. See the below code:

<script src="/lib/bootstrap/dist/js/bootstrap.js"></script>

Cache Busting feature from asp-fragment Tag Helper

Images, CSS files and JavaScript files are cached on the browsers. So when you visit a page what requires these cached files, then the browser provides these files to the web page directly from its caches. This makes the page to load faster as these files are not request from the server.

Suppose you change the JavaScript file on your server but the browser will continue to provide this JavaScript file, to all the pages that requires it, from its cache. So new JavaScript changes are not reflected on the pages.

So how to cope up with this problem? There has to be some way to tell the browser to download the file from the server when you do changes to the file. Addressing this problem is called Cache Busting.

Cache Busting is done with asp-fragment Tag Helper. It adds a query string to the URL of the JS file that contains a checksum that acts as a version number. Now when you make any change to the JavaScript file then the checksum automatically changes and the browser knows that now it needs to download the latest JS file from the server and do it’s caching.

Use the asp-fragment Tag Helper like shown below:

<script asp-src-include="/lib/bootstrap/dist/**/b*.js"
        asp-src-exclude="**.slim.*,**.min.*,**.bundle.*"
        asp-append-version="true">
</script>

The HTML code formed now is:

<script src="/lib/bootstrap/dist/js/bootstrap.js?v=82SVOjZ1qLdrq8VUmAisFapCSq1bpgavtXQaDGLPAAg"></script>

Including JavaScript files from Content Delivery Networks using Tag Helpers

Content Delivery Networks (CDN) contains a number of Data Servers distributed around the globe. All of these Data Servers have a saved copy of a website’s static files like images, CSS, JS. When a user opens the website in the browser then rather than requesting the static files from the website’s servers, it request from the Data Server that is closest to the geographic location of the user.

This reduces the load time of the website and also the bandwidth. I advise you to use CDN even if your website is small.

jQuery is a very popular JavaScript library which can be loaded from the ASPNET CDN. The link is:

http://ajax.aspnetcdn.com/ajax/jQuery/jquery-3.2.1.min.js
In the below highlighted code of the layout View I am loading jQuery from the ASPNET CDN:

<!DOCTYPE html>

<html>
<head>
    <meta name="viewport" content="width=device-width" />
    <title>@ViewBag.Title</title>
    <link href="/lib/bootstrap/dist/css/bootstrap.css" rel="stylesheet" />
    <script asp-src-include="/lib/bootstrap/dist/**/b*.js"
            asp-src-exclude="**.slim.*,**.min.*,**.bundle.*"
            asp-append-version="true">
    </script>
    <script src="http://ajax.aspnetcdn.com/ajax/jQuery/jquery-3.2.1.min.js"></script>
</head>
<body>
    ...
</body>
</html>

The ‘asp-fallback-src-include’, ‘asp-fallback-src-exclude’ and ‘asp-fallback-test’ Tag Helpers are made specifically to work with CDN. Suppose in case of some problem the CDN fails to provide the load of jQuery in such a case you should load the jQuery from your website server.

So update the layout’s code jQuery CDN code to this:

<!DOCTYPE html>

<html>
<head>
    <meta name="viewport" content="width=device-width" />
    <title>@ViewBag.Title</title>
    <link href="/lib/bootstrap/dist/css/bootstrap.css" rel="stylesheet" />
    <script asp-src-include="/lib/bootstrap/dist/**/b*.js"
            asp-src-exclude="**.slim.*,**.min.*,**.bundle.*"
            asp-append-version="true">
    </script>
    <script src="http://ajax.aspnetcdn.com/ajax/jQuery/jquery-3.2.1.min.js"
            asp-fallback-src-include="/lib/jquery/dist/**/*.min.js"
            asp-fallback-src-exclude="**.slim.**"
            asp-fallback-test="window.jQuery">
    </script>
</head>
<body>
    ...
</body>
</html>

The src attribute of the script tag specifies the ASPNET CDN location to load jQuery.

The asp-fallback-src-include and asp-fallback-src-exclude Tag Helpers are used to select and exclude local jQuery files in case of CDN failure.

The asp-fallback-test Tag Helper defines a JavaScript code (here ‘window.jQuery’) that will be evaluated on the browser. If the code fails only then the ‘asp-fallback-src-include’ and ‘asp-fallback-src-exclude’ tag helpers will play their part.

Tag Helpers for CSS Files

The Built-In Tag Helpers for the CSS files are used for managing their inclusion and exclusion from the Views. These Tag Helpers are described below:

Name Description
asp-href-include Specifies the CSS files to be included in the View.
asp-href-exclude Specifies the JavaScript files to be excluded from the View.
asp-append-version Specifies the query string to be applied to the CSS file’s path
whenever the contents of the file changes. This is used for Cache Busting

asp-fallback-href-include Specifies the CSS file to include if there is some problem
with the Content Delivery Network.
asp-fallback-href-exclude Specifies the CSS file to exclude if there is some problem
with the Content Delivery Network.
asp-fallback-href-test-class Specifies a CSS class that will be used to test the Content Delivery Network.
asp-fallback-href-test-property Specifies a CSS class property that will be used to test the Content Delivery Network.
asp-fallback-href-test-value Specifies a CSS class property value that will be used to
test the Content Delivery Network.

My application has many Bootstrap CSS files located under the wwwroot/lib/bootstrap/dist/css folder as shown by the image given below:

bootstrap css files location

Including CSS files on the View

To include all the bootstrap CSS files from the asp-href-include Tag Helper change the code of the layout View as highlighted below:

<!DOCTYPE html>

<html>
<head>
    <meta name="viewport" content="width=device-width" />
    <title>@ViewBag.Title</title>
    <link rel="stylesheet" asp-href-include="/lib/bootstrap/dist/**/*min.css" />
    <script asp-src-include="/lib/bootstrap/dist/**/b*.js"
            asp-src-exclude="**.slim.*,**.min.*,**.bundle.*"
            asp-append-version="true">
    </script>
    <script src="http://ajax.aspnetcdn.com/ajax/jQuery/jquery-3.2.1.min.js"
            asp-fallback-src-include="/lib/jquery/dist/**/*.min.js"
            asp-fallback-src-exclude="**.slim.**"
            asp-fallback-test="window.jQuery">
    </script>
</head>
<body>
    ....
</body>
</html>

I have used the patters (** and *) for matching the files.
** – for any number of characters including charcter ‘/’.
* – for any number of characters excluding charcter ‘/’.

This will add the files that end whose name end with ‘.css’. So the following 3 files are added.

<link rel="stylesheet" href="/lib/bootstrap/dist/css/bootstrap-grid.min.css">
<link rel="stylesheet" href="/lib/bootstrap/dist/css/bootstrap-reboot.min.css">
<link rel="stylesheet" href="/lib/bootstrap/dist/css/bootstrap.min.css">

Excluding CSS files on the View

The asp-href-exclude Tag Helper is used to exclude CSS files from View. Now use this tag helper to remove the ‘reboot’ and ‘grid’ CSS files.

See the code below:

<!DOCTYPE html>

<html>
<head>
    <meta name="viewport" content="width=device-width" />
    <title>@ViewBag.Title</title>
    <link rel="stylesheet" asp-href-include="/lib/bootstrap/dist/**/*min.css" 
                           asp-href-exclude="**/*reboot*,**/*grid*" />
    <script asp-src-include="/lib/bootstrap/dist/**/b*.js"
            asp-src-exclude="**.slim.*,**.min.*,**.bundle.*"
            asp-append-version="true">
    </script>
    <script src="http://ajax.aspnetcdn.com/ajax/jQuery/jquery-3.2.1.min.js"
            asp-fallback-src-include="/lib/jquery/dist/**/*.min.js"
            asp-fallback-src-exclude="**.slim.**"
            asp-fallback-test="window.jQuery">
    </script>
</head>
<body>
    ....
</body>
</html>

Now this time only 1 CSS file is included:

<link rel="stylesheet" href="/lib/bootstrap/dist/css/bootstrap.min.css"> 

Including CSS files from Content Delivery Networks using Tag Helpers

You can also include CSS files from Content Delivery Networks using Tag Helper. Let me show you how to add ‘bootstrap.min.css’ file from MaxCDN.

Add the below highlighted code to the layout file:

<!DOCTYPE html>

<html>
<head>
    <meta name="viewport" content="width=device-width" />
    <title>@ViewBag.Title</title>
    <link href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.6/css/bootstrap.min.css"
          asp-fallback-href-include="/lib/bootstrap/dist/**/*.min.css"
          asp-fallback-href-exclude="**/*reboot*,**/*grid*"
          asp-fallback-test-class="btn"
          asp-fallback-test-property="display"
          asp-fallback-test-value="inline-block"
          rel="stylesheet" />
    <script asp-src-include="/lib/bootstrap/dist/**/b*.js"
            asp-src-exclude="**.slim.*,**.min.*,**.bundle.*"
            asp-append-version="true">
    </script>
    <script src="http://ajax.aspnetcdn.com/ajax/jQuery/jquery-3.2.1.min.js"
            asp-fallback-src-include="/lib/jquery/dist/**/*.min.js"
            asp-fallback-src-exclude="**.slim.**"
            asp-fallback-test="window.jQuery">
    </script>
</head>
<body>
    ....
</body>
</html>

The href attribute specifies the CDN URL which in my case is the MaxCDN URL for bootstrap.min.cs file.

The asp-fallback-href-include and asp-fallback-href-exclude Tag Helpers are used to select the files from the website directory if the CDN is unavailable.

The next 3 Tag Helpers are used to test whether the bootstrap file correctly downloaded from the CDN or not. These tag helpers are:

1. asp-fallback-test-class
2. asp-fallback-test-property
3. asp-fallback-test-value

They work by adding a meta element to the document that has been added to the class defined by the ‘asp-fallback-test-class’ tag helper.

In my case the meta element added to the document will be:

<meta name="x-stylesheet-fallback-test" class="btn" />

Now the ‘asp-fallback-test-property’ tag helper is used to specify a CSS property that is set by this CSS class (here ‘btn’), and the ‘asp-fallback-test-value’ tag helper is used to specify the value that it will be set to.

These tag helper also add JavaScript to the view that tests the value of the CSS property on the meta element to figure out whether the CSS file has been loaded perfectly from the CDN or not. If the JavaScript test fails then the fallback CSS files are used instead.

You can download the source code using the below link:

Download

Conclusion

In this tutorial I have covered most of the part of Tag Helpers. In the next tutorial I will teach you how to make Custom Tag Helpers.

Share this article -

yogihosting

ABOUT THE AUTHOR

This article has been written by the Technical Staff of YogiHosting. Check out other articles on "WordPress, SEO, jQuery, HTML" and more.