Asp.Net MVC 4自动绑定表单中对象数组的模型

时间:2014-04-23 10:55:00

标签: javascript arrays asp.net-mvc model-binding form-post

我在JavaScript中构建了一个对象数组,并希望通过Ajax将它们发布回服务器(我使用jQuery)

JavaScript对象数组如下所示:

var columns = [
    { name: 'col 1', source: 'whatever', hidden: false, width: 50 },
    ...
];

我发布回来像这样:

$.post('/MyController/MyAction', { 'columns': columns });

关于控制器操作我目前正在这样:

enter image description here

我有一个名为JqColumn的c#对象我要将帖子绑定到,它看起来像这样:

public class JqGridColumn
{
    public string name;
    public string source;
    public int width;
    public bool hidden;
}

所以我认为在类型JqGridColumn[] columns的控制器操作中添加一个参数会自动绑定发布的数据,但它不会(它生成一个数组,具有正确数量的元素,但每个数组中的项目具有空白值)

谁能告诉我我做错了什么?谢谢!

更新

目前,我手动绑定控制器操作中的项目如下:

    public void ColumnChooser(JqGridColumn[] columns)
    {
        for (int i = 0; i < columns.Length; i++)
        {
            columns[i].hidden = bool.Parse(Request.Form["columns[" + i + "][hidden]"]);
            columns[i].width = int.Parse(Request.Form["columns[" + i + "][width]"]);
            columns[i].name = Request.Form["columns[" + i + "][name]"];
            columns[i].source = Request.Form["columns[" + i + "][source]"];
        }
        return;
    }

...工作正常,但我真的很想知道.Net MVC(正确)方法!

3 个答案:

答案 0 :(得分:10)

由于您没有为ModelBinder类型注册特定JqGridColumn,因此将使用DefaultModelBinder。但是:

  • 它不会绑定字段,只会绑定公共属性。

  • 当您实际发布columns[0].name时,数组绑定的预期格式为columns[0][name]

如果您只是以 JSON 格式发送columns而非名称 - 价值对,则问题可以轻松解决:

$.ajax({
    url: '/MyController/MyAction',
    method: 'POST',
    contentType: 'application/json',
    data: JSON.stringify({ columns: columns })
});

但是,如果您不想更改课程,可以注册一个ModelBinder专用于JqGridColumn,并使其适用于Fields和当前的jQuery序列化:

public class JqGridColumnBinder : DefaultModelBinder
{
    protected override object CreateModel(ControllerContext controllerContext, ModelBindingContext bindingContext, Type modelType)
    {
        string name = bindingContext.ValueProvider.GetValue(bindingContext.ModelName + "[name]").AttemptedValue;
        string source = bindingContext.ValueProvider.GetValue(bindingContext.ModelName + "[source]").AttemptedValue;
        int width = (int)bindingContext.ValueProvider.GetValue(bindingContext.ModelName + "[width]").ConvertTo(typeof(int));
        bool hidden = (bool)bindingContext.ValueProvider.GetValue(bindingContext.ModelName + "[hidden]").ConvertTo(typeof(bool));

        return new JqGridColumn
        {
            name = name,
            source = source,
            width = width,
            hidden = hidden
        };
    }
}

然后在 App_Start / ModelBindingConfig.cs 中注册:

binders.Add(typeof(JqGridColumn), new JqGridColumnBinder());

答案 1 :(得分:0)

这是因为您的JqGridColumn对象需要属性,而不是字段。请参阅此问题以供参考:

ASP.net MVC - Model binding excludes class fields?

答案 2 :(得分:0)

尝试回复传统:真实设置 和dataType:json

$.ajax({
    url: '/MyController/MyAction',
    method: 'POST',
    traditional: true,
    dataType: json
    data: columns ,            
    sucess: function () { alert('Success'); }
});