Passa l'array all'azione mvc tramite AJAX


124

Sto cercando di passare un array (o IEnumerable) di int da via AJAX a un'azione MVC e ho bisogno di un piccolo aiuto.

il javascript è

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

e l'azione del controller è

public ActionResult MyAction(IEnumerable<int> arrayOfValues )

Al momento la richiesta è formattata come

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

Quindi ci sono quasi, se tolgo le parentesi quadre ottengo la risposta corretta. Come dovrei passare quell'array al mio get in modo che il controller possa riconoscere di cosa si tratta?

Molte grazie per il vostro aiuto

Dave

Risposte:


149

Impostare la proprietà tradizionale su true prima di effettuare la chiamata get. vale a dire:

jQuery.ajaxSettings.traditional = true

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

3
grazie! potresti delineare le differenze tra ajax tradizionale e non tradizionale? vorrei capire meglio cosa sto facendo al resto della mia applicazione.
Tom Beech

5
puoi anche aggiungere l'impostazione tradizionale a una singola chiamata. Quindi non influenzerà il resto
Gluip

1
Questa risposta è corretta, ma se preferisci impostare "tradizionale" per una singola chiamata, controlla la risposta di @RionWilliams. Votando entrambi. Grazie!
kzfabi

@Tom Beech A partire da jQuery 1.4, il metodo $ .param () serializza oggetti profondi in modo ricorsivo per adattarsi ai moderni linguaggi di scripting e framework come PHP e Ruby on Rails. È possibile disabilitare questa funzionalità a livello globale impostando jQuery.ajaxSettings.traditional = true;
Alexey Shevelyov

Nessuna di queste risposte ha funzionato per me (forse perché il mio controller era un controller API?), Ma ho trovato la mia soluzione nella seguente risposta SO: stackoverflow.com/a/11100414/1751792
Lopsided

119

Ho avuto problemi in passato durante il tentativo di eseguire un POST (non sono sicuro che sia esattamente quello che stai facendo, ma ricordo che quando si passa un array, il tradizionale deve essere impostato su true .

 var arrayOfValues = new Array();

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

4
Questo è molto meglio che impostarlo ciecamente a livello globale in un file web.config, come suggeriscono alcune persone. L'altro ha la sua serie di buone occasioni, ma la tua dovrebbe essere la soluzione predefinita.
Panzercrisis

Questo è solo l'invio di dati come parametro ad ActionResult, richiamerà il codice Inside ActionResult? Ad esempio, se c'è del codice per inserire arrayofvalues ​​nel database, quel codice verrà eseguito?
Saurabh

Questo ha risolto esattamente ciò di cui avevo bisogno. I miei array continuavano a tornare come nulli nel mio controller finché non l'ho aggiunto e li ho
ricevuti

52

Una risposta abbastanza tarda, ma diversa da quelle già presenti qui:

Se invece di $.ajaxdesideri utilizzare funzioni abbreviate $.geto $.post, puoi passare gli array in questo modo:


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

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


Appunti:

  • Il parametro booleano in $.paramè per la traditionalproprietà, che DEVE essere trueaffinché funzioni .

2
Grazie per il suggerimento sulla proprietà tradizionale. Non sono riuscito a capire perché il mio parametro C # fosse nullo. Ho scoperto che il tipo "int []" funzionerà anche nel metodo Action C #.
Dan Randolph

9

Dovresti essere in grado di farlo bene:

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

Quindi il tuo metodo di azione sarebbe così:

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

Per te, sembra che tu abbia solo bisogno di stringere i tuoi valori. Il JSONValueProvider in MVC lo convertirà di nuovo in un IEnumerable per te.


Grazie per la risposta, ma penso che sia necessario impostare il tradizionale su vero. Ho votato contro perché penso che funzionerebbe anche questo.
Dave

9

La risposta per utilizzare l'opzione "tradizionale" è corretta. Sto solo fornendo alcune informazioni di base per chi desidera saperne di più.

Dalla documentazione di jQuery:

A partire da jQuery 1.8, il metodo $ .param () non utilizza più jQuery.ajaxSettings.traditional come impostazione predefinita e verrà impostato su false.

Puoi anche leggere di più qui: http://michaelsync.net/2012/04/05/tips-asp-net-mvc-javascriptserializer-3-questions-and-3-answers e http://haacked.com/archive /2008/10/23/model-binding-to-a-list.aspx

HTH


2

SE TUTTI GLI ALTRI FALLISCONO...

Nessuna delle altre risposte qui ha risolto il mio problema. Stavo tentando di effettuare una chiamata al metodo GET da JavaScript a un controller API Web MVC e di inviare un array di numeri interi come parametro all'interno di tale richiesta. Ho provato tutte le soluzioni qui, ma il parametro sul mio controller risultava ancora NULL (o Niente per voi utenti VB).

Alla fine ho trovato la mia soluzione in un diverso post SO , ed è stato davvero molto semplice: basta aggiungere l' [FromUri]annotazione prima del parametro array nel controller ( ho anche dovuto effettuare la chiamata utilizzando l'impostazione AJAX "tradizionale" per evitare annotazioni tra parentesi ). Vedi sotto per il codice effettivo che ho usato nella mia applicazione.


