Custom HTML Helper in ASP.NET Core MVC 

Custom HTML Helper in the ASP.NET Core MVC

In this article, I will discuss How We Create Custom HTML Helpers in ASP.NET Core MVC Applications with Examples. Please read our previous article discussing Hidden Field HTML Helper in ASP.NET Core MVC. As part of this article, we will discuss the following two important pointers.

  1. How can we Display Images in an ASP.NET Core MVC Application?
  2. How do we Create Custom HTML Helpers in ASP.NET Core MVC to Display Images?

The ASP.NET Core MVC Framework provides many built-in HTML helper methods that we can directly use in a Razor View. It also allows the creation of a Custom HTML Helper Method. Once you create the custom HTML helper method, you can reuse it many times in your application.

Example to Understand Custom HTML Helpers in ASP.NET Core MVC:

To create a custom HTML Helper in ASP.NET Core MVC, we need to understand that HTML Helpers generate HTML markup programmatically within Razor views. Custom HTML Helpers allow us to encapsulate reusable pieces of HTML and logic. Let’s look at an example to understand how to Create a Custom HTML helper in an ASP.NET Core MVC Application. We will create one page to display the employee details, as shown in the image below. As you can see, along with the Employee ID, Name, Designation, and Department, we also display the Employee Photo.

Example to Understand Custom HTML Helpers in ASP.NET Core MVC

Creating Employee Model:

First, create a class file named Employee.cs within the Models Folder and copy and paste the following code. Here, we have created the Employee model to hold the required data.

namespace HTML_HELPER.Models
{
    public partial class Employee
    {
        public int Id { get; set; }
        public string? FullName { get; set; }
        public string? Designation { get; set; }
        public string? Department { get; set; }
        public string? Photo { get; set; }
        public string? AlternateText { get; set; }
    }
}
Creating Images Folder within the wwwroot Folder:

Next, add a folder with the Name Images within the wwwroot Folder where we will store the Employee photos. To do so, Right-click on the wwwroot, select Add Folder, and then rename the folder as Images. Then download and add the following image to the Images Folder. Rename the image name as MyPhoto.png.

Creating Images Folder within the wwwroot Folder

Modifying Home Controller:

Next, modify the Home Controller as follows. Here, we have created one action method. We initialize the Employee object with some hardcoded data within the action method. We also set the Photo properties to the Path of the Photo, i.e., /Images/MyPhoto.png.

using HTML_HELPER.Models;
using Microsoft.AspNetCore.Mvc;
namespace HTML_HELPER.Controllers
{
    public class HomeController : Controller
    {
        public ActionResult Index()
        {
            //Here we are hardcoded the Employee Details
            //In Realtime you will get the data from any data source
            Employee employee = new Employee()
            {
                Id = 106724,
                FullName = "Pranaya Rout",
                Designation = "Manager",
                Department = "IT",
                Photo = "/Images/MyPhoto.png",
                AlternateText = "Pranaya Rout Photo Not Available"
            };
            return View(employee);
        }
    }
}
Modifying Index.cshtml View of Home Controller:

Next, open the Index.cshtml view file and then copy and paste the following code into it.

@model HTML_HELPER.Models.Employee
@{
    ViewBag.Title = "Employee Details";
}

<div class="container mt-5">
    <div class="row justify-content-center">
        <div class="col-lg-6">
            <div class="card shadow-sm">
                <div class="card-header bg-primary text-white text-center">
                    <h4 class="mb-0">Employee Details</h4>
                </div>
                <div class="card-body">
                    <div class="row mb-3">
                        <label class="col-4"><strong>Employee ID:</strong></label>
                        <div class="col-8">
                            <p class="form-control-plaintext mb-0">@Html.DisplayFor(model => model.Id)</p>
                        </div>
                    </div>
                    <div class="row mb-3">
                        <label class="col-4"><strong>Full Name:</strong></label>
                        <div class="col-8">
                            <p class="form-control-plaintext mb-0">@Html.DisplayFor(model => model.FullName)</p>
                        </div>
                    </div>
                    <div class="row mb-3">
                        <label class="col-4"><strong>Designation:</strong></label>
                        <div class="col-8">
                            <p class="form-control-plaintext mb-0">@Html.DisplayFor(model => model.Designation)</p>
                        </div>
                    </div>
                    <div class="row mb-3">
                        <label class="col-4"><strong>Department:</strong></label>
                        <div class="col-8">
                            <p class="form-control-plaintext mb-0">@Html.DisplayFor(model => model.Department)</p>
                        </div>
                    </div>
                    <div class="row mb-3">
                        <label class="col-4"><strong>Photo:</strong></label>
                        <div class="col-8">
                            <p class="form-control-plaintext mb-0">@Html.DisplayFor(model => model.Photo)</p>
                        </div>
                    </div>
                    <div class="row mb-3">
                        <label class="col-4"><strong>Alternate Text:</strong></label>
                        <div class="col-8">
                            <p class="form-control-plaintext mb-0">@Html.DisplayFor(model => model.AlternateText)</p>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </div>
