Use Razor View Inside Custom Tag Helpers in ASP.NET Core MVC 5

On the Visual Studio, select Create a new project from Get Started

Select ASP.NET Core Web Application

Input Project Name and select Location for new project

Select ASP.NET Core 5.0 Version and select ASP.NET Core Empty Template. Click Create button to finish

Open Startup.cs file and add new configurations as below:

using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;

namespace LearnASPNETCoreMVC5
{
    public class Startup
    {
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddControllersWithViews();
        }

        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }

            app.UseRouting();

            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllerRoute(
                    name: "default",
                    pattern: "{controller=Demo}/{action=Index}/{id?}");
            });
        }
    }
}

Create new folder named Models. In Models folder, create new entity class as below:

Create new class named Product.cs as below:

namespace LearnASPNETCoreMVC5.Models
{
    public class Product
    {
        public string Id { get; set; }
        public string Name { get; set; }
        public double Price { get; set; }
    }
}

Create new folder named TagHelpers. In this folder, create tag1 tag helper as below:

In TagHelpers folder, create new class named Tag1TagHelper.cs as below:

using Microsoft.AspNetCore.Mvc.Rendering;
using Microsoft.AspNetCore.Mvc.ViewFeatures;
using Microsoft.AspNetCore.Razor.TagHelpers;
using System.Threading.Tasks;

namespace LearnASPNETCoreMVC5.TagHelpers
{
    [HtmlTargetElement("tag1", TagStructure = TagStructure.NormalOrSelfClosing)]
    public class Tag1TagHelper : TagHelper
    {
        [ViewContext]
        [HtmlAttributeNotBound]
        public ViewContext ViewContext { get; set; }

        private IHtmlHelper _htmlHelper;

        public Tag1TagHelper(IHtmlHelper htmlHelper)
        {
            _htmlHelper = htmlHelper;
        }

        public override async Task ProcessAsync(TagHelperContext context, TagHelperOutput output)
        {
            (_htmlHelper as IViewContextAware).Contextualize(ViewContext);
            output.TagName = "";
            output.Content.SetHtmlContent(await _htmlHelper.PartialAsync("TagHelpers/Tag1/Index"));
        }
    }
}

Create new folder named Views. In Views folder, create new folder named Shared. In Shared folder, create new folder named TagHelpers. In TagHelpers folder, create new folder named Tag1. In Tag1 folder, create new Razor View named Index.cshtml as below:

<h3>Tag 1</h3>

In TagHelpers folder, create tag2 tag helper as below:

In TagHelpers folder, create new class named Tag2TagHelper.cs as below:

using Microsoft.AspNetCore.Mvc.Rendering;
using Microsoft.AspNetCore.Mvc.ViewFeatures;
using Microsoft.AspNetCore.Razor.TagHelpers;
using System.Threading.Tasks;

namespace LearnASPNETCoreMVC5.TagHelpers
{
    [HtmlTargetElement("tag2", TagStructure = TagStructure.NormalOrSelfClosing)]
    public class Tag2TagHelper : TagHelper
    {
        [ViewContext]
        [HtmlAttributeNotBound]
        public ViewContext ViewContext { get; set; }

        private IHtmlHelper _htmlHelper;

        public Tag2TagHelper(IHtmlHelper htmlHelper)
        {
            _htmlHelper = htmlHelper;
        }

        public override async Task ProcessAsync(TagHelperContext context, TagHelperOutput output)
        {
            (_htmlHelper as IViewContextAware).Contextualize(ViewContext);

            _htmlHelper.ViewBag.Age = 20;
            _htmlHelper.ViewBag.Username = "acc1";
            _htmlHelper.ViewBag.Status = true;
            _htmlHelper.ViewBag.Price = 4.5;

            output.TagName = "";
            output.Content.SetHtmlContent(await _htmlHelper.PartialAsync("TagHelpers/Tag2/Index"));
        }
    }
}

In TagHelpers folder, create new folder named Tag2. In Tag2 folder, create new Razor View named Index.cshtml as below:

<h3>Tag 2</h3>
Age: @ViewBag.Age
<br />
Username: @ViewBag.Username
<br />
Status: @ViewBag.Status
<br />
Price: @ViewBag.Price

In TagHelpers folder, create tag3 tag helper as below:

In TagHelpers folder, create new class named Tag3TagHelper.cs as below:

using LearnASPNETCoreMVC5.Models;
using Microsoft.AspNetCore.Mvc.Rendering;
using Microsoft.AspNetCore.Mvc.ViewFeatures;
using Microsoft.AspNetCore.Razor.TagHelpers;
using System.Threading.Tasks;

