AeroYoung
AeroYoung

Reputation: 31

NetCore InputTagHelper using reflection

I have a model with lots of properties. Creating or updating theirs views is a troublesome work.

So i trying to use Reflection to create view during runtime: (PS: yes, i know the front-end is very import, i should use Vue or other frame to create views at designtime. But I just want to try buildering forms at runtime, yes i am a freak. LOL)

There is my code:

@{
    var dic = Model.GetAttributePropsByCategory();// get PropertyInfo by CategoryAttribute and custom DisplayIndexAttribute
}
@foreach (var items in dic)
{
    var category = items.Key; //  InfoCategoryAttribute
    foreach (var tuple in items.Value)
    {
        var displayIndex = tuple.Item1; // Custom: DisplayIndexAttribute
        var prop = tuple.Item2; // PropertyInfo

        <input asp-for="@prop.Name" class="form-control"/>
    }
}

My target is:

<input class="form-control valid" type="text" data-val="true" data-val-required="The VIN field is required." id="VIN" name="VIN" value="VIN001" aria-describedby="VIN-error" aria-invalid="false">

But the result like this:

<input class="form-control valid" type="text" data-val="true" data-val-required="The Name field is required." id="prop_Name" name="prop.Name" aria-describedby="prop_Name-error" aria-invalid="false">

So, I read the source code in the aspnetcore.mvc.taghelpers. I found the key is InputTagHelper.For:

public class InputTagHelper : TagHelper
{
    ...

    [HtmlAttributeName(ForAttributeName)]
    public ModelExpression For { get; set; }

    ...
}

But I can't understand how the InputTagHelper.For was created. Therefor, i dont know how to override it to achieve my target.

Is there any Suggestions? Thx.

Upvotes: 1

Views: 311

Answers (1)

Fei Han
Fei Han

Reputation: 27793

In source code of InputTagHelper, we can find following code snippet will help generate textbox input and the third parameter For.Name would be used to set value(s) of textbox id and name attribute.

return Generator.GenerateTextBox(
    ViewContext,
    modelExplorer,
    For.Name,
    modelExplorer.Model,
    format,
    htmlAttributes);

And if we debug the source code, we will find the value of For look like below.

enter image description here

To achieve your expected result, you can customize it and pass For.Model.ToString() to GenerateTextBox method rather than For.Name, like below.

return Generator.GenerateTextBox(
    ViewContext,
    modelExplorer,
    //For.Name,
    For.Model.ToString(),
    modelExplorer.Model,
    format,
    htmlAttributes);

Test Result

enter image description here

Upvotes: 1

Related Questions