Form Tag Helpers in ASP.NET Core MVC

Form Tag Helpers in ASP.NET Core MVC

In this article, I will discuss the Form Tag Helpers in ASP.NET Core MVC Application with Examples. Please read our previous article discussing about creating a Responsive Navigation Menus in ASP.NET Core Applications. I will discuss creating a Form in ASP.NET Core Application using the Form Tag Helpers in this article. We will work with the same example we created in our previous article.

What are the Tag Helpers used to Create a Form in ASP.NET Core MVC?

Tag Helpers in ASP.NET Core MVC make binding and generating HTML elements in Razor views easier. ASP.NET Core MVC Framework provides several Tag Helpers to simplify form generation, binding, and validation when creating forms. At the end of this article, we will create a form using Tag Helpers, as shown below. The following form is used to create a Student.

Form Tag Helpers in ASP.NET Core MVC Application with Examples

Form Tag Helper in ASP.NET Core:

<form>: Used to generate a form element.

  • asp-action: Specifies the action method to be called on form submission.
  • asp-controller: Specifies the controller that contains the action method.
  • asp-route: Used for additional route values.
  • asp-antiforgery: Automatically includes anti-forgery tokens if set to true (default is true).

To create a Form in ASP.NET Core MVC View, we need to use the <form> tag helper. The syntax for using the Form Tag Helper is shown below. The <form> tag helper binds to the <form> HTML element. We can specify which action and controller the form should submit to using the asp-action and asp-controller attributes.

<form asp-controller="Home" asp-action="Create" method="post"> 
</form>

As you can see in the above code, we are using the asp-controller and asp-action attributes within the Form Tag Helper. These two tag attributes specify the controller and the action method to submit the form data. The method attribute specifies whether it is a Get or Post Request. When the form is submitted, we want to issue a post request, so we set the method type to post. If you want to submit the data to an action method of HTTP Get type, you need to specify the method type as Get.

Note: If you didn’t specify the controller and action name using the asp-controller and asp-action tag helpers, then by default, when the form is submitted, it will invoke the same action method of the controller that rendered the form.

Input Tag Helper in ASP.NET Core MVC:

<input>: Generates input elements and automatically binds them to model properties

  • asp-for: Specifies the model property to which the input is bound.
  • asp-isrequired: Adds the required attribute if the model indicates the required field.

The input tag helpers bind to the <input> HTML element. These are versatile and generate different input types based on your model attributes. This helps to automate the generation of id, name, and value attributes based on model property conventions, facilitates validation, and provides enhanced Razor syntax highlighting and IntelliSense support. The type of input generated is inferred from the model property’s type. For instance:

  • string maps to type=”text”
  • bool maps to type=”checkbox”
  • DateTime or DateTime? maps to type=”datetime-local”

Here, we want a form to create a new Student. So, the model for our view is Student class, and we can specify the model using the following directive.
@model Student

We want to display a text box in our form to capture the student’s name. We also want that text box to bind with the Name property of the Student model class. This can be done easily using the asp-for Tag helper, as shown below.

<input asp-for="Name" class="form-control">

As you can see here, we set the value for the asp-for tag helper to the Name property of the Student model class. You will also get IntelliSense support while setting the value property. Later, if you change the property name from Name to StudnetName on the Student class and do not change the value assigned to the tag helper, you will get a compiler error.

The above input tag helper generates an input element with id and name attributes. Both the ID and name are set to a value such as Name, as shown below.

<input type="text" id="Name" name="Name" value="" class="form-control">
Label Tag Helper in ASP.NET Core MVC:

<label>: Automatically generates labels associated with model properties. It helps in generating correct for attributes linking the label to the respective input.

  • asp-for: Specifies which model property this label is for.

Using the asp-for attribute, the <label> tag helper can generate a label for an associated input element. The Label Tag Helper in ASP.NET Core generates a label. The “asp-for” attribute links the label with its corresponding input element. For example,

<label asp-for="Name"></label>
<input asp-for="Name" class="form-control">

The above code generates the following HTML.

<label for="Name">Name</label>
<input type="text" id="Name" name="Name" value="" class="form-control">

Here, the label is linked with the input element. This is because the label for the attribute and the input element id attribute have the same value (i.e., Name). That means the corresponding input element will receive the focus when we click on the label.

TextArea Tag Helper in ASP.NET Core MVC:

