Reputation: 31
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
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.
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
Upvotes: 1