</div>

Now, Run the application and navigate to the URL Home/Index. It will produce the following output. Notice that the Photo and AlternateText property values are displayed instead of rendering the photo.

How We Create Custom HTML Helpers in ASP.NET Core MVC

To display the Image, modify the Index.cshtml file as follows:

@model HTML_HELPER.Models.Employee
@{
    ViewBag.Title = "Employee Details";
}

<div class="container mt-5">
    <div class="row justify-content-center">
        <div class="col-lg-6">
            <div class="card shadow-sm">
                <div class="card-header bg-primary text-white text-center">
                    <h4 class="mb-0">Employee Details</h4>
                </div>
                <div class="card-body">
                    <div class="row mb-3">
                        <label class="col-4"><strong>Employee ID:</strong></label>
                        <div class="col-8">
                            <p class="form-control-plaintext mb-0">@Html.DisplayFor(model => model.Id)</p>
                        </div>
                    </div>
                    <div class="row mb-3">
                        <label class="col-4"><strong>Full Name:</strong></label>
                        <div class="col-8">
                            <p class="form-control-plaintext mb-0">@Html.DisplayFor(model => model.FullName)</p>
                        </div>
                    </div>
                    <div class="row mb-3">
                        <label class="col-4"><strong>Designation:</strong></label>
                        <div class="col-8">
                            <p class="form-control-plaintext mb-0">@Html.DisplayFor(model => model.Designation)</p>
                        </div>
                    </div>
                    <div class="row mb-3">
                        <label class="col-4"><strong>Department:</strong></label>
                        <div class="col-8">
                            <p class="form-control-plaintext mb-0">@Html.DisplayFor(model => model.Department)</p>
                        </div>
                    </div>
                    <div class="row mb-3">
                        <label class="col-4"><strong>Photo:</strong></label>
                        <div class="col-8">
                            <img src="@Model.Photo" alt="@Model.AlternateText" class="img-thumbnail" style="width: 150px; height: 150px;" />
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </div>
</div>

Notice that here we are using img HTML tag. Now, run the application and notice that the image is displayed as expected, as shown below.

How to Create a Custom Image HTML Helper in ASP.NET Core MVC Application with Examples

We use the code below to render Images in the ASP.NET MVC application. We are building the image tag by passing the values for the src and alt attributes.

<img src=”@Model.Photo” alt=”@Model.AlternateText” class=”img-thumbnail” style=”width: 150px; height: 150px;” />

Though the above code is not very complex, moving this logic into its own helper method still makes sense. We don’t want any complicated logic in our views; views should be as simple as possible. Don’t you think it would be very nice if we could render the image using the Image() HTML helper method, as shown below?

@Html.Image(Model.Photo, Model.AlternateText, new {@class=”img-thumbnail” style=”width: 150px; height: 150px;”})

But, ASP.NET Core MVC does not provide any built-in Image() HTML helper. So, let’s build our own custom image HTML helper method.

How to Create Custom HTML Helper in ASP.NET Core MVC

To create a custom HTML helper in ASP.NET Core MVC, we need to follow the below steps:

  • Create a Helper Class: Create a static class containing the custom HTML helper methods.
  • Create Extension Methods: Define extension methods within the helper class. The method should extend the IHtmlHelper interface or any derived interface. That means the first parameter must be this IHtmlHelper.
  • Implement Helper Methods: Write the logic for the custom HTML helper method within the extension method. The extension method should generate HTML markup based on the provided parameters.
Creating Custom Image Tag Helper:

Let us proceed and understand How We Can Create a Custom Image HTML Helper Method in ASP.NET Core MVC. So, create a static class to hold our custom HTML Helper. This helper will generate an image tag by accepting parameters for the src, alt, and additional HTML attributes (like class and style). Create a class file with the name CustomHTMLHelper.cs (you can give any name) within the Models folder (You can create it inside any folder or directory) and then copy and paste the following code into it. The following code is self-explained, so please read the comment lines for a better understanding.

using Microsoft.AspNetCore.Html; 
using Microsoft.AspNetCore.Mvc.Rendering; 
using Microsoft.AspNetCore.Mvc.ViewFeatures; 