namespace LearnASPNETCoreMVC5.TagHelpers
{
    [HtmlTargetElement("tag3", TagStructure = TagStructure.NormalOrSelfClosing)]
    public class Tag3TagHelper : TagHelper
    {
        [ViewContext]
        [HtmlAttributeNotBound]
        public ViewContext ViewContext { get; set; }

        private IHtmlHelper _htmlHelper;

        public Tag3TagHelper(IHtmlHelper htmlHelper)
        {
            _htmlHelper = htmlHelper;
        }

        public override async Task ProcessAsync(TagHelperContext context, TagHelperOutput output)
        {
            (_htmlHelper as IViewContextAware).Contextualize(ViewContext);

            _htmlHelper.ViewBag.Product = new Product {
                Id = "p01",
                Name = "Name 1",
                Price = 4.5
            };

            output.TagName = "";
            output.Content.SetHtmlContent(await _htmlHelper.PartialAsync("TagHelpers/Tag3/Index"));
        }
    }
}

In TagHelpers folder, create new folder named Tag3. In Tag3 folder, create new Razor View named Index.cshtml as below:

<h3>Tag 3</h3>
Id: @ViewBag.Product.Id
<br />
Name: @ViewBag.Product.Name
<br />
Price: @ViewBag.Product.Price

In TagHelpers folder, create tag4 tag helper as below:

In TagHelpers folder, create new class named Tag4TagHelper.cs as below:

using LearnASPNETCoreMVC5.Models;
using Microsoft.AspNetCore.Mvc.Rendering;
using Microsoft.AspNetCore.Mvc.ViewFeatures;
using Microsoft.AspNetCore.Razor.TagHelpers;
using System.Collections.Generic;
using System.Threading.Tasks;

namespace LearnASPNETCoreMVC5.TagHelpers
{
    [HtmlTargetElement("tag4", TagStructure = TagStructure.NormalOrSelfClosing)]
    public class Tag4TagHelper : TagHelper
    {
        [ViewContext]
        [HtmlAttributeNotBound]
        public ViewContext ViewContext { get; set; }

        private IHtmlHelper _htmlHelper;

        public Tag4TagHelper(IHtmlHelper htmlHelper)
        {
            _htmlHelper = htmlHelper;
        }

        public override async Task ProcessAsync(TagHelperContext context, TagHelperOutput output)
        {
            (_htmlHelper as IViewContextAware).Contextualize(ViewContext);

            _htmlHelper.ViewBag.Products = new List<Product> {
                new Product { Id = "p01", Name = "Name 1", Price = 12 },
                new Product { Id = "p02", Name = "Name 2", Price = 5 },
                new Product { Id = "p03", Name = "Name 3", Price = 6 },
                new Product { Id = "p04", Name = "Name 4", Price = 24 }
            };

            output.TagName = "";
            output.Content.SetHtmlContent(await _htmlHelper.PartialAsync("TagHelpers/Tag4/Index"));
        }
    }
}

In TagHelpers folder, create new folder named Tag4. In Tag4 folder, create new Razor View named Index.cshtml as below:

<h3>Tag 4</h3>
<table border="1">
    <tr>
        <th>Id</th>
        <th>Name</th>
        <th>Price</th>
    </tr>
    @foreach (var product in ViewBag.Products)
    {
        <tr>
            <td>@product.Id</td>
            <td>@product.Name</td>
            <td>@product.Price</td>
        </tr>
    }
</table>

Right click current project and select Razor View Imports and click Add button to finish. In _ViewImports.cshtml file, add TagHelpers libraries as below:

@addTagHelper *, LearnASPNETCoreMVCWithRealApps

Create new folder named Controllers. In this folder, create new controller named DemoController.cs as below:

using Microsoft.AspNetCore.Mvc;

namespace LearnASPNETCoreMVC5.Controllers
{
    [Route("demo")]
    public class DemoController : Controller
    {
        [Route("")]
        [Route("index")]
        [Route("~/")]
        public IActionResult Index()
        {
            return View();
        }
    }
}

Create new folder named Views. In this folder, create new folder named Demo. Create new view named Index.cshtml as below:

<html>
<head>
    <meta name="viewport" content="width=device-width" />
    <title>Use Razor View Inside Custom Tag Helpers in ASP.NET Core MVC 5</title>
</head>
<body>

    <h3>Use Razor View Inside Custom Tag Helpers in ASP.NET Core MVC</h3>

    <tag1 />
    <br />
    <tag2 />
    <br />
    <tag3 />
    <br />
    <tag4 />

</body>
</html>

Access Index action in Demo controller with following url: http://localhost:48982/Demo/Index

Output