MVC 3.0 ModelBinder bindingContext.ValueProvider.GetValue(key) returns null when binding in a collection

Dzyann picture Dzyann · Feb 7, 2012 · Viewed 10.2k times · Source

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.

Answer

Vangi picture Vangi · Sep 29, 2017

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);