namespace HTML_HELPER.Models
{
    // Declares a static class named CustomHTMLHelper.
    // Static classes cannot be instantiated and are typically used for utility or helper methods.
    public static class CustomHTMLHelper 
    {
        // Extension method for IHtmlHelper.
        // This method adds an 'Image' helper to generate an <img> tag.
        public static IHtmlContent Image(this IHtmlHelper htmlHelper, string src, string alt, object? htmlAttributes = null)
        {
            // Creates a new <img> tag using the TagBuilder class, which helps in generating well-formed HTML tags.
            var imgTag = new TagBuilder("img");

            // Adds the 'src' attribute to the <img> tag with the value passed in the 'src' parameter.
            imgTag.Attributes.Add("src", src);

            // Adds the 'alt' attribute to the <img> tag with the value passed in the 'alt' parameter.
            imgTag.Attributes.Add("alt", alt);

            // Checks if there are any additional HTML attributes (such as class, style, etc.) passed in the 'htmlAttributes' parameter.
            if (htmlAttributes != null)
            {
                // Converts the anonymous object 'htmlAttributes' into a dictionary of key-value pairs that represent HTML attributes.
                var attributes = HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes);

                // Merges the additional HTML attributes into the <img> tag.
                // Existing attributes (like 'src' and 'alt') are not overwritten.
                imgTag.MergeAttributes(attributes);
            }

            // Returns the generated <img> tag as an IHtmlContent object, which can be rendered directly in Razor views.
            return imgTag;
        }
    }
}
Code Explanation:
  • IHtmlHelper: This interface provides methods for rendering HTML elements in Razor views. The extension method (Image) extends its functionality by adding a custom method to render an <img> tag.
  • Image() Method: This is an extension method for IHtmlHelper that accepts parameters for src, alt, and an optional htmlAttributes parameter to render an <img> tag.
  • TagBuilder: This class generates HTML elements programmatically. It ensures that the HTML is well-formed and that attributes are correctly added.
  • AnonymousObjectToHtmlAttributes: This method converts an anonymous object (e.g., new { @class = “img-thumbnail” }) into a dictionary of attributes (e.g., class=”img-thumbnail”). This makes it easy to pass HTML attributes without manually building the dictionary.
Use the Custom HTML Helper:

Now that we have created our custom helper method, we can use it in your view. So, modify the Index.cshtml file as shown below. In the below example, the Custom Image HTML Helper method generates an <img> tag with the specified src, alt, and optional HTML attributes.

@model HTML_HELPER.Models.Employee
@{
    ViewBag.Title = "Employee Details";
}

<div class="container mt-5">
    <div class="row justify-content-center">
        <div class="col-lg-6">
            <div class="card shadow-sm">
                <div class="card-header bg-primary text-white text-center">
                    <h4 class="mb-0">Employee Details</h4>
                </div>
                <div class="card-body">
                    <div class="row mb-3">
                        <label class="col-4"><strong>Employee ID:</strong></label>
                        <div class="col-8">
                            <p class="form-control-plaintext mb-0">@Html.DisplayFor(model => model.Id)</p>
                        </div>
                    </div>
                    <div class="row mb-3">
                        <label class="col-4"><strong>Full Name:</strong></label>
                        <div class="col-8">
                            <p class="form-control-plaintext mb-0">@Html.DisplayFor(model => model.FullName)</p>
                        </div>
                    </div>
                    <div class="row mb-3">
                        <label class="col-4"><strong>Designation:</strong></label>
                        <div class="col-8">
                            <p class="form-control-plaintext mb-0">@Html.DisplayFor(model => model.Designation)</p>
                        </div>
                    </div>
                    <div class="row mb-3">
                        <label class="col-4"><strong>Department:</strong></label>
                        <div class="col-8">
                            <p class="form-control-plaintext mb-0">@Html.DisplayFor(model => model.Department)</p>
                        </div>
                    </div>
                    <div class="row mb-3">
                        <label class="col-4"><strong>Photo:</strong></label>
                        <div class="col-8">
                            @Html.Image(Model.Photo, Model.AlternateText, new { @class = "img-thumbnail", style = "width: 150px; height: 150px;" })                         
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </div>
</div>

Now, with the above changes in place, run the application, and you will get the output as expected, as shown in the image below.

How to Create Custom HTML Helper in ASP.NET Core MVC

So, Custom HTML Helpers provide a convenient way to encapsulate complex HTML generation logic, making views cleaner and more maintainable. They can be especially useful when generating custom HTML elements that require specific attributes or behaviors.

Another Way to Create Custom HTML Helper Method:

Now, instead of creating the Image method as an extension method, we can also create this as a non-extension method and use it inside our views. For example, modify the CustomHTMLHelper class as follows:

using Microsoft.AspNetCore.Html; 
using Microsoft.AspNetCore.Mvc.Rendering; 
using Microsoft.AspNetCore.Mvc.ViewFeatures;

