Home > Net >  ASP.NET Core 6, Obtaining Metadata for a custom asp-for TagHelper in the context of an EditorTemplat
ASP.NET Core 6, Obtaining Metadata for a custom asp-for TagHelper in the context of an EditorTemplat

Time:03-08

Given an editor for statement in a regular razor view in ASP.NET Core 6.

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

The model looks something like this.

public class Model 
{
    [DataMember(Name = "firstName", IsRequired = true)]
    [Required]
    [StringLength(250)]
    [DataType(DataType.Text)]
    [DisplayName("Given Name")]
    public string? FirstName { get; set; }
}

I have created a custom template. boot-text.cshtml

<div >
    <label asp-for="@Model" ></label>
    <div >
        <input asp-for="@Model" type="text" 
        <span asp-validation-for="@Model"></span>
    </div>
</div>

I have a tag helper.

[HtmlTargetElement("input", TagStructure = TagStructure.Unspecified)]
public class AspForTagHelper : TagHelper
{
    [HtmlAttributeName("asp-for")] 
    public ModelExpression For { get; set; }

    public override void Process(TagHelperContext context, TagHelperOutput output)
    {
       // For is null here
    }
}

In the above TagHelper the model is always NULL.

I looked at the source code here: https://github.com/dotnet/aspnetcore/blob/main/src/Mvc/Mvc.TagHelpers/src/InputTagHelper.cs

I copied all the source code into my own tag helper, and I also get a reference exception at For.Metadata

var metadata = For.Metadata;
var modelExplorer = For.ModelExplorer;

This begs the question, how does the default tag helper manage to get the model metadata. The above asp-for renders just fine using my template if I just remove my tag helper altogether.

So the source code I found is perhaps not the real ASPNET Core 6 source code?

CodePudding user response:

Your tag helper will be run based on the content of your [HtmlTargetElement] attribute.

When your tag helper is run, your properties will be bound based on any [HtmlAttributeName]. But this binding is optional and will not prevent your tag helper from running.

Since you have only specified [HtmlTargetElement("input" and haven't included any required Attributes = , your tag helper will be run against all <input tags even if they have no asp-for attribute. Which explains why you are seeing that your For property is always null.

TLDR: what you need is;

[HtmlTargetElement("input", Attributes = "asp-for", TagStructure = TagStructure.Unspecified)]
public class AspForTagHelper : TagHelper
{ ... }
  • Related