Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Iterate ModelBindingContext.ValueProvider

I have more then one property I need to grab, that starts with the same prefix but I can only get the exact value by key for ModelBindingContext.ValueProvider. Is there a way to grab multiple ValueProviders or iterate the System.Web.Mvc.DictionaryValueProvider<object>?

 var value = bindingContext.ValueProvider.GetValue(propertyDescriptor.Name);

The reason for doing this is a dynamic property called Settings which will bind to json properties below. Right now there is no property called "Enable" on Settings so it doesnt bind normally.

public class Integration
{
      public dynamic Settings {get;set;}
}

"Integrations[0].Settings.Enable": "true"
"Integrations[0].Settings.Name": "Will"
like image 724
Mike Flynn Avatar asked Jun 20 '26 07:06

Mike Flynn


1 Answers

Got it

 public class DynamicPropertyBinder : PropertyBinderAttribute
    {
        public override bool BindProperty(ControllerContext controllerContext, ModelBindingContext bindingContext, PropertyDescriptor propertyDescriptor)
        {
            if (propertyDescriptor.PropertyType == typeof(Object))
            {
                foreach(var valueProvider in bindingContext.ValueProvider as System.Collections.IList)
                {
                    var dictionary = valueProvider as DictionaryValueProvider<object>;

                    if (dictionary != null)
                    {
                        var keys = dictionary.GetKeysFromPrefix($"{bindingContext.ModelName}.{propertyDescriptor.Name}");

                        if (keys.Any())
                        {
                            var expando = new ExpandoObject();

                            foreach (var key in keys)
                            {
                                var keyValue = dictionary.GetValue(key.Value);

                                if (keyValue != null)
                                {
                                    AddProperty(expando, key.Key, keyValue.RawValue);

                                }
                            }

                            propertyDescriptor.SetValue(bindingContext.Model, expando);
                            return true;
                        }
                    }
                }
            }

            return false;
        }

        public static void AddProperty(ExpandoObject expando, string propertyName, object propertyValue)
        {
            var expandoDict = expando as IDictionary<string, object>;
            if (expandoDict.ContainsKey(propertyName))
                expandoDict[propertyName] = propertyValue;
            else
                expandoDict.Add(propertyName, propertyValue);
        }
    }
like image 92
Mike Flynn Avatar answered Jun 23 '26 05:06

Mike Flynn