Home > other >  ASPNET 6 TagHelper context not maintained when using an editor template
ASPNET 6 TagHelper context not maintained when using an editor template

Time:03-10

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  id="person" role="tabpanel" aria-labelledby="home-tab" parent-context="parent">
<div >
    <div >
        <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  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 >
    <div >
        <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.

CodePudding user response:

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  id="person" role="tabpanel" aria-labelledby="home-tab" parent-context="parent">
<div >
    <div >
        <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  id="person" role="tabpanel" aria-labelledby="home-tab" parent-context="parent">
<div >
    <div >
        <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.

  • Related