In a recent asp.net core project, I needed to create a somewhat complex list editor widget and I decided to encapsulate it in a tag helper.

Since it would be painful to build the widget's content using interpolated strings under the tag helper's `Process` method, I started searching for a way to render a cshtml template similar to what `@Html.Partial` providers but usable inside the `Process` method.

After doing some googling in vain, I posted an [issue on the asp.net core Mvc project](https://github.com/aspnet/Mvc/issues/5504) to suggest adding a mechanism for rendering cshtml templates from tag helpers. [frankabbruzzese](https://github.com/frankabbruzzese) pointed out then in the discussion that it was possible to get a working `IHtmlHelper` inside a custom tag helper and to use its `IHtmlHelper.Partial` method.

In this post we are going to see how to:

- get and properly initialize an `Htmlhelper` in a custom tag helper
- pass data to the cshtml template

As usual the full project code is [available on Github](https://github.com/MissaouiChedy/UsingCshtmlTemplatesInTagHelpers). But first off let's discuss why you should not do this.

## Razor view components

When I was building the list editor widget I was not aware of the new [Razor View Component](https://docs.microsoft.com/en-us/aspnet/core/mvc/views/view-components) mechanism , which basically allows to render a partial template, to pass it data and to do some processing before the actual rendering.

**It seems that using View Components is a cleaner approach** as we are going to see in an [upcoming post](https://blog.techdominator.com/article/render-partials-with-asp.net-core-view-components.html).

But still one might need to use an `HtmlHelper` inside a tag helper maybe for some reason I am not anticipating. That's why I want to share what I learned.

## Getting an IHtmlHelper through Dependency Injection and properly initializing it

By using the [dependency injection mechanism](https://docs.microsoft.com/en-us/aspnet/core/fundamentals/dependency-injection) in asp.net core it is possible to get an `IHtmlHelper` instance, the only catch is that the provided instance is not ready for use; it needs to be contextualized i.e. to be set with the [`ViewContext`](https://docs.microsoft.com/en-us/aspnet/core/api/microsoft.aspnetcore.mvc.rendering.viewcontext#Microsoft_AspNetCore_Mvc_Rendering_ViewContext) object of the view in which the tag helper is rendered.

This is achieved by the `(htmlHelper as IViewContextAware).Contextualize(ViewContext);` statement which needs the current `ViewContext` instance.

<script src="https://gist.github.com/MissaouiChedy/e5991c20ced340656347553e11d5d4e9.js"></script>

In the previous example the TagHelper constructor will be used by the dependency injection context to provide an `IHtmlHelper` instance and the `ViewContext` property slapped with the `[ViewContext]` attribute will be populated by the current ViewContext. Notice how the html helper is contextualized at the start of the `ProcessAsync` method.

The `HtmlHelper` is then used to render a cshtml view (`~/Views/Shared/Template.cshtml` in the example), by calling the `HtmlHelper.Partial` method.

## Passing data to the view

Passing data to the razor view is similar to passing data to the [`Controller.View`](vc.controller#Microsoft_AspNetCore_Mvc_Controller_View_System_String_System_Object_) method, you have basically 3 ways:

- passing a model object to a strongly typed view
- populating the `ViewData` dictionary
- populating the `ViewBag` expando object

Under the tag helper `ProcessAsync` method it is possible to use the `ViewData` and `ViewBag` properties contained in the `HtmlHelper` instance.

<script src="https://gist.github.com/MissaouiChedy/f3ad7e27db8b79fe59fa38e90393e718.js"></script>

Notice how the model has been passed explicitly and how the `ViewData` and its expando object facade the `ViewBag` are passed implicitly. The data is then accessed in the rendered razor partial template as in the following example:

<script src="https://gist.github.com/MissaouiChedy/e5d8b21f4a755e368118180072ea180b.js"></script>
### Creating a new ViewData dictionary instance

One last thing: While creating the list editor widget, I had to actually create a new instance of the `ViewData` dictionary instead of using the one in the `HtmlHelper` instance. I will skip the details of the issue I encountered in the interest of brievety.

In asp.net core the most convenient constructor that allows to create an instance "from scratch" in the [`ViewDataDictionary`](https://docs.microsoft.com/en-us/aspnet/core/api/microsoft.aspnetcore.mvc.viewfeatures.viewdatadictionary) class has the following signature: `ViewDataDictionary(IModelMetadataProvider metadataProvider, ModelStateDictionary modelState)`.

The required `IModelMetadataProvider` instance can be requested through dependency injection and the `ModelStateDictionary` can be instantiated by using its parameterless constrcutor.

<script src="https://gist.github.com/MissaouiChedy/77407619e42f787f8ff057c74560d712.js"></script>