I am trying to bind custom form fields to an existing ViewModel. I have a ViewModel that looks similar to this
public class BasicProfileViewModel {
public Employee Employee { get; set; }
}
I am loading my form using the above but what i also have is an CustomFormFieldComponent
which add custom form fields
Which is based of some of the values in the Employee model
@await Component.InvokeAsync("CustomFormFields", new { Model.Level, Model.Employee.CompanyId, Model.Employee.EmployeeId })
The component is really simple just return an list that i retrieve from the DB
@model List<CustomFormField>
@for (int i = 0; i < Model.Count(); i++)
{
<div class="row">
<div class="form-group form-material col-md-6">
@Html.LabelForModel(Model[i].FieldLabel, new { @class = "form-control-label" })
@if (Model[i].IsMandatory)
{
<span>*</span>
}
@if (Model[i].DropdownValues.Any())
{
var values = new SelectList(Model[i].DropdownValues);
<select asp-items="@values" class="form-control"></select>
}
else
{
@Html.TextBoxFor(m => Model[i].FieldValue, new { @class = "form-control" })
}
</div>
</div>
}
How can i get those custom form fields part of my ViewModel?
I am thinking of doing an custom model binder, Employee is an complex object so setting the values using reflection is not as straight forward. And i have not even started with the custom form fields.
public class RequestBasicProfile
{
public Employee Employee { get; set; } = new Employee();
public List<CustomFormField> FormFields { get; set; }
}
public class RequestBasicProfileBinder : IModelBinder
{
public Task BindModelAsync(ModelBindingContext bindingContext)
{
if (bindingContext == null)
{
throw new ArgumentNullException(nameof(bindingContext));
}
var result = new RequestBasicProfile();
foreach (var item in bindingContext.HttpContext.Request.Form)
{
var propertyInfo = result.Employee.GetType().GetProperty(item.Key.Replace("Employee.", ""));
if (propertyInfo != null)
{
var value = item.Value[0];
propertyInfo.SetValue(result.Employee, Convert.ChangeType(value, propertyInfo.PropertyType), null);
}
}
bindingContext.Result = ModelBindingResult.Success(result);
return Task.CompletedTask;
}
}