The <textarea> tag helper functions similarly to the input tag helper and binds to the <textarea> HTML element. But here, it specifically targets the Textarea element instead of the input element. The textarea tag helper adds the asp-for tag helper attribute to a text area element. For example, let’s say our Student model has a property to store the address, then for address property, we can use textarea tag helper as shown below.

<textarea asp-for="Address" class="form-control"></textarea>

The text area tag helper will generate Name and Id properties based on the Property Name specified in the asp-for attribute. If you want to display the textarea with a specified number of rows and cols, you need to use the following attributes.

<textarea asp-for="Address" rows="4" cols="30" class="form-control"></textarea>
Checkbox tag helper in ASP.NET Core MVC:

In ASP.NET Core MVC, you can use the input tag helper to create checkboxes. Suppose we have a model class named Student with a property IsRegular of boolean type indicating whether the student is a regular student or not. To create a checkbox for the IsRegular property, we would use the input tag helper as follows:

<label>
    <input asp-for="IsRegular" type="checkbox" /> Is Regular Student
</label>

The asp-for attribute binds the checkbox to the IsRegular property. When the form is submitted, the value of the checkbox (either true or false) will be bound to the IsRegular property of the model. By default, if the value of IsRegular Property in the model is true, the checkbox will be rendered as checked. Otherwise, it will be unchecked.

Select Tag Helper in ASP.NET Core MVC:

<select>: Generates drop-down lists bound to model properties.

  • asp-for: Specifies the model property to bind the select to.
  • asp-items: Specifies the options for the dropdown list.

The Select Tag helper in ASP.NET Core generates a select tag with associated option elements. Let us assume the following Branches Property hold the list of all branches.
public List<SelectListItem> Branches{ get; set; }

In our example, we want a dropdown list to display the list of Branches. We also want a label that should be linked with the select element. The following code does the same.

<label for="Branch">Branch</label>
<select asp-for="Branch" asp-items="Model.Branches"></select>

The options for the branch select element can be hard-coded like in the example below, or they can also come from an enum or a database table. In our example, we will use an enum for the select options.

<label for="Branch">Branch</label>

<select id="Branch" name="Branch">
    <option value="0">None</option>
    <option value="1">CSE</option>
    <option value="2">ETC</option>
    <option value="3">Mech</option>
</select>
Radio Button Tag Helper in ASP.NET Core MVC:

The radio button control is designed to support selecting only one of a mutually exclusive set of predefined options. In ASP.NET Core MVC, the radio button tag helper can be used to generate <input type=”radio”> elements that bind to model properties. This is particularly helpful for scenarios where you want to provide multiple options but allow only one selection.

Let’s consider an example to illustrate the use of the radio button tag helper. Assume we have a model property Gender with possible values “Male,” “Female,” and “Other.” Let us assume we have a property called Gender in our model to hold the Gender value. In our Razor view, we can use the tag helper to bind radio buttons to the Gender property as follows.

<input asp-for="Gender" type="radio" value="Male" id="male" />
<label for="male">Male</label>

<input asp-for="Gender" type="radio" value="Female" id="female" />
<label for="female">Female</label>

<input asp-for="Gender" type="radio" value="Other" id="other" />
<label for="other">Other</label>

Here, the asp-for attribute is set to the model property (Gender in this case). Each radio button has a different value attribute, representing each possible value for the Gender property. The id attribute binds the <label> elements to the respective radio buttons. When the form is submitted, the Gender property of the model will be populated with the value of the selected radio button, thanks to the model binding.

Validation Tag Helpers in ASP.NET Core MVC:

<span>: Displays validation messages.

  • asp-validation-for: Specifies the model property for which the validation message is displayed.
  • asp-validation-summary: Specifies the validation summary display mode (All, ModelOnly, or None).

Syntax: <span asp-validation-for=”Email” class=”text-danger”></span>

Generating Hidden Inputs

To generate a hidden input field:

<input asp-for="Id" type="hidden" />

This is often used to pass IDs, or other data users should not see or edit.

Setting Placeholder, Autocomplete, and Other Attributes

Just like regular HTML attributes, you can set attributes like placeholder, autocomplete, etc:

<input asp-for="Email" placeholder="Enter your email" autocomplete="off" class="form-control" />
Form Action Tag Helpers:

<button asp-action=”…”>: Generates a button that submits the form to a specific action.

<button asp-action="Submit" class="btn btn-primary">Submit</button>

