[SOLVED] ASPNET 6 TagHelper context not maintained when using an editor template

Issue

Given some parent / child TagHelper(s).

Parent

[HtmlTargetElement("div", Attributes = "parent-context")]
public class AspFormViewTagHelper : TagHelper
{
    [HtmlAttributeName("parent-context")] 
    public string? Prefix { get; set; }

    public override void Init(TagHelperContext context)
    {
        context.Items["parent-context"] = Prefix;
    }
}

Child

[HtmlTargetElement("input", Attributes = "asp-for, child-context")]
public class AspForVueTagHelper : TagHelper
{
    [HtmlAttributeName("asp-for")] public ModelExpression For { get; set; }

    [HtmlAttributeName("child-context")] public String ChildContext { get; set; }

    public override void Process(TagHelperContext context, TagHelperOutput output)
    {
        if (!context.Items.ContainsKey("parent-context"))
            return;
        var prefix = (string) context.Items["parent-context"];
        // The above is null when using an editor template?
    }
}

When rendering HTML, this works perfectly.

<div class="tab-pane fade show active" id="person" role="tabpanel" aria-labelledby="home-tab" parent-context="parent">
<div class="row mb-1px">
    <div class="col-md-9">
        <input asp-for="@Model.Person.FirstName" child-context="child" />
    </div>
</div>
</div>

However, if I render an Editor Template, then the context is lost.

<div class="tab-pane fade show active" id="person" role="tabpanel" aria-labelledby="home-tab" parent-context="parent">
    @Html.EditorFor(_ => _.Person.FirstName, "boot-text-child")
</div>

With boot-text-child.cshtml containing this….

<div class="row mb-1px">
    <div class="col-md-9">
        <input asp-for="@Model" child-context="from-editor-template" />
    </div>
</div>

The parent context is gone.
Why does the heirarchy of rendering break down when an editor template is used. Is there any way to force the rendering so that the context is maintained for an Editor Template.

The child is correctly called both times, but when the editor template is used, the context.Items is empty.

Solution

The issue might relates the scope of TagHelperContext, I checked your code on my side and set some break point in the custom tag and relate view page, it seems that when using the following code:

<div class="tab-pane fade show active" id="person" role="tabpanel" aria-labelledby="home-tab" parent-context="parent">
<div class="row mb-1px">
    <div class="col-md-9">
        <input asp-for="@Model.Person.FirstName" child-context="child" />
    </div>
</div>
</div>

The break point order is: Main page => AspFormViewTagHelperc.cs => AspForVueTagHelper.cs

But if using Editor Template and @Html.EditorFor, the order is: Main page => AspFormViewTagHelperc.cs => Editor Template page => AspForVueTagHelper.cs.

If I put the parent div into the Editor Template page, the context.Items contains the value. The Editor Template page code like this:

<div class="tab-pane fade show active" id="person" role="tabpanel" aria-labelledby="home-tab" parent-context="parent">
<div class="row mb-1px">
    <div class="col-md-9">
        <input asp-for="@Model" child-context="child" />
    </div>
</div>
</div>

In the main page, only using the Html.EditorFor, like this:

@Html.EditorFor(_ => _.Person.FirstName, "boot-text-child")

enter image description here

So, you can use this method to render the elements or directly using the tag helper instead of using @Html.EditorFor.

Answered By – Zhi Lv

Answer Checked By – Jay B. (BugsFixing Admin)

Leave a Reply

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