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

3

12

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.

Intern answered 7/2, 2012 at 16:6 Comment(1)
I suggest you that visit [this link][1]. I think it's useful for your problem. [1]: https://mcmap.net/q/1012140/-kendoui-grid-does-not-fire-savechanges-event-system-missingmethodexception-cannot-create-an-instance-of-an-interfaceQuestionary
B
3

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);
Businesswoman answered 29/9, 2017 at 10:15 Comment(5)
Where did propertyDescriptor come from?Cultural
@onefootswill, I can not remember now but I think it comes from the method: BindProperty(ControllerContext, ModelBindingContext, PropertyDescriptor) learn.microsoft.com/en-us/dotnet/api/…Businesswoman
Thanks @vangi I realized at some point that this question was dealing with an old version of the API. I solved my problem without needing to get the value from the ValueProvider. Cheers.Cultural
@Cultural How did you get the list items then?Townsville
@bzmid If your are creating a modelbinder for a list of some kind, I'd take a look at the CollectionModelBinder source, which will probably be doing what you needCultural
C
1

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

Carincarina answered 18/5, 2012 at 5:6 Comment(0)
L
1

I was having the same issue as you and when I was digging I found your page and I think that this can help you too :) :

After Reviewing this link gaves me the idea: basically is trying to parse the querystring. You can found it in the controllercontext.httpcontext.

hope that this helps you

Best regards

Laissezfaire answered 15/6, 2012 at 14:5 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.