Section 6 of 6

Tag Helpers

🎯 What You'll Learn

  • What are tag helpers
  • Built-in tag helpers
  • Form tag helpers
  • Anchor tag helper
  • Environment tag helper
  • Creating custom tag helpers

What are Tag Helpers?

Tag helpers enable server-side code to participate in creating and rendering HTML elements. They provide an HTML-friendly syntax compared to HTML Helpers.

Tag Helpers vs HTML Helpers

HTML Helper (Old) HTML
@Html.ActionLink("Products", "Index", "Products", null, new { @class = "btn btn-primary" })
Tag Helper (New) HTML
<a asp-controller="Products" asp-action="Index" class="btn btn-primary">Products</a>

Enabling Tag Helpers

Views/_ViewImports.cshtml HTML
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers

Anchor Tag Helper

Generate Links HTML
<!-- Link to action -->
<a asp-controller="Products" asp-action="Index">Products</a>

<!-- Link with route parameter -->
<a asp-controller="Products" asp-action="Details" asp-route-id="5">Details</a>

<!-- Link with multiple route values -->
<a asp-controller="Products" 
   asp-action="Search" 
   asp-route-category="Electronics" 
   asp-route-page="1">Search</a>

Form Tag Helpers

Form Tag Helper

Generate Form HTML
<form asp-controller="Products" asp-action="Create" method="post">
    <!-- Form fields -->
    <button type="submit">Create</button>
</form>

Input Tag Helper

Generate Input Fields HTML
@model Product

<form asp-action="Create">
    <!-- Text input -->
    <input asp-for="Name" class="form-control" />

    <!-- Number input -->
    <input asp-for="Price" class="form-control" />

    <!-- Checkbox -->
    <input asp-for="IsActive" type="checkbox" />
</form>

Label Tag Helper

Generate Labels HTML
<label asp-for="Name"></label>
<!-- Generates: <label for="Name">Name</label> -->

<label asp-for="Price" class="form-label"></label>

Validation Tag Helpers

Display Validation Messages HTML
<!-- Validation message for specific field -->
<span asp-validation-for="Name" class="text-danger"></span>

<!-- Validation summary for all errors -->
<div asp-validation-summary="All" class="text-danger"></div>

Select Tag Helper

Generate Dropdowns HTML
<!-- Simple select -->
<select asp-for="CategoryId" asp-items="ViewBag.Categories" class="form-control">
    <option value="">-- Select Category --</option>
</select>
Controller C#
public IActionResult Create()
{
    ViewBag.Categories = new SelectList(_context.Categories, "Id", "Name");
    return View();
}

Textarea Tag Helper

Generate Textarea HTML
<textarea asp-for="Description" class="form-control" rows="5"></textarea>

Environment Tag Helper

Conditional Rendering Based on Environment HTML
<!-- Development only -->
<environment include="Development">
    <link rel="stylesheet" href="~/css/site.css">
</environment>

<!-- Production only -->
<environment exclude="Development">
    <link rel="stylesheet" href="~/css/site.min.css">
</environment>

Image Tag Helper

Cache Busting HTML
<img src="~/images/logo.png" asp-append-version="true" />
<!-- Generates: <img src="/images/logo.png?v=abc123" /> -->

Cache Tag Helper

Cache Content HTML
<cache expires-after="@TimeSpan.FromMinutes(10)">
    <h2>Expensive Operation Result</h2>
    @await Component.InvokeAsync("ExpensiveComponent")
</cache>

Creating Custom Tag Helpers

TagHelpers/EmailTagHelper.cs C#
[HtmlTargetElement("email")]
public class EmailTagHelper : TagHelper
{
    public string Address { get; set; } = string.Empty;

    public override void Process(TagHelperContext context, TagHelperOutput output)
    {
        output.TagName = "a";
        output.Attributes.SetAttribute("href", $"mailto:{Address}");
        output.Content.SetContent(Address);
    }
}
Register Custom Tag Helper HTML
<!-- Views/_ViewImports.cshtml -->
@addTagHelper *, InvenTrack
Use Custom Tag Helper HTML
<email address="support@inventtrack.com"></email>
<!-- Generates: <a href="mailto:support@inventtrack.com">support@inventtrack.com</a> -->

Complete InvenTrack Example

Views/Products/Create.cshtml HTML
@model Product

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

<h1>Create Product</h1>

<form asp-action="Create" method="post">
    <div asp-validation-summary="ModelOnly" class="text-danger"></div>

    <div class="mb-3">
        <label asp-for="Name" class="form-label"></label>
        <input asp-for="Name" class="form-control" />
        <span asp-validation-for="Name" class="text-danger"></span>
    </div>

    <div class="mb-3">
        <label asp-for="Category" class="form-label"></label>
        <input asp-for="Category" class="form-control" />
        <span asp-validation-for="Category" class="text-danger"></span>
    </div>

    <div class="mb-3">
        <label asp-for="Price" class="form-label"></label>
        <input asp-for="Price" class="form-control" />
        <span asp-validation-for="Price" class="text-danger"></span>
    </div>

    <div class="mb-3">
        <label asp-for="Quantity" class="form-label"></label>
        <input asp-for="Quantity" class="form-control" />
        <span asp-validation-for="Quantity" class="text-danger"></span>
    </div>

    <div class="mb-3">
        <label asp-for="Description" class="form-label"></label>
        <textarea asp-for="Description" class="form-control" rows="3"></textarea>
        <span asp-validation-for="Description" class="text-danger"></span>
    </div>

    <div class="mb-3">
        <button type="submit" class="btn btn-primary">Create</button>
        <a asp-action="Index" class="btn btn-secondary">Cancel</a>
    </div>
</form>

@section Scripts {
    @await Html.PartialAsync("_ValidationScriptsPartial")
}

Common Tag Helpers Reference

Tag Helper Purpose Example
asp-controller Specify controller <a asp-controller="Products">
asp-action Specify action <a asp-action="Index">
asp-route-{param} Route parameter <a asp-route-id="5">
asp-for Bind to model property <input asp-for="Name">
asp-validation-for Validation message <span asp-validation-for="Name">
asp-items Select list items <select asp-items="ViewBag.Items">
asp-append-version Cache busting <img asp-append-version="true">

Best Practices

  • Prefer tag helpers: Use over HTML helpers for cleaner syntax
  • asp-for binding: Use for automatic validation and model binding
  • Cache busting: Use asp-append-version for static files
  • Environment tag: Serve different assets per environment
  • Custom tag helpers: Create for reusable HTML patterns
  • Validation: Always include validation tag helpers

Key Takeaways

  • Tag helpers: Server-side code in HTML-friendly syntax
  • asp-* attributes: Special attributes for tag helpers
  • asp-for: Binds to model properties
  • asp-action/asp-controller: Generate URLs
  • asp-validation-for: Display validation messages
  • Environment tag: Conditional rendering by environment
  • Custom tag helpers: Extend with TagHelper base class
  • @addTagHelper: Enable tag helpers in views
🎉 Part X Complete!

Congratulations! You've completed Part X: MVC & Views. You now understand:

  • ✅ MVC architecture and folder structure
  • ✅ Controllers, action methods, and action results
  • ✅ Razor syntax for dynamic HTML
  • ✅ Layouts, partials, and view organization
  • ✅ View components for reusable widgets
  • ✅ Tag helpers for HTML-friendly server code

You now have the skills to build server-rendered web applications with ASP.NET Core MVC! Keep up the excellent work! 🚀