Model在Asp.Net MVC中绑定包含不同对象类型的json数组

时间:2011-06-22 16:20:42

标签: asp.net json asp.net-mvc-3

我有一个包含整数和对象的json数组。

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

我还有以下服务器端类

class country {
  string Name;
  int Value;
}

我应该如何将json数组绑定到服务器端参数?我尝试在服务器上使用List<object>。它可以很好地绑定整数,但不会创建国家/地区实例。而是创建原始对象并将其添加到列表中。

感谢。

2 个答案:

答案 0 :(得分:1)

您可以尝试这样的事情:

将控制器操作设置为接受List<int>表示整数值,并为{Country}对象接受List<Country>

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

然后构建您的JSON,使其包含整数数组和国家/地区对象数组:

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

执行简单的AJAX调用以发送数据

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

答案 1 :(得分:1)

好的,我终于解决了。我创建了一个从默认模型绑定器派生的自定义模型绑定器来实现此目的。这是代码。

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