Editor HTML Helper in ASP.NET Core MVC

Editor HTML Helper in ASP.NET Core MVC

In this article, I will discuss How to Use Editor HTML Helper in ASP.NET Core MVC Application to generate input HTML elements. Please read our previous article, where we discussed How to Generate a List Box using List Box HTML Helper in ASP.NET Core MVC Application.

Editor HTML Helper in ASP.NET Core MVC

As of now, we have seen and used different types of HTML Helper methods to generate different types of HTML elements in ASP.NET Core MVC applications. In ASP.NET Core MVC, the Editor helper method generates HTML input elements based on the data type of the model property to which it’s bound. It automatically selects the appropriate input type based on the model property’s data annotations and type. This flexibility makes it very useful for creating form elements dynamically, especially in scenarios where the form is generated based on the model properties.

Data Types and Its Equivalent HTML Elements:

In ASP.NET Core MVC, the Editor helper method dynamically chooses the appropriate HTML element based on the data type of the model property it’s bound to. This decision-making is facilitated by editor templates and the data annotations that might be applied to your model properties. The following diagram lists the HTML element created for each data type by the Editor() or EditorFor() method.

How to Use Editor HTML Helper in ASP.NET Core MVC Application

Example to Understand Editor HTML Helper Method in ASP.NET Core MVC:

Editor is a generic method that creates an input element for the specified model property. The Editor HTML Helper method requires a string expression as a parameter to specify the property name. Syntax: @Html.Editor(“PropertyName”)

Let’s understand how to use Editor HTML Helper in an ASP.NET Core MVC Application with one example. First, create a class file named Employee.cs within the Models folder and copy and paste the following code.

namespace HTML_HELPER.Models
{
    public class Employee
    {
        public string Name { get; set; }         // string
        public int Age { get; set; }             // int
        public decimal Salary { get; set; }      // decimal
        public bool IsEmployed { get; set; }     // bool
        public DateTime DateOfBirth { get; set; } // DateTime
        public List<string> Skills { get; set; } // List<string>
        public Gender Gender { get; set; }       // Enum
        public IFormFile ProfilePicture { get; set; } // IFormFile
        public Guid UserId { get; set; }         // Guid
        public TimeSpan WorkingHours { get; set; } // TimeSpan
    }

    public enum Gender
    {
        Male,
        Female,
        Other
    }
} 
Modifying the Home Controller:

Next, create an Empty MVC Controller named EmployeeController within the Controllers folder and copy and paste the following code.

using HTML_HELPER.Models;
using Microsoft.AspNetCore.Mvc;

namespace HTML_HELPER.Controllers
{
    public class EmployeeController : Controller
    {
        [HttpGet]
        public IActionResult Create()
        {
            // Populating Employee with some dummy data
            var model = new Employee
            {
                Name = "Pranaya Rout",
                Age = 35,
                Salary = 55000.00m,
                IsEmployed = true,
                DateOfBirth = new DateTime(1988, 02, 29),
                Gender = Gender.Male,
                Skills = new List<string>() { "C#", "ASP.NET Core" },
                ProfilePicture = null, 
                UserId = Guid.NewGuid(),
                WorkingHours = new TimeSpan(8, 0, 0) // 8 hours
            };

            return View(model);
        }

        [HttpPost]
        public IActionResult Create(Employee model)
        {
            if (ModelState.IsValid)
            {
                // Save the model to the database or process it here.
                return RedirectToAction("Success");
            }

            return View(model);
        }

        public string Success()
        {
            return "Employee Created/Modified Successfully";
        }
    }
}
Creating the Create.cshtml View:

Next, create the Create.cshtml view and copy and paste the following code.

@model Employee

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