<a asp-action=”…”>: Generates an anchor tag that links to a specific action. Useful for cancel buttons or navigation links within forms.

<a asp-action="Index" class="btn btn-secondary">Cancel</a>
Creating the Form using Form Tag Helpers in ASP.NET Core MVC:

First, we need to create the required models as follows:

Gender.cs:

Create a class file named Gender.cs, then copy and paste the following code. This is going to be an enum which will represent the gender-named constants.

namespace FirstCoreMVCApplication.Models
{
    public enum Gender
    {
        Male,
        Female
    }
}
Branch.cs

Create a class file named Branch.cs and copy and paste the following code into it. This is going to be an enum which will represent the branches named constants.

namespace FirstCoreMVCApplication.Models
{
    public enum Branch
    {
        None,
        CSE,
        ETC,
        Mech
    }
}
Student.cs

Create a class file with the name Student.cs and copy and paste the following code into it. This will be a class that will hold the student data, and this will be our model.

namespace FirstCoreMVCApplication.Models
{
    public class Student
    {
        public int StudentId { get; set; }
        public string? Name { get; set; }
        public string? Email { get; set; }
        public string? Password { get; set; }
        public Branch? Branch { get; set; }
        public Gender? Gender { get; set; }
        public bool IsRegular { get; set; }
        public string? Address { get; set; }
        public DateTime DateOfBorth { get; set; }
    }
}
Modifying Home Controller:

Next, modify the Home Controller as follows. Here, we are adding the Create action method.

using FirstCoreMVCApplication.Models;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Rendering;

namespace FirstCoreMVCApplication.Controllers
{
    public class HomeController : Controller
    {
        //Create a Variable to Hold List of Students
        //This is going to be our data source
        private List<Student> listStudents = new List<Student>();
        public HomeController()
        {
            //Within the Constructor we are Initializing listStudents variable
            //In Real-Time, we will get the data from the database
            listStudents = new List<Student>()
            {
               new Student() { StudentId = 101, Name = "James", Branch = Branch.CSE, Gender = Gender.Male, Address = "A1-2018", Email = "James@g.com" },
               new Student() { StudentId = 102, Name = "Priyanka", Branch = Branch.ETC, Gender = Gender.Female, Address = "A1-2019", Email = "Priyanka@g.com" },
               new Student() { StudentId = 103, Name = "David", Branch = Branch.CSE, Gender = Gender.Male, Address = "A1-2020", Email = "David@g.com" },
               new Student() { StudentId = 104, Name = "Pranaya", Branch = Branch.Mech, Gender = Gender.Male, Address = "A1-2021", Email = "Pranaya@g.com" }
            };
        }
        public ViewResult Index()
        {
            //returning all the students
            return View(listStudents);
        }

        public ViewResult Details(int Id)
        {
            //returning the student based on the Student Id
            var studentDetails = listStudents.FirstOrDefault(std => std.StudentId == Id);
            return View(studentDetails);
        }

        [HttpGet]
        public ViewResult Create()
        {
            ViewBag.AllGenders = Enum.GetValues(typeof(Gender)).Cast<Gender>().ToList();
            
            ViewBag.AllBranches = new List<SelectListItem>()
            {
                new SelectListItem { Text = "None", Value = "1" },
                new SelectListItem { Text = "CSE", Value = "2" },
                new SelectListItem { Text = "ETC", Value = "3" },
                new SelectListItem { Text = "Mech", Value = "4" }
            };

            return View();
        }
    }
}
Creating the Create View:

Now add a view named Create.cshtml to the Home folder of your application. Once you add the Create.cshtml view, copy and paste the following code.

@model FirstCoreMVCApplication.Models.Student

@{
    ViewBag.Title = "Create";
    Layout = "~/Views/Shared/_Layout.cshtml";
    var Branches = ViewBag.AllBranches as List<Branch>;
}

