开发者

Model Binding a json array containing different object types in Asp.Net MVC

I have a json array containing integers and objects.

[1,2,3,{Name:"russia",Value:6},{Name:"usa",Value:"8"}]

I also have the following server-side class

class country {
  string Name;
  int Value;
}

How should I go about binding the json array to a server-side parameter ? I tried using a List<object> on server. It bind开发者_开发问答s the integers fine but no country instances are created. Instead, primitive objects are created and added to the list.

Thanks.


You could try something like this:

Format your controller action to accept a List<int> for your integer values and a List<Country> for your Country objects.

public ActionResult Index(List<int> intValues, List<Country> countryValues)

Then build your JSON like so that it contains and array of integers and an array of country objects:

var postData = {
    intValues: [1, 2, 3],
    countryValues: [
        { Name: 'USA', Value: 6 },
        { Name: 'Russia', Value: 8 }
    ]
};

And perform a simple AJAX call to send the data

$(function() {
    $.ajax({
        type: 'POST',
        url: "@Url.Action("Create")",
        contentType: "application/json",
        data: JSON.stringify(postData)
    });
});


Okay, I solved it at last. I created a custom model binder derived from the default model binder to accomplish this. Here's the code.

public ActionResult Home(NonHomogeneousList input)

[ModelBinder(typeof(CustomModelBinder))]
class NonHomogeneousList : List<object>

public class CustomModelBinder : DefaultModelBinder
{
    public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
        {
            NonHomogeneousList model = (NonHomogeneousList)base.BindModel(controllerContext, bindingContext);
            if (model.Members != null)
            {
                IModelBinder countryBinder = Binders.GetBinder(typeof(Country));

            // find out if the value provider has the required prefix
            bool hasPrefix = bindingContext.ValueProvider.ContainsPrefix(bindingContext.ModelName);
            string prefix = (hasPrefix) ? bindingContext.ModelName + "." : "";

            for (var i = 0; i < model.Count; i++)
            {
                var member = model.Members[i];
                if (member.GetType().Equals(typeof(object)))
                {
                    var subKey =  CreateSubIndexName( prefix , i);
                    ModelBindingContext innerContext = new ModelBindingContext()
                    {
                        ModelMetadata = ModelMetadataProviders.Current.GetMetadataForType(null, typeof(Country)),
                        ModelName = subKey,
                        ModelState = bindingContext.ModelState,
                        PropertyFilter = bindingContext.PropertyFilter,
                        ValueProvider = bindingContext.ValueProvider,
                    };
                    var country = countryBinder.BindModel(controllerContext, innerContext);
                    model.Members[i] =  country;
                }
            }
        }
        return model;
    }
}
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