<form asp-action="Create" asp-controller="Employee" method="post" enctype="multipart/form-data">

    <div class="row mb-3">
        <div class="col-md-3">
            @Html.Label("Name", "Name", new { @class = "form-label" })
        </div>
        <div class="col-md-9">
            @Html.Editor("Name", new { htmlAttributes = new { @class = "form-control", placeholder = "Enter your name" } })
        </div>
    </div>

    <div class="row mb-3">
        <div class="col-md-3">
            @Html.Label("Age", "Age", new { @class = "form-label" })
        </div>
        <div class="col-md-9">
            @Html.Editor("Age", new { htmlAttributes = new { @class = "form-control", placeholder = "Enter your age" } })
        </div>
    </div>

    <div class="row mb-3">
        <div class="col-md-3">
            @Html.Label("Salary", "Salary", new { @class = "form-label" })
        </div>
        <div class="col-md-9">
            @Html.Editor("Salary", new { htmlAttributes = new { @class = "form-control", placeholder = "Enter your salary" } })
        </div>
    </div>

    <div class="row mb-3">
        <div class="col-md-3">
            @Html.Label("IsEmployed", "Is Employed", new { @class = "form-check-label" })
        </div>
        <div class="col-md-9 d-flex align-items-center">
            @Html.Editor("IsEmployed", new { htmlAttributes = new { @class = "form-check-input" } })
        </div>
    </div>

    <div class="row mb-3">
        <div class="col-md-3">
            @Html.Label("Skills", "Skills", new { @class = "form-label" })
        </div>
        <div class="col-md-9">
            @Html.Editor("Skills", new { htmlAttributes = new { @class = "form-control" } })
        </div>
    </div>

    <div class="row mb-3">
        <div class="col-md-3">
            @Html.Label("DateOfBirth", "Date of Birth", new { @class = "form-label" })
        </div>
        <div class="col-md-9">
            @Html.Editor("DateOfBirth", new { htmlAttributes = new { @class = "form-control", placeholder = "Enter your birth date" } })
        </div>
    </div>

    <div class="row mb-3">
        <div class="col-md-3">
            @Html.Label("Gender", "Gender", new { @class = "form-label" })
        </div>
        <div class="col-md-9">
            @Html.Editor("Gender", new { htmlAttributes = new { @class = "form-select" } })
        </div>
    </div>

    <div class="row mb-3">
        <div class="col-md-3">
            @Html.Label("ProfilePicture", "Profile Picture", new { @class = "form-label" })
        </div>
        <div class="col-md-9">
            @Html.Editor("ProfilePicture", new { htmlAttributes = new { @class = "form-control" } })
        </div>
    </div>

    <div class="row mb-3">
        <div class="col-md-3">
            @Html.Label("UserId", "User ID", new { @class = "form-label" })
        </div>
        <div class="col-md-9">
            @Html.Editor("UserId", new { htmlAttributes = new { @class = "form-control", placeholder = "Enter your User ID" } })
        </div>
    </div>

    <div class="row mb-3">
        <div class="col-md-3">
            @Html.Label("WorkingHours", "Working Hours", new { @class = "form-label" })
        </div>
        <div class="col-md-9">
            @Html.Editor("WorkingHours", new { htmlAttributes = new { @class = "form-control", placeholder = "Enter your working hours" } })
        </div>
    </div>

    <button type="submit" class="btn btn-primary">Submit</button>
</form>

Now, run the application; it will give you the following output. In the above example, we have specified the property names of the Employee model. So, the Editor HTML Helper method creates the appropriate input elements based on the datatype of Employee model properties, as shown in the image below.

Example to Understand Editor HTML Helper Method in ASP.NET Core MVC

Gender Enum Not Showing All Options

The EditorFor method doesn’t automatically render a dropdown list with all enum options. To resolve this without using DropDownListFor, we need to ensure that the editor template for the enum type is correctly applied.

Skills Rendered as Multiple Textboxes Instead of TextArea

When using EditorFor with an IEnumerable<string>, the default behavior is to render one input field for each element in the collection. To ensure a single textarea is rendered without using TextAreaFor, we can provide a custom editor template.

What are Custom Editor Templates in ASP.NET Core MVC?

Custom Editor Templates in ASP.NET Core MVC are reusable Razor views that render model properties in a custom way. Instead of rendering a form field in the default manner (e.g., a text box for strings, a checkbox for booleans, etc.), you can create custom templates to control how specific data types or properties are displayed.

These templates are stored in special folders (Views/Shared/EditorTemplates/) and are automatically used by the EditorFor HTML helper method when rendering the corresponding model properties.

Gender (Enum) Custom Editor Template:

Create a custom editor template for enum types. The location will be Views/Shared/EditorTemplates/Gender.cshtml. Once you create the Gender.cshtml view, copy and paste the following code:

@model Enum
@Html.DropDownListFor(m => m, new SelectList(Enum.GetValues(Model.GetType())), "Select Gender", new { @class = "form-select" })
Skills (List<string>) Custom Editor Template:

Create a custom editor template for IEnumerable<string> to render a single textarea. The File location will be: Views/Shared/EditorTemplates/Skills.cshtml. Once you create the Skills.cshtml view, copy and paste the following code. This custom editor template will render a textarea where the skills will be displayed as a comma-separated string. You can split the string into a list of hobbies when you submit the form.

@model List<string>
<textarea class="form-control" rows="3">@string.Join(",", Model)</textarea>

With the above changes in place, run the application, and you will see that Gender is working, but Skills are still not working. So, to resolve this issue, we need to decorate the Skill property with the UIHint attribute to indicate that a custom editor template should be applied for this property.

What is UIHint Attribute in ASP.NET Core MVC?

The UIHint attribute in ASP.NET Core MVC is used to specify which custom template should be used to render a model property in a view. It provides a way to override the default behavior of HTML helpers such as EditorFor, DisplayFor, or LabelFor. It instructs the framework to use a particular editor or display template based on the attribute’s value. So, modify the Employee.cs class file as follows:

using System.ComponentModel.DataAnnotations;

namespace HTML_HELPER.Models
{
    public class Employee
    {
        public string Name { get; set; }         // string
        public int Age { get; set; }             // int
        public decimal Salary { get; set; }      // decimal
        public bool IsEmployed { get; set; }     // bool
        public DateTime DateOfBirth { get; set; } // DateTime
        [UIHint("Skills")]
        public List<string> Skills { get; set; } // List<string>
        public Gender Gender { get; set; }       // Enum
        public IFormFile ProfilePicture { get; set; } // IFormFile
        public Guid UserId { get; set; }         // Guid
        public TimeSpan WorkingHours { get; set; } // TimeSpan
    }

    public enum Gender
    {
        Male,
        Female,
        Other
    }
}

With the above changes in place, it should display the Skills separated by a comma, as shown in the below image:

Editor HTML Helper in ASP.NET Core MVC

Example to Understand EditorFor HTML Helper Method in ASP.NET Core MVC:

EditorFor is a strongly typed method that generates an input element based on the type of the model property. Syntax: @Html.EditorFor(model => model.PropertyName)

The EditorFor HTML Helper method is strongly typed. As it is a strongly typed method, we must use a lambda expression to specify the name. Let us understand this with an example. Please modify the Index.cshtml view as shown below to use the EditorFor extension method

@model Employee

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

