I am new using custom ModelBinders, I have been looking around and I couldn't find any post related to this specific case.
I have an entity like:
public class DynamicData
{
public IList<DynamicDataItem> DynamicDataItems{get;set;}
}
In the View i bind it like follows:
@Html.EditorFor(model => model.DynamicDataItems);
I have special information in the class DynamicDataItems, that I would like to retrieve in a specific way, so I created my own Model Binder.
public class DynamicDataItemBinder : IModelBinder
{
public object BindModel(ControllerContext controllerContext,
ModelBindingContext bindingContext)
{
var key = bindingContext.ModelName;
var valueProviderResult = bindingContext.ValueProvider
.GetValue(key);
if (valueProviderResult == null ||
string.IsNullOrEmpty(valueProviderResult
.AttemptedValue))
{
return null;
}
//Here retrieve my own Information
return DynamicDataItem;
}
}
The bindingContext.ModelName contains "DynamicDataItem[0]".
If I do bindingContext.ValueProvider.ContainsPrefix(key), it returns true, but when I do GetValue(key), it returns null. If I inspect what the ValueProvider contains, I see that there is several items with their Key Starting in "DynamicDataItem[0]". How Am I supossed to retrieve the information from all the fields for the Item that is being binded currently ("DynamicDataItem[0]")? Should I retrieve them all one by one? Like this:
var result1= bindingContext.ValueProvider.GetValue("DynamicDataItem[0].Id");
var result2= bindingContext.ValueProvider.GetValue("DynamicDataItem[0].Name");
I will greatly appreciate any guidance you can give me with this.
I know this is old post but I have the same problem and my solution was to use bindingContext.ModelName:
ValueProviderResult result = bindingContext.ValueProvider.GetValue(propertyDescriptor.Name);
if(result == null)
result = bindingContext.ValueProvider.GetValue(bindingContext.ModelName + "." + propertyDescriptor.Name);
The problem appears to be that your are trying to bind an object of type DynamicDataItem
to an input. Since DynamicDataItem
isn't a string or some other primitive type, there is no straightforward way for the binder to figure out what to do with your input and it returns null.
Assuming the class DynamicDataItem
has properties of it's own what you want to do is provide editors for each property of a DynamicDataItem
. If all you are trying to do is pass a model with a bound collection of child objects from a view, you don't even need a custom model binder. What I think you want is something in your view that reads more like this
<input type="text" name="DynamicDataItem[0].SomeTextField" />
<input type="text" name="DynamicDataItem[0].SomeOtherTextField" />
Check out Phil Haack and Scott Hanselman on the topic
Here and Here
I hope that helps
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With