namespace HTML_HELPER.Models 
{
    // Defines a static class called CustomHTMLHelper. 
    // Static classes are typically used for helper methods and cannot be instantiated.
    public static class CustomHTMLHelper
    {
        // Defines a static method named Image that returns IHtmlContent (used for rendering HTML content in Razor views).
        // This method accepts 'src' (image source URL), 'alt' (alternative text), and optional HTML attributes.
        public static IHtmlContent Image(string src, string alt, object? htmlAttributes = null)
        {
            // Creates a new <img> tag using the TagBuilder class, which helps in generating well-formed HTML tags.
            var imgTag = new TagBuilder("img");

            // Adds the 'src' attribute to the <img> tag, setting it to the value passed by the 'src' parameter.
            imgTag.Attributes.Add("src", src);

            // Adds the 'alt' attribute to the <img> tag, setting it to the value passed by the 'alt' parameter.
            imgTag.Attributes.Add("alt", alt);

            // Checks if the 'htmlAttributes' parameter is not null.
            // This parameter contains additional HTML attributes such as class, style, etc.
            if (htmlAttributes != null)
            {
                // Converts the anonymous object 'htmlAttributes' into a dictionary of key-value pairs.
                // These key-value pairs represent HTML attributes and their values (e.g., class, style, id).
                var attributes = HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes);

                // Merges the additional HTML attributes (if any) into the <img> tag.
                // If the <img> tag already has attributes, they are preserved and not overwritten.
                imgTag.MergeAttributes(attributes);
            }

            // Returns the constructed <img> tag as an IHtmlContent object, 
            // which can be rendered directly in Razor views to display the image.
            return imgTag;
        }
    }
} 

Now, the above Image method is not an extension method, and hence, we cannot invoke it using the @Html property. Instead, we can call it using the class name, i.e., CustomHTMLHelper. So, modify the Index.cshtml file as follows.

@model HTML_HELPER.Models.Employee
@{
    ViewBag.Title = "Employee Details";
}

<div class="container mt-5">
    <div class="row justify-content-center">
        <div class="col-lg-6">
            <div class="card shadow-sm">
                <div class="card-header bg-primary text-white text-center">
                    <h4 class="mb-0">Employee Details</h4>
                </div>
                <div class="card-body">
                    <div class="row mb-3">
                        <label class="col-4"><strong>Employee ID:</strong></label>
                        <div class="col-8">
                            <p class="form-control-plaintext mb-0">@Html.DisplayFor(model => model.Id)</p>
                        </div>
                    </div>
                    <div class="row mb-3">
                        <label class="col-4"><strong>Full Name:</strong></label>
                        <div class="col-8">
                            <p class="form-control-plaintext mb-0">@Html.DisplayFor(model => model.FullName)</p>
                        </div>
                    </div>
                    <div class="row mb-3">
                        <label class="col-4"><strong>Designation:</strong></label>
                        <div class="col-8">
                            <p class="form-control-plaintext mb-0">@Html.DisplayFor(model => model.Designation)</p>
                        </div>
                    </div>
                    <div class="row mb-3">
                        <label class="col-4"><strong>Department:</strong></label>
                        <div class="col-8">
                            <p class="form-control-plaintext mb-0">@Html.DisplayFor(model => model.Department)</p>
                        </div>
                    </div>
                    <div class="row mb-3">
                        <label class="col-4"><strong>Photo:</strong></label>
                        <div class="col-8">
                            @CustomHTMLHelper.Image(Model.Photo, Model.AlternateText, new { @class = "img-thumbnail", style = "width: 150px; height: 150px;" })
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </div>
</div>

Now, run the application, and you should get the same output.

When Should We Use Custom HTML Helper in ASP.NET Core MVC?

Custom HTML Helpers in ASP.NET Core MVC should be used when:

  • Reusability of Common HTML Code: If you repeatedly write the same HTML and logic across multiple views (e.g., rendering images, buttons, or other complex UI components), custom HTML helpers can encapsulate that logic and HTML into a reusable method. This ensures consistency and reduces code duplication.
  • Simplifying Views: Views should focus on presentation, not logic. Moving complex logic or repetitive code into custom HTML helpers keeps the views clean and more readable.
  • Consistency Across Views: Custom HTML helpers ensure that certain elements (e.g., buttons, inputs, image tags) are rendered consistently across the application. Any changes to the helper reflect across all views that use it, ensuring consistency in the UI.
  • Separation of Concerns: By moving code that isn’t purely for presentation out of views and into helpers, you are following the separation of concerns principle. Helpers deal with HTML generation, while views deal with the display, making both easier to maintain and test.

In the next article, I will discuss Real-Time Examples of Custom HTML Helpers in ASP.NET Core MVC Applications. In this article, I explain how to Create a Custom Image HTML Helper in an ASP.NET Core MVC Application with Examples. I hope this article on creating a custom image HTML helper in ASP.NET Core MVC will help you with your needs.

Leave a Reply

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