Firma del controller:

Firma del controller NOTA: l'annotazione in C # sarebbe [FromUri]


JavaScript:

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

Stringa URL effettiva:

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

2

Un po 'tardi qui, ma potrei usare ulteriormente la soluzione di SNag in $ .ajax (). Ecco il codice se potesse aiutare qualcuno:

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
}

1

Se stai migrando ad ASP.NET Core MVC da .Net Framework MVC come me, le cose sono leggermente cambiate. La chiamata ajax deve essere sull'oggetto grezzo usando stringify, quindi piuttosto che passare i dati { vals: arrayOfValues }dovrebbe essere JSON.stringify(arrayOfValues)il seguente:

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

L'altra modifica apportata in ASP.NET Core consiste nell'impedire la falsificazione delle richieste tra siti, quindi per le chiamate a un'azione MVC da un metodo ajax l' [FromBody]atribute deve essere applicato al parametro dell'azione come segue:

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

Grazie, questo è stato incredibilmente utile dopo ogni altra permutazione di modi per inviare i dati fallita!
NibblyPig

0

Se utilizzi ASP.NET Core MVC e devi gestire le parentesi quadre (anziché utilizzare l'opzione "tradizionale" di jQuery), l'unica opzione che ho trovato è creare manualmente IEnumerableil metodo nel contoller.

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

0

Lavoro con asp.net core 2.2 e jquery e devo inviare un oggetto complesso ('classe principale') da una vista a un controller con semplici campi dati e alcuni array.
Non appena ho aggiunto l'array nella definizione di "classe principale" c # (vedi sotto) e ho inviato l'array (riempito correttamente) su ajax (post), l'intero oggetto era nullo nel controller.
In primo luogo, ho pensato, la mancanza di "tradizionale: vero", per la mia chiamata ajax era la ragione, ma non è così.
Nel mio caso il motivo era la definizione nella "classe principale" c #.
Nella 'classe principale', ho avuto:

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

e EreignisTagNeu è stato definito come:

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

Ho dovuto cambiare la definizione nella 'classe principale' in:

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

Ora funziona.
Quindi ... per me sembra che asp.net core abbia un problema (con post), se l'elenco per un array non è definito completamente nella 'classe principale'.
Nota: nel mio caso funziona con o senza "tradizionale: vero", per la chiamata ajax


-3

Devi convertire Array in stringa:

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

funziona anche in forma di int, long o string

public ActionResult MyAction(int[] arrayOfValues )

Questa non è nemmeno la sintassi corretta per inviare un array al server. Stai solo passando un oggetto e presumendo che sia un array, il che non sarà mai il caso di ciò che hai fornito, che è una STRINGA.
Twister1002
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.