Click here to Skip to main content
15,867,488 members
Articles / Web Development / ASP.NET

ASP.NET Core 2.0 MVC Tag Helpers

Rate me:
Please Sign up or sign in to vote.
2.29/5 (5 votes)
27 Aug 2017CPOL2 min read 12.6K   3  
How to use Tag Helpers in ASP.NET Core MVC to simplify the creation of data entry forms. Continue reading...

Problem

How to use Tag Helpers in ASP.NET Core MVC to simplify the creation of data entry forms.

Solution

In an empty project, update Startup class to add services and middleware for MVC: public void ConfigureServices( IServiceCollection services) { services.AddMvc(); } public void Configure( IApplicationBuilder app, IHostingEnvironment env) { app.UseDeveloperExceptionPage(); app.UseMvc(routes => { routes.MapRoute( name: "namedRoute", template: "call-named-route/{id?}", defaults: new { controller="Home", action="NamedRoute" }); routes.MapRoute( name: "default", template: "{controller=Home}/{action=Index}/{id?}"); }); }

Add a controller with these action methods:

C#
public IActionResult Index()
{
    var model = new EmployeeViewModel();
    return View(model);
}

[HttpPost]
public IActionResult Index(EmployeeViewModel model)
{
    if (!ModelState.IsValid)
    {
        return View(model);
    }
    var json = JsonConvert.SerializeObject(model);
    return Content(json);
}

public IActionResult Echo(int id)
{
    return Content(id.ToString());
}

public IActionResult NamedRoute(int id)
{
    return Content(id.ToString());
}

Add a _ViewImports.cshtml page in Views folder. Add directive to import tag helpers:

C#
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers

Add a model to use in data entry screen:

C#
public enum Gender { Male = 1, Female = 2}

public class EmployeeViewModel
{
    [HiddenInput]
    public int Id { get; set; }

    [Required]
    public string Firstname { get; set; }

    [EmailAddress]
    public string Email { get; set; }

    [Url]
    public string BlogUrl { get; set; }

    [Phone]
    public string MobileNo { get; set; }

    [DataType(DataType.Password)]
    public string Password { get; set; }

    [DataType(DataType.Date)]
    public DateTime BirthDate { get; set; }

    public double Salary { get; set; }

    [Display(Name = "Part Time?")]
    public bool IsPartTime { get; set; }

    public string Notes { get; set; }

    public string Title { get; set; }
    public IEnumerable<string> Interests { get; set; }
    public Gender Gender { get; set; }

    public List<SelectListItem> GetTitles()
    { ... }

    public List<SelectListItem> GetInterests()
    { ... }
}

Add a razor page (Index.cshtml):

Razor
@using  Fiver.Mvc.TagHelpers.Models.Home
@model EmployeeViewModel

@* Form *@
<form asp-controller="Home" asp-action="Index" method="post">
    @* Validation Summary *@
    <div asp-validation-summary="All"></div>

    @* Label, Input, Validation(span) *@
    <input asp-for="Id" />

    <label asp-for="Firstname"></label> 
    <input asp-for="Firstname" /> 
    <span asp-validation-for="Firstname"></span> <br />
    
    <label asp-for="BirthDate"></label>
    <input asp-for="BirthDate" asp-format="{0:dd/MM/yyyy}"/>
    <span asp-validation-for="BirthDate"></span> <br />

    @* Textarea *@
    <label asp-for="Notes"></label>
    <textarea asp-for="Notes"></textarea>
    <span asp-validation-for="Notes"></span> <br />

    @* Select (single) *@
    <label asp-for="Title"></label>
    <select asp-for="Title" asp-items="Model.GetTitles()">
        <option value="">--select--</option>    
    </select><br />

    @* Select (multiple) *@
    <label asp-for="Interests"></label>
    <select asp-for="Interests" asp-items="Model.GetInterests()"></select><br />

    @* Select (enum) *@
    <label asp-for="Gender"></label>
    <select asp-for="Gender" asp-items="Html.GetEnumSelectList<Gender>()">
        <option value="" selected>--select--</option>  
    </select><br />

    <br />
    <button type="submit">Save</button><br />
</form>

Discussion

Tag Helpers help generate HTML by attaching attributes to existing HTML elements or by creating new elements. Although they look like HTML elements and attributes, Tag Helpers are processed by Razor (server-side).

I like to think of Tag Helpers as C# extensions methods, i.e., they allow us to attach extra behaviour to existing classes.

The sample project shows the usage of various tag helpers that can help in creating data entry forms. I’ll outline the key information about these below:

Form

  • Generates HTML form’s action attribute
  • Generate a hidden verification token field used with [ValidateAntiForgeryToken] attribute on [HttpPost] action method
  • Can specify asp-route-[param], however it will be ignored if the route parameter exists in the form as well
  • Can use asp-route for named routes

Input & Text Area

  • Generates id and <strong>name
  • Generate validation attributes
  • Generate type attribute based on model’s property type and data annotations

Label

  • Generate for
  • Picks the [Display] attribute on model property as label text

Validation

  • <strong>asp-validation-for: generates validation message for single property on model.
  • asp-validation-summary: generates validation messages for model and it’s properties. You could choose option to suppress individual property messages.

Select

  • Generates select and option
  • Can be populated by List<SelectListItem>, received from model or injected service
  • Can be populated by specifying enum type, using GetEnumSelectList()
  • Multi-selection enabled if asp-for is IEnumerable
  • Can add default option too, these will be combined with the ones from data source

Anchor

  • Can generate href based on controller, action and route parameters
  • Can generate href based route name
  • Can generate href based host and protocol
  • asp-route-[param] transmitted as query string if [param] not part of the route
ASP.NET
<a asp-controller="Home" asp-action="Echo" asp-route-id=@Model.Id>Echo!</a><br />
    <a asp-route="namedRoute" asp-route-id=@Model.Id>Call Named Route</a><br />
    <a asp-host="tahir-naushad.com" asp-protocol="http">Blog</a>

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



Comments and Discussions

 
-- There are no messages in this forum --