<div>
    <form asp-controller="Home" asp-action="Create" method="post" class="mt-3">
        <div style="margin-top:7px" class="form-group row">
            <label asp-for="Name" class="col-sm-2 col-form-label"></label>
            <div class="col-sm-10">
                <input asp-for="Name" class="form-control" placeholder="Enter Your Name">
            </div>
        </div>
        <div style="margin-top:7px" class="form-group row">
            <label asp-for="Email" class="col-sm-2 col-form-label"></label>
            <div class="col-sm-10">
                <input asp-for="Email" class="form-control" placeholder="Enter Your Email Id">
            </div>
        </div>
        <div style="margin-top:7px" class="form-group row">
            <label asp-for="Password" class="col-sm-2 col-form-label"></label>
            <div class="col-sm-10">
                <input asp-for="Password" class="form-control" placeholder="Enter Your Password">
            </div>
        </div>

        <div style="margin-top:7px" class="form-group row">
            <label asp-for="Branch" class="col-sm-2 col-form-label"></label>
            <div class="col-sm-10">
                <select asp-for="Branch" class="custom-select mr-sm-2"
                        asp-items="Html.GetEnumSelectList<Branch>()"></select>
                @*<select asp-for="Branch" asp-items="ViewBag.AllBranches"></select>*@
            </div>
        </div>

        <div style="margin-top:7px" class="form-group row">
            <label asp-for="IsRegular" class="col-sm-2 col-form-label"></label>
            <div class="col-sm-10">
                <input type="checkbox" class="custom-control-input" asp-for="IsRegular">
            </div>
        </div>

        <div style="margin-top:7px" class="form-group row">
            <label asp-for="DateOfBorth" class="col-sm-2 col-form-label"></label>
            <div class="col-sm-10">
                <input asp-for="DateOfBorth" class="form-control">
            </div>
        </div>

        <div style="margin-top:7px" class="form-group row">
            <label asp-for="Gender" class="col-sm-2 col-form-label"></label>
            <div class="col-sm-10">
                @foreach (var gender in ViewBag.AllGenders)
                {
                    <label class="radio-inline">
                        <input type="radio" asp-for="Gender" value="@gender" id="Gender@(gender)" />@gender<br />
                    </label>
                }
            </div>
        </div>

        <div style="margin-top:7px" class="form-group row">
            <label asp-for="Address" class="col-sm-2 col-form-label"></label>
            <div class="col-sm-10">
                <textarea asp-for="Address" class="form-control" placeholder="Enter Your Address"></textarea>
            </div>
        </div>

        <div style="margin-top:10px" class="form-group row">
            <div class="col-sm-10">
                <button type="submit" class="btn btn-primary">Create</button>
            </div>
        </div>
    </form>
</div>
Modifying Layout View:

If you are coming directly to this article without reading our previous article, then please modify the _Layout.cshtml view as follows:

<!DOCTYPE html>
<html>
<head>
    <meta name="viewport" content="width=device-width" />
    <title>@ViewBag.Title</title>
    <link href="~/css/MyCustomStyleSheet.css" rel="stylesheet" />
    <link href="~/lib/twitter-bootstrap/css/bootstrap.css" rel="stylesheet" />
    <script src="~/lib/jquery/jquery.js"></script>
    <script src="~/lib/twitter-bootstrap/js/bootstrap.js"></script>
</head>
<body>
    <div class="container">
        <nav style="margin-top:15px" class="navbar navbar-expand-sm bg-dark navbar-dark">
            <a style="margin-left:5px" class="navbar-brand" asp-controller="home" asp-action="index">
                <img src="~/images/Logo.png" width="50" height="50">
            </a>
            <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#collapsibleNavbar">
                <span class="navbar-toggler-icon"></span>
            </button>
            <div class="collapse navbar-collapse" id="collapsibleNavbar">
                <ul class="navbar-nav">
                    <li class="nav-item">
                        <a class="nav-link" asp-controller="home" asp-action="index">List</a>
                    </li>
                    <li class="nav-item">
                        <a class="nav-link" asp-controller="home" asp-action="create">Create</a>
                    </li>
                    <li>
                        <a class="nav-link" asp-controller="home" asp-action="about">About</a>
                    </li>
                    <li>
                        <a class="nav-link" asp-controller="home" asp-action="contact">Contact</a>
                    </li>
                </ul>
            </div>
        </nav>

        <div>
            @RenderBody()
        </div>
    </div>
</body>
</html>

Now, run the application and click on the Create Menu, and you should see the required view as expected. Form tag helpers in ASP.NET Core MVC provide a more concise way to bind form elements to model properties, manage validation, and handle form submissions, making the Razor views cleaner and more maintainable.

In the next article, I will discuss Partial Tag Helper in ASP.NET Core MVC Applications. In this article, I try to explain Form Tag Helpers in ASP.NET Core MVC Application with examples. I hope you enjoy this Form Tag Helpers in ASP.NET Core MVC article.

Leave a Reply

Your email address will not be published. Required fields are marked *