web-dev-qa-db-fra.com

Passer tableau à mvc Action via AJAX

J'essaie de passer un tableau (ou IEnumerable) d'ints de via AJAX à une action MVC et j'ai besoin d'un peu d'aide. 

le javascript est 

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

et l'action du contrôleur est 

public ActionResult MyAction(IEnumerable<int> arrayOfValues )

Au moment où la demande est formatée comme 

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

Donc, j'y suis presque, si je supprime les crochets, j'obtiens la réponse correcte. Comment devrais-je passer ce tableau dans mon get afin que le contrôleur puisse reconnaître ce que c'est? 

Merci beaucoup pour votre aide

Dave

115
Dave

Définissez la propriété traditionnelle sur true avant de passer l'appel get .

jQuery.ajaxSettings.traditional = true

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

J'ai eu des problèmes par le passé lors de la tentative d'exécution d'un POST (je ne sais pas si c'est exactement ce que vous faites, mais je me souviens que, lors du passage d'un tableau, traditional doit être défini sur true .

 var arrayOfValues = new Array();

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

Assez tard, mais différent réponse à celles déjà présentes ici:

Si, au lieu de $.ajax, vous souhaitez utiliser les fonctions abrégées $.get ou $.post , vous pouvez passer des tableaux de cette façon:


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
}

POST abrégé

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
}


Remarques:

  • Le paramètre booléen dans $.param correspond à la propriété traditional , qui DOIT être true pour que cela fonctionne
47
SNag

La réponse à utiliser l'option «traditionnelle» est correcte. Je ne fais que fournir quelques informations de base pour ceux qui souhaitent en savoir plus.

À partir de la documentation jQuery:

Depuis jQuery 1.8, la méthode $ .param () n'utilise plus jQuery.ajaxSettings.traditional comme paramètre par défaut et will défaut à false.

Vous pouvez également en lire plus ici: http://michaelsync.net/2012/04/05/tips-asp-net-mvc-javascriptserializer-3-questions-and-3-answers et http://haacked.com/archive/2008/10/23/model-binding-to-a-list.aspx

HTH

9
Tom Gerken

Vous devriez être capable de faire ça très bien:

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

Alors votre méthode d'action serait comme suit:

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

Pour vous, il semble que vous ayez juste besoin de renforcer vos valeurs. JSONValueProvider dans MVC reconvertira cela en un IEnumerable pour vous. 

7
Tejs

Si tout le reste échoue ...

Aucune des autres réponses ici résolu mon problème. J'essayais de passer un appel de méthode GET depuis JavaScript vers un contrôleur API Web MVC et d'envoyer un tableau d'entiers en tant que paramètre dans cette demande. J'ai essayé toutes les solutions ici, mais le paramètre de mon contrôleur était toujours NULL (ou rien pour vous VB utilisateurs). 

J'ai finalement trouvé ma solution dans un différent SO post , et c’était vraiment très simple: il suffit d’ajouter l’annotation [FromUri] avant le paramètre array dans le contrôleur (j’ai également dû effectuer l’appel avec le paramètre "traditionnel" AJAX pour éviter les annotations entre crochets). Voir ci-dessous le code que j'ai utilisé dans mon application.


Signature du contrôleur:

 Controller Signature NOTE: l'annotation en C # serait[FromUri]


JavaScript:

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

URL réelle:

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

Un peu tard ici, mais je pourrais utiliser la solution de SNag plus loin dans $ .ajax (). Voici le code si cela pourrait aider quelqu'un:

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
}
0
Saket

Si vous migrez vers ASP.NET Core MVC à partir de .Net Framework MVC comme moi, les choses ont légèrement changé. L'appel ajax doit être sur l'objet brut en utilisant stringify, donc plutôt que de transmettre les données de { vals: arrayOfValues }, il devrait être JSON.stringify(arrayOfValues) comme suit:

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

L'autre modification apportée dans ASP.NET Core consiste à empêcher la falsification de requêtes intersites. Ainsi, pour les appels à une action MVC à partir d'une méthode ajax, l'attribut [FromBody] doit être appliqué au paramètre action comme suit:

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

Si vous utilisez ASP.NET Core MVC et que vous devez gérer les crochets (plutôt que d'utiliser l'option "traditionnelle" de jQuery), la seule option que j'ai trouvée est de générer manuellement la variable IEnumerable dans la méthode contoller. .

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