Built-In Tag Helpers are pre-built in the ASP.NET 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.
Page Contents
Form Tag Helpers are used 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 generating 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 tag. 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 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 Codes 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 { private IRepository repository; public HomeController(IRepository repo) { repository = repo; } public IActionResult Index() { return View(repository.Products); } public ViewResult Create() { return View(); } [HttpPost] public IActionResult Create(Product product) { repository.AddProduct(product); return RedirectToAction("Index"); } } }
I have applied the HTML for attribute on the label elements. It specifies the element with the label it is bound to.
The Input elements have been given names – ‘Name’, ‘Price’ & ‘Quantity’. These are the names of the properties of the Model class called 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. This is the technique called Model Binding and it is very-very useful in creating highest quality codes.
Now run your application and go to the URL – https://localhost:44327/Home/Create (port may be different for you). Here you will see a form, so 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:
Next fill the create form and click the Add button (see the below image).
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:
Note : Since the form in the Create View is invoking none other than the same view (i.e. create view) it is currently in, therefore there is no need to apply asp-action and asp-controller tag helpers.
The below code works just great:
<form method="post"> .... </form>
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 ASP.NET Core MVC does two things:
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. I have highlighted this code line (see below code).
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); } public ViewResult Create() { return View(); } [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:
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).
In the Controller’s action the the attribute – [ValidateAntiForgeryToken] will automatically validate this cookie and security token.
The Label element has only one Tag Helper which is called 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:
The Input element has a very useful Built-In Tag Helpers which is ‘asp-for’.
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 URL – https://localhost:44327/Home/Create that initiates the Create View. 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 shown in the below code:
<input class="form-control" type="text" id="Name" name="Name" value> <input class="form-control" type="text" data-val="true" data-val-number="The field Price must be a number." data-val-required="The Price field is required." id="Price" name="Price" value> <input class="form-control" type="number" data-val="true" data-val-required="The Quantity field is required." id="Quantity" name="Quantity" value>
You will find the Name and Price inputs are of type text but the Quantity input has the type number. The reason is because the ASP.NET Core provides the type value to HTML controls based on the Model Property Types.
The below table tells about the how the different type values 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 it’s id and name to that of the specified Model Property.
There are 2 Built-In Tag Helpers for the Select element. These are given by this table below.
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 field from input to select as shown below:
<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>
Now check the HTML code created for the select element in the browser. You will see the that it contains the id and value attributes set as Quantity. See the below code:
<select class="form-control" data-val="true" data-val-required="The Quantity field is required." 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 MVC framework is very intelligent, when you bind the select control with the Model Value then you will see the select control’s 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’s URL which is https://localhost:44327/Home/Create. Here add a new record by giving name as ‘Pants’, Price as ‘88’ and Quantity as ‘150’.
See the below image:
Now bind this last added product to the Edit View by going to it’s URL – https://localhost:44327/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" data-val="true" data-val-required="The Quantity field is required." 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.
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 source.
Change the Create View’s quantity select element’s 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 actions (HTTP GET Type). The changes are shown in the below given code in highlighted manner.
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 { private IRepository repository; public HomeController(IRepository repo) { repository = repo; } public IActionResult Index() { return View(repository.Products); } public ViewResult Create() { ViewBag.Quantity = new SelectList(repository.Products.Select(c => c.Quantity).Distinct()); return View(); } [HttpPost] [ValidateAntiForgeryToken] public IActionResult Create(Product product) { repository.AddProduct(product); return RedirectToAction("Index"); } 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 https://localhost:44327/Home/Create or https://localhost:44327/Home/Edit URLs and you will find that this time the option elements are created from the ViewBag.Quantity data source.
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 rel="stylesheet" asp-href-include="lib/bootstrap/css/bootstrap.min.css" /> </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:
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 expires. |
expires-sliding | Sliding time is the period since the last usage. So this tag helper specifies the sliding time in TimeSpan value at which cache expires. |
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. |
Change the cache code in the _Layout.cshtml file to use the expires-after tag helper as shown below.
<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.
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.
Now change the cache code in the _Layout.cshtml view to use sliding time expiry from expires-sliding tag helper.
<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 test this thing you have to 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.
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 there are 3 actions – Index, Edit and Create, so 3 versions of cache will be created (1 for each action method).
The expire-sliding tag helper set the sliding expiry time for these versions.
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 it is based on the routing system.
The concept of Routing is covered in 6 tutorials which are:
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 targeting the Create View as shown in the code below:
@model IEnumerable<Product> <a asp-action="Create" class="btn btn-dark">Create</a> <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>
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 which 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>
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:
Let us include a bootstrap.js file in the _Layout.cshtml. The location of the file is wwwroot/lib/bootstrap/js/bootstrap.js.
The location is shown in the image below:
You will notice that there are 4 JS files in the same location:
1. bootstrap.js
2. bootstrap.bundle.js
3. bootstrap.bundle.min.js
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 rel="stylesheet" asp-href-include="lib/bootstrap/css/bootstrap.min.css" /> <script asp-src-include="lib/bootstrap/**/*.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 HTML HEAD.
<head> <meta name="viewport" content="width=device-width" /> <title></title> <link rel="stylesheet" href="/lib/bootstrap/css/bootstrap.min.css" /> <script src="/lib/bootstrap/js/bootstrap.js"></script> <script src="/lib/bootstrap/js/bootstrap.bundle.js"></script> <script src="/lib/bootstrap/js/bootstrap.bundle.min.js"> </script> <script src="/lib/bootstrap/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/**/*bundle.js"></script>
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/**/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/js/bootstrap.js"></script>
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 it’s cache. 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 it’s 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 again.
Use the asp-fragment Tag Helper like shown below:
<script asp-src-include="/lib/bootstrap/**/b*.js" asp-src-exclude="**.slim.*,**.min.*,**.bundle.*" asp-append-version="true"> </script>
The HTML code now formed is:
<script src="/lib/bootstrap/js/bootstrap.js?v=82SVOjZ1qLdrq8VUmAisFapCSq1bpgavtXQaDGLPAAg"></script>
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 them from the Data Server that is closest to the geographic location of the user.
This reduces the load time of the website and also saves 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
<!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" /> <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 CDNs. Suppose, in case of some problem, the CDN fails to provide jQuery. In such a case you should load the jQuery from your website hosting 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 rel="stylesheet" asp-href-include="lib/bootstrap/css/bootstrap.min.css" /> <script src="http://ajax.aspnetcdn.com/ajax/jQuery/jquery-3.2.1.min.js" asp-fallback-src-include="/lib/jquery/**/*.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.
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 CSS 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/css folder as shown by the image given below:
To include all the bootstrap CSS files from the asp-href-include Tag Helper change the code of the layout View 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/**/*min.css" /> <script src="http://ajax.aspnetcdn.com/ajax/jQuery/jquery-3.2.1.min.js" asp-fallback-src-include="/lib/jquery/**/*.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.
This will add the files whose name end with .css. So the following 3 files are added.
<link rel="stylesheet" href="/lib/bootstrap/css/bootstrap-grid.min.css" />
<link rel="stylesheet" href="/lib/bootstrap/css/bootstrap-reboot.min.css" />
<link rel="stylesheet" href="/lib/bootstrap/css/bootstrap.min.css" />
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/**/*min.css" asp-href-exclude="**/*reboot*,**/*grid*" /> <script asp-src-include="/lib/bootstrap/**/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/**/*.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/css/bootstrap.min.css" />
You can also include CSS files from Content Delivery Networks using Tag Helpers. 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/**/*.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 src="http://ajax.aspnetcdn.com/ajax/jQuery/jquery-3.2.1.min.js" asp-fallback-src-include="/lib/jquery/**/*.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:
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:
In this tutorial I have covered most of the part of Built-in Tag Helpers. In the next tutorial I will teach you how to make Custom Tag Helpers.
Share this article -