I have the following Model
public class MyModel
{
public string Name {get;set;}
public int? Age {get;set;}
public string City {get;set;}
public decimal? Salary {get;set;}
public JObject ExtraFields {get;set;}
}
I am trying to implement Custom Model Binder. If the submitted form has key
that matches with the Model's propery then set model's property value else add the key and value to ExtraFields
.
Note that ExtraFields
is JObject
public class MyModelBinder: IModelBinder
{
public Task BindModelAsync(ModelBindingContext bindingContext)
{
if (bindingContext == null)
{
throw new ArgumentNullException(nameof(bindingContext));
}
MyModel model = new MyModel()
{
ExtraFields = new JObject()
};
var form = bindingContext.HttpContext.Request.Form;
var properties = typeof(MyModel).GetProperties();
foreach (var key in form.Keys)
{
var p = properties.FirstOrDefault(x => x.Name == key);
var val = form[key];
if (p != null)
{
p.SetValue(model, val); // throws exception
}
else
{
var v = StringValues.IsNullOrEmpty(val) ? null : val.ToString();
model.ExtraFields.Add(key, v);
}
}
bindingContext.Model = model;
bindingContext.Result = ModelBindingResult.Success(model);
return Task.CompletedTask;
}
}
Issue
I am getting exception while setting the value of the model
Object of type 'Microsoft.Extensions.Primitives.StringValues' cannot be converted to type 'System.String
If possible, i would like to avoid checking type of the model's target property and then convert value to target type. This should happen implicitly.
Basically, for all the matching keys invoke ASP.NET's default binder, and for all remaining keys add value to ExtraFields