Pass array to mvc Action via AJAX

I'm trying to pass an array (or IEnumerable) of ints from via AJAX to an MVC action and I need a little help.

the javascript is

$.get('/controller/MyAction', { vals: arrayOfValues }, function (data) {...

and the controller action is

public ActionResult MyAction(IEnumerable<int> arrayOfValues )

At the moment the request is formatted as

controller/MyAction?_=1301503418429&arrayOfValues[]=491&arrayOfValues[]=368&arrayOfValues[]=235&arrayOfValues[]=437

So I'm almost there, if I take the square brackets off I get the correct response. How should I be passing that array into my get so that the controller can recognise what it is?

Many thanks for your help

Dave

178548 次浏览

You should be able to do this just fine:

$.ajax({
url: 'controller/myaction',
data: JSON.stringify({
myKey: myArray
}),
success: function(data) { /* Whatever */ }
});

Then your action method would be like so:

public ActionResult(List<int> myKey)
{
// Do Stuff
}

For you, it looks like you just need to stringify your values. The JSONValueProvider in MVC will convert that back into an IEnumerable for you.

Set the traditional property to true before making the get call. i.e.:

jQuery.ajaxSettings.traditional = true


$.get('/controller/MyAction', { vals: arrayOfValues }, function (data) {...

I have had issues in the past when attempting to perform a POST (not sure if that is exactly what you are doing, but I recall when passing an array in, traditional must be set to true.

 var arrayOfValues = new Array();


//Populate arrayOfValues
$.ajax({
type: "POST",
url: "<%= Url.Action("MyAction","Controller")%>",
traditional: true,
data: { 'arrayOfValues': arrayOfValues }
});

The answer to use the 'traditional' option is correct. I'm just providing some more background info for this who wish to learn more.

From the jQuery documentation:

As of jQuery 1.8, the $.param() method no longer uses jQuery.ajaxSettings.traditional as its default setting and will default to false.

You can also read more here: http://michaelsync.net/2012/04/05/tips-asp-net-mvc-javascriptserializer-3-questions-and-3-answers and http://haacked.com/archive/2008/10/23/model-binding-to-a-list.aspx

HTH

Quite a late, but different answer to the ones already present here:

If instead of $.ajax you'd like to use shorthand functions $.get or $.post, you can pass arrays this way:


Shorthand GET

var array = [1, 2, 3, 4, 5];
$.get('/controller/MyAction', $.param({ data: array }, true), function(data) {});


// Action Method
public void MyAction(List<int> data)
{
// do stuff here
}

Shorthand POST

var array = [1, 2, 3, 4, 5];
$.post('/controller/MyAction', $.param({ data: array }, true), function(data) {});


// Action Method
[HttpPost]
public void MyAction(List<int> data)
{
// do stuff here
}


Notes:

  • The boolean parameter in $.param is for the traditional property, which MUST be true for this to work.

You need to convert Array to string :

//arrayOfValues = [1, 2, 3];
$.get('/controller/MyAction', { arrayOfValues: "1, 2, 3" }, function (data) {...

this works even in form of int, long or string

public ActionResult MyAction(int[] arrayOfValues )

IF ALL ELSE FAILS...

None of the other answers here solved my problem. I was attempting to make a GET method call from JavaScript to an MVC Web API controller, and to send an array of integers as a parameter within that request. I tried all the solutions here, but still the parameter on my controller was coming up NULL (or Nothing for you VB users).

I eventually found my solution in a different SO post, and it was actually really simple: Just add the [FromUri] annotation before the array parameter in the controller (I also had to make the call using the "traditional" AJAX setting to avoid bracket annotations). See below for the actual code I used in my application.


Controller Signature:

Controller Signature NOTE: The annotation in C# would be [FromUri]


JavaScript:

$.get('/api/InventoryApi/GetBalanceField', $.param({productIds: [42], inventoryFormId: 5493, inventoryBalanceType: 'Beginning'},true)).done(function(data) {console.log(data);});

Actual URL String:

http://randomhostname/api/InventoryApi/GetBalanceField?productIds=42&inventoryFormId=5493&inventoryBalanceType=Beginning

If you're using ASP.NET Core MVC and need to handle the square brackets (rather than use the jQuery "traditional" option), the only option I've found is to manually build the IEnumerable in the contoller method.

string arrayKey = "p[]=";
var pArray = HttpContext.Request.QueryString.Value
.Split('&')
.Where(s => s.Contains(arrayKey))
.Select(s => s.Substring(arrayKey.Length));

If you are migrating to ASP.NET Core MVC from .Net Framework MVC like I was, things have changed slightly. The ajax call must be on the raw object using stringify so rather than passing data of { vals: arrayOfValues } it should be JSON.stringify(arrayOfValues) as follows:

$.ajax({
url: 'controller/myaction',
data: JSON.stringify(arrayOfValues),
success: function(data) { /* Whatever */ }
});

The other change that has been made in ASP.NET Core is to prevent cross-site request forgery so for calls to an MVC action from an ajax method the [FromBody] atribute must be applied to the action parameter as follows:

public ActionResult MyAction([FromBody] IEnumerable<int> arrayOfValues )

A bit late here, but I could use SNag's solution further into $.ajax(). Here is the code if it would help anyone:

var array = [1, 2, 3, 4, 5];


$.ajax({
type: "GET",
url: '/controller/MyAction',
data: $.param({ data: array}, true),
contentType: 'application/json; charset=utf-8',
success: function (data) {
},
error: function (x, y, z) {
}
});


// Action Method
public void MyAction(List<int> data)
{
// do stuff here
}

I work with asp.net core 2.2 and jquery and have to submit a complex object ('main class') from a view to a controller with simple data fields and some array's.
As soon as I have added the array in the c# 'main class' definition (see below) and submitted the (correct filled) array over ajax (post), the whole object was null in the controller.
First, I thought, the missing "traditional: true," to my ajax call was the reason, but this is not the case.
In my case the reason was the definition in the c# 'main class'.
In the 'main class', I had:

public List<EreignisTagNeu> oEreignistageNeu { get; set; }

and EreignisTagNeu was defined as:

public class EreignisTagNeu
{
public int iHME_Key { get; set; }
}

I had to change the definition in the 'main class' to:

 public List<int> oEreignistageNeu { get; set; }

Now it works.
So... for me it seems as asp.net core has a problem (with post), if the list for an array is not defined completely in the 'main class'.
Note: In my case this works with or without "traditional: true," to the ajax call

If you need to pass more parameters where par1 it's an array, the JSON must contain every parameter, I used this code:

$.ajax({
type: "POST",
url: URL,
data: JSON.stringify({ par1: val1, par2: val2 }),
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (data) {},
error: function (result) {}
});