<form asp-action="Create" asp-controller="Employee" method="post" enctype="multipart/form-data">

    <div class="row mb-3">
        <div class="col-md-3">
            @Html.LabelFor(m => m.Name, new { @class = "form-label" })
        </div>
        <div class="col-md-9">
            @Html.EditorFor(m => m.Name, new { htmlAttributes = new { @class = "form-control", placeholder = "Enter your name" } })
        </div>
    </div>

    <div class="row mb-3">
        <div class="col-md-3">
            @Html.LabelFor(m => m.Age, new { @class = "form-label" })
        </div>
        <div class="col-md-9">
            @Html.EditorFor(m => m.Age, new { htmlAttributes = new { @class = "form-control", placeholder = "Enter your age" } })
        </div>
    </div>

    <div class="row mb-3">
        <div class="col-md-3">
            @Html.LabelFor(m => m.Salary, new { @class = "form-label" })
        </div>
        <div class="col-md-9">
            @Html.EditorFor(m => m.Salary, new { htmlAttributes = new { @class = "form-control", placeholder = "Enter your salary" } })
        </div>
    </div>

    <div class="row mb-3">
        <div class="col-md-3">
            @Html.LabelFor(m => m.IsEmployed, new { @class = "form-check-label" })
        </div>
        <div class="col-md-9 d-flex align-items-center">
            @Html.EditorFor(m => m.IsEmployed, new { htmlAttributes = new { @class = "form-check-input" } })
        </div>
    </div>

    <div class="row mb-3">
        <div class="col-md-3">
            @Html.LabelFor(m => m.Skills, new { @class = "form-label" })
        </div>
        <div class="col-md-9">
            @Html.EditorFor(m => m.Skills, new { htmlAttributes = new { @class = "form-control" } })
        </div>
    </div>

    <div class="row mb-3">
        <div class="col-md-3">
            @Html.LabelFor(m => m.DateOfBirth, new { @class = "form-label" })
        </div>
        <div class="col-md-9">
            @Html.EditorFor(m => m.DateOfBirth, new { htmlAttributes = new { @class = "form-control", placeholder = "Enter your birth date" } })
        </div>
    </div>

    <div class="row mb-3">
        <div class="col-md-3">
            @Html.LabelFor(m => m.Gender, new { @class = "form-label" })
        </div>
        <div class="col-md-9">
            @Html.EditorFor(m => m.Gender, new { htmlAttributes = new { @class = "form-select" } })
        </div>
    </div>

    <div class="row mb-3">
        <div class="col-md-3">
            @Html.LabelFor(m => m.ProfilePicture, new { @class = "form-label" })
        </div>
       <div class="col-md-9">
            @Html.EditorFor(m => m.ProfilePicture, new { htmlAttributes = new { @class = "form-control" } })
        </div>
    </div>

    <div class="row mb-3">
        <div class="col-md-3">
            @Html.LabelFor(m => m.UserId, new { @class = "form-label" })
        </div>
        <div class="col-md-9">
            @Html.EditorFor(m => m.UserId, new { htmlAttributes = new { @class = "form-control", placeholder = "Enter your User ID" } })
        </div>
    </div>

    <div class="row mb-3">
        <div class="col-md-3">
            @Html.LabelFor(m => m.WorkingHours, new { @class = "form-label" })
        </div>
        <div class="col-md-9">
            @Html.EditorFor(m => m.WorkingHours, new { htmlAttributes = new { @class = "form-control", placeholder = "Enter your working hours" } })
        </div>
    </div>

    <button type="submit" class="btn btn-primary">Submit</button>
</form>

In the above example, we specified the property name using the lambda expression. The result is the same whether you use the Editor() or the EditorFor() extension method. Now, run the application; it will give you the same output.

What are the Differences Between Editor and EditorFor in ASP.NET Core MVC?

In ASP.NET Core MVC, Editor and EditorFor HTML helper methods render form fields for model properties in a Razor view. However, they differ in how they are used and the level of control they provide.

What are the Differences Between Editor and EditorFor in ASP.NET Core MVC?

Detailed Comparison
Strongly Typed vs. Non-Strongly Typed
  • EditorFor: This is a strongly typed helper. It uses lambda expressions to refer to the model’s properties, providing compile-time type checking and IntelliSense support. If you rename a property, refactoring tools can automatically update the lambda expressions in your views.
  • Editor: This is a non-strongly typed helper. It takes the property name as a string, meaning there is no compile-time checking. This can lead to errors if the property name is mistyped or renamed, as the compiler cannot verify it.
Compile-Time Checking
  • EditorFor: Provides compile-time checking because it uses lambda expressions. If the property Name in your model is removed or renamed, the compiler will notify you of the issue.
  • Editor: Does not provide compile-time checking. If you mistype the property name or it is renamed in the model, this will not be caught until runtime, which can lead to runtime errors.
Model Binding
  • EditorFor: Automatically binds to the model property based on the expression. It is specifically designed for strongly typed views where each editor is bound to a specific property in the model.
  • Editor: You need to pass the property name as a string manually, and the binding happens based on that name. This makes it less safe compared to EditorFor.
Performance
  • EditorFor: Slightly more performant because it uses strong typing and expressions.
  • Editor: Slightly less performant because it involves string lookup and reflection.
When to Use Editor vs EditorFor
  • Use EditorFor when: You have a strongly typed model, and you want the benefits of compile-time checking, better performance, and support for refactoring tools. This is the default and preferred approach in most ASP.NET Core MVC applications.
  • Use Editor when: You need to dynamically generate form fields where the property names are not known until runtime or where you’re dealing with scenarios that do not support strong typing (e.g., handling form fields dynamically based on user input).

In the next article, I will discuss the Password Field HTML Helper in the ASP.NET Core MVC application and explain how to Use the Editor HTML Helper with Examples. I hope this article will help you with your needs.

Leave a Reply

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