KallDrexx
KallDrexx

Reputation: 27813

How do you serialize a JS array so Asp.net MVC can bind it to a c# list?

I am trying to send a jquery sortable list of items to my MVC method for data processing. Currently I am trying to send it via the following code:

var data = {};
data.projectId = projectId;
data.publishedSectionIds = $('#section_list').sortable('toArray');

// Perform the ajax
$.ajax({ url: '/Project/Publish',
    type: 'POST',
    data: data,
    success: function (result) {
        alert(result.message);
    } 
});

The problem with this code is it makes the Post parameters look like this:

projectId=2&publishedSectionIds[]=1&publishedSectionIds[]=2

The issue with this (as can be seen by the solution to this question) is that MVC only seems to serialize into a List if the post parameters do NOT have brackets.

How can I serialize the javascript array so my action with a List<int> parameter model binds correctly?


Edit: The action's signature looks like:

 public ActionResult Publish(int projectId, List<int> publishedSectionIds)

Upvotes: 5

Views: 2493

Answers (4)

Jeremy Boyd
Jeremy Boyd

Reputation: 5405

When I pass in JavaScript arrays into my post method, i type them as an int[] not List<int>.

Try this if you haven't.

Upvotes: 0

eapen
eapen

Reputation: 579

If you want to handle it completely in JS (you may need to edit line 2 - I have assumed that you are using a list and are trying to pull the id attribute itself)

var data = "projectId=" + projectId;
$("#section_list li").each(function(){ data += "&publishedSectionIds=" + this.id;});
$.ajax({ url: '/main/test',
    type: 'POST',
    data: data,
    success: function (result) {
        alert(result.message);
    } 
});

or if you want to make sure you are using sortable('toArray') data (although the above result also provides the sorted data)

var data = "projectId=" + projectId;
var tempData = $('#section_list').sortable('toArray');
$.each(tempData, function(index, value){ data += "&publishedSectionIds=" + value;});
$.ajax({ url: '/main/test',
    type: 'POST',
    data: data,
    success: function (result) {
        alert(result.message);
    } 
});

Upvotes: 0

Patricia
Patricia

Reputation: 7802

alright here's something i just wrote now that works!

here's the action:

Public Overridable Function PostProject(ByVal model As Project) As ActionResult
    Return Json(model.PublishedSectionIds)

End Function

here's the class:

Public Class Project
    Public Property ProjectId As Integer
    Public Property PublishedSectionIds As IList(Of Integer)
End Class

here's the javascript:

        var data = {};
        data.ProjectId = 1;

        data.PublishedSectionIds = $('#section_list').sortable('toArray');
        var url=  "/testing/tester";
        $.ajax({ 
            url:url,
            type: 'POST',
             traditional: true,
            data: data,
            success: function (result) {
                alert(result);
            }
        });

ignore the fact that my action is overridable. that's just from t4mvc.

i tried it with the list being and IList or a List, both work just fine.

hope that helps!

Edit:

I also tested it w/o the model like so:

    Public Overridable Function PostProject2(ByVal ProjectId As Integer, ByVal PublishedSectionIds As List(Of Integer)) As ActionResult
        Return Json(PublishedSectionIds)

    End Function

add it worked just fine as well.

Upvotes: 2

Okeydoke
Okeydoke

Reputation: 1357

try adding the following option traditional: true

eg

$.ajax({ url: '/Project/Publish',
    type: 'POST',
    data: data,
    traditional: true,
    success: function (result) {
        alert(result.message);
    } 
});

see

As of jQuery 1.4, the $.param() method serializes deep objects recursively to accommodate modern scripting languages and frameworks such as PHP and Ruby on Rails. You can disable this functionality globally by setting jQuery.ajaxSettings.traditional = true;.

http://api.jquery.com/jQuery.param/

Upvotes: 3

Related Questions