最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Asp.Net MVC 4 Automatically bind model from array of objects in form post - Stack Overflow

programmeradmin1浏览0评论

I have built an array of objects in JavaScript and want to post them back to the server via Ajax (Im using jQuery)

The JavaScript object array looks like this:

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

Im posting it back like this:

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

On the controller action Im currently getting this:

I have a c# object called JqColumn that I want to bind the post into, it looks like this:

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

So I thought that adding a parameter in the controller action of type JqGridColumn[] columns would automatically bind the posted data, but it doesn't (it generates a array, with the correct number of elements, but each item in the array has blank values)

Can anyone tell me what Im doing wrong? Thanks!

UPDATE

At present, I am manually binding the items in my controller action as follows:

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

...which works fine, but I'd really like to know the .Net MVC (correct) way to do it!

I have built an array of objects in JavaScript and want to post them back to the server via Ajax (Im using jQuery)

The JavaScript object array looks like this:

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

Im posting it back like this:

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

On the controller action Im currently getting this:

I have a c# object called JqColumn that I want to bind the post into, it looks like this:

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

So I thought that adding a parameter in the controller action of type JqGridColumn[] columns would automatically bind the posted data, but it doesn't (it generates a array, with the correct number of elements, but each item in the array has blank values)

Can anyone tell me what Im doing wrong? Thanks!

UPDATE

At present, I am manually binding the items in my controller action as follows:

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

...which works fine, but I'd really like to know the .Net MVC (correct) way to do it!

Share Improve this question edited Apr 23, 2014 at 11:44 Jimbo asked Apr 23, 2014 at 10:54 JimboJimbo 23k44 gold badges125 silver badges162 bronze badges 3
  • Have you tried making the fields on your JqGridColumn object into properties (ie, add a get & set) as it sounds the the model binder can't find the fields – Simon Halsey Commented Apr 23, 2014 at 11:22
  • Tried and still no joy I'm afraid... :( – Jimbo Commented Apr 23, 2014 at 11:42
  • Have you tried using a WebApi Controller, the model binding might be handled differently using the WebAPI Controller as the default MVC binding (i think) depends on HTML Elements being posted back in a FormCollection. – Patrick Magee Commented Apr 24, 2014 at 8:56
Add a ment  | 

3 Answers 3

Reset to default 10

Since you didn't register a specific ModelBinder for the JqGridColumn type, the DefaultModelBinder will be used. But:

  • It won't bind Fields, only public Properties.

  • The expected format for Array binding is columns[0].name while you're actually posting columns[0][name].

The problem could be solved easily if you'll simply send your columns in JSON format instead of Name-Value-Pairs:

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

Yet, if you don't like to change your class, you could register a ModelBinder specific for JqGridColumn and have it working even with Fields and current jQuery serialization:

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

Then register it in App_Start/ModelBindingConfig.cs:

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

It's because your JqGridColumn object needs properties, not fields. see this question for reference:

ASP MVC - Model binding excludes class fields?

try post back with the traditional : true setting and dataType: json

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

评论列表(0)

  1. 暂无评论