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
{ ... }