I figure it out after reading multiple different articles which had part of the answer.
So first you need to have inject in the constructor of the tag helper IHtmlGenerator
, which will generate the tag helper html, also generation of the elements requires ViewContext, which you can have only have as a property with Attribute
ViewContext
.
This is the summary of ViewContext
attribute:
Summary:
Specifies that a tag helper property should be set with the current Microsoft.AspNetCore.Mvc.Rendering.ViewContext
when creating the tag helper. The property must have a public set method.
The code look likes this:
[HtmlTargetElement("form-control-text-box")]
public class FormControlTextBoxHelper:TagHelper
{
[HtmlAttributeName("asp-for")]
public ModelExpression For { get; set; }
private readonly IHtmlGenerator _generator;
[ViewContext]
public ViewContext ViewContext { get; set; }
public FormControlTextBoxHelper(IHtmlGenerator generator)
{
_generator = generator;
}
public override void Process(TagHelperContext context, TagHelperOutput output)
{
using (var writer = new StringWriter())
{
writer.Write(@"<div class=""form-group"">");
var label = _generator.GenerateLabel(
ViewContext,
For.ModelExplorer,
For.Name, null,
new { @class = "control-label" });
label.WriteTo(writer, NullHtmlEncoder.Default);
var textArea = _generator.GenerateTextBox(ViewContext,
For.ModelExplorer,
For.Name,
For.Model,
null,
new { @class = "form-control" });
textArea.WriteTo(writer, NullHtmlEncoder.Default);
var validationMsg = _generator.GenerateValidationMessage(
ViewContext,
For.ModelExplorer,
For.Name,
null,
ViewContext.ValidationMessageElement,
new { @class = "text-danger" });
validationMsg.WriteTo(writer, NullHtmlEncoder.Default);
writer.Write(@"</div>");
output.Content.SetHtmlContent(writer.ToString());
}
}
}
So this tag helper called like <form-control-text-box asp-for="InputModel.Title"></form-control-text-box>
will produce the html which is equal to:
<div class="form-group">
<label asp-for="InputModel.Title" class="control-label"></label>
<input asp-for="InputModel.Title" class="form-control" />
<span asp-validation-for="InputModel.Title" class="text-danger"></span>
</div>
I hope I help someone to figure it out faster.