| by Achyut Kendre | No comments

How to create custom tag helper in ASP.NET Core?

ASP.NET Core
ASP.NET Core Tutorial

Example Code: https://drive.google.com/file/d/19iWlBIz9e_eE4Vv1tdamdNDmYFR-yK9s/view?usp=sharing

The tag helper enables us to run the server-side code to generate HTML, CSS, Javascript code in Razor View. In my previous article, I have talked about tag helper, form tag helper, and other common tag helpers. In this article, I will explain how to create custom tag helper in ASP.NET Core MVC.

Using the tag helper, we can extend our existing HTML elements or create our own custom HTML elements. The custom tag helper is nothing but the class that implements the ITagHelper interface. However, .NET Core MVC provides us the implementation of this interface.

To create custom tag helper, the first step is to create a class that inherits from “TagHelper” class. This class has a virtual method to generate HTML tags. It contains both synchronous (Process) and asynchronous (ProcessAsync) implementation of the virtual method.

public virtual Task ProcessAsync(TagHelperContext context, TagHelperOutput output);
public virtual void Process(TagHelperContext context, TagHelperOutput output);

We can implement either one of these two or both, based on our requirement. The Process method (or ProcessAsync) is responsible to generate the HTML that is rendered by the browser. It receives context of tag helper instance and TegHelperOuter which we can be used to read and change the content of our tag helper that is within scope.

§We can implement either one of these two or both, based on our requirement. The Process method (or ProcessAsync) is responsible to generate the HTML that is rendered by the browser.

We can implement either one of these two or both, based on our requirement. The Process method (or ProcessAsync) is responsible to generate the HTML that is rendered by the browser.

These methods has two parameters first is TagHelperContext which will get you access to httpcotext and second is TagHelperOutput help you configure the values in output tag.

ASP.NET Core also provides you one more attribute HtmlTargetElement attribute which allow you to pass the tag helper name as parameter that will be used in view.

Now let us implement simple tag helper as follows –

namespace CTagHelpersEX.CustomHelpers
{
    [HtmlTargetElement("DemoTag")]
    public class MyDemoTag:TagHelper
    {
        public string Name { get; set; }
        public override void Process(TagHelperContext context, TagHelperOutput output)
        {
            output.TagName = "MyTag";
            output.TagMode = TagMode.StartTagAndEndTag;
            output.Attributes.Add("width", "100px");
            string str = "<span> Hi !" + Name +"</span>";
            string strb = "<b> Hi !" + Name + "</b>";

            output.PreContent.SetHtmlContent(str);
            output.PostContent.SetHtmlContent(strb);
        }
    }
}

You can add the reference of that tag helper in _ViewImports file so that it will be available globally to all view.

_ViewImports.cshtml
@addTagHelper *, CTagHelpersEX

Now you can use it –

<DemoTag name="Sunil"></DemoTag>

Passing a model Data to a Tag Helper

We can also pass the model data to the tag helper via model binding by creating properties of type “ModelExpression”.
Using HtmlAttributeName attribute, we can create a friendly attribute name. The ModelExpression describes a model expression passed to the tag helper. Using Model property of this class, we can get model object for the expression of interest.

[HtmlAttributeName("for-name")]  
public ModelExpression EmployeeName { get; set; }  
 [HtmlAttributeName("for-designation")]  
public ModelExpression Designation { get; set; } 

Once you create these properties here you can access those properties in process method as follows –

string str = "<h4>Hi!" + EmpName.Model + " with designation " + Designation.Model + " </h4>";
     

Complete code for tag helper class is –

[HtmlTargetElement("EmpDet")]
public class EmpDetailsTagHelper:TagHelper
{
 [HtmlAttributeName("for-name")]
 public ModelExpression EmpName { get; set; }
 [HtmlAttributeName("for-designation")]
 public ModelExpression Designation { get; set; }
 public override void Process(TagHelperContext context,  TagHelperOutput output)
   {
       output.TagName = "EDet";
       output.TagMode = TagMode.StartTagAndEndTag;
       string str = "<h4>Hi!" + EmpName.Model + " with designation " + Designation.Model + " </h4>";
       output.PreContent.SetHtmlContent(str);
       }
    }

Then you can use this in a view as follows –

@model Emp 
@{
    Layout = null;
}

<!DOCTYPE html>

<html>
<head>
    <meta name="viewport" content="width=device-width" />
    <title>Index</title>
</head>
<body>
     <h1> Index action of home</h1>
     <DemoTag name="Gaensh" sclass="ASPNETCore"></DemoTag> <br />
     <EmpDet for-name="EmpName" for-designation="Designation"></EmpDet>
</body>
</html>