Übergeben Sie das Array über AJAX an mvc Action

123

Ich versuche, ein Array (oder IEnumerable) von Ints über AJAX an eine MVC-Aktion zu übergeben, und ich benötige ein wenig Hilfe.

Das Javascript ist

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

und die Controller-Aktion ist

public ActionResult MyAction(IEnumerable<int> arrayOfValues )

Im Moment ist die Anfrage als formatiert

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

Ich bin also fast da, wenn ich die eckigen Klammern abnehme, bekomme ich die richtige Antwort. Wie soll ich dieses Array an mein get übergeben, damit der Controller erkennen kann, was es ist?

Vielen Dank für deine Hilfe

Dave

Dave
quelle

Antworten:

149

Setzen Sie die traditionelle Eigenschaft auf true, bevor Sie den Aufruf abrufen. dh:

jQuery.ajaxSettings.traditional = true

$.get('/controller/MyAction', { vals: arrayOfValues }, function (data) {... 
Chandu
quelle
3
Danke! Könnten Sie bitte die Unterschiede zwischen traditionellem und nicht traditionellem Ajax skizzieren? Ich möchte besser verstehen, was ich mit dem Rest meiner Bewerbung mache.
Tom Beech
5
Sie können die traditionelle Einstellung auch einem einzelnen Anruf hinzufügen. Dann wird es den Rest nicht beeinflussen
Gluip
1
Diese Antwort ist korrekt, aber wenn Sie es vorziehen, "traditionell" für einen einzelnen Anruf festzulegen, überprüfen Sie die Antwort von @RionWilliams. Beide abstimmen. Vielen Dank!
Kzfabi
@ Tom Beech Ab jQuery 1.4 serialisiert die Methode $ .param () tiefe Objekte rekursiv, um moderne Skriptsprachen und Frameworks wie PHP und Ruby on Rails zu berücksichtigen. Sie können diese Funktionalität global deaktivieren, indem Sie jQuery.ajaxSettings.traditional = true festlegen.
Alexey Shevelyov
Keine dieser Antworten funktionierte für mich (vielleicht weil mein Controller ein API-Controller war?), Aber ich fand meine Lösung in der folgenden SO-Antwort: stackoverflow.com/a/11100414/1751792
Lopsided
119

Ich hatte in der Vergangenheit Probleme beim Versuch, einen POST durchzuführen (nicht sicher, ob Sie genau das tun, aber ich erinnere mich, dass beim Übergeben eines Arrays traditionell auf true gesetzt werden muss .

 var arrayOfValues = new Array();

 //Populate arrayOfValues 
 $.ajax({ 
      type: "POST",
      url: "<%= Url.Action("MyAction","Controller")%>",
      traditional: true,
      data: { 'arrayOfValues': arrayOfValues }              
 });
Rion Williams
quelle
4
Dies ist so viel besser, als es einfach blind global in einer web.config-Datei festzulegen, wie einige Leute vorschlagen. Der andere hat seine eigenen guten Anlässe, aber Ihre sollte die Standardlösung sein.
Panzercrisis
Dies sendet nur Daten als Parameter an ActionResult. Ruft es den Code Inside ActionResult auf? Wenn beispielsweise Code zum Einfügen von Array-Werten in die Datenbank vorhanden ist, wird dieser Code ausgeführt?
Saurabh
Dies löste genau das, was ich brauchte. Meine Arrays kamen in meinem Controller immer wieder als null zurück, bis ich dies hinzufügte und sie in meinem Controller wie folgt bekam: IEnumerable <string> array
SeanMC
52

Eine ziemlich späte, aber andere Antwort als die hier bereits vorhandenen:

Wenn Sie anstelle von $.ajaxKurzfunktionen $.getoder verwenden möchten $.post, können Sie Arrays folgendermaßen übergeben:


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

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


Anmerkungen:

  • Der boolesche Parameter in $.paramist für die traditionalEigenschaft, die sein muss, truedamit dies funktioniert .
Haken
quelle
2
Vielen Dank für den Tipp zum traditionellen Anwesen. Ich konnte nicht herausfinden, warum mein C # -Parameter null war. Ich habe festgestellt, dass der Typ "int []" auch in der C # -Aktionsmethode funktioniert.
Dan Randolph
9

Sie sollten in der Lage sein, dies ganz gut zu tun:

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

Dann wäre Ihre Aktionsmethode wie folgt:

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

Für Sie sieht es so aus, als müssten Sie nur Ihre Werte stringifizieren. Der JSONValueProvider in MVC konvertiert dies zurück in einen IEnumerable für Sie.

Tejs
quelle
Vielen Dank für die Antwort, aber ich denke, es sieht so aus, als müsste ich traditionell auf wahr setzen. Habe upvoted da ich denke das würde auch funktionieren.
Dave
9

Die Antwort auf die Option "traditionell" ist richtig. Ich biete nur einige weitere Hintergrundinformationen für diese, die mehr erfahren möchten.

Aus der jQuery-Dokumentation:

Ab jQuery 1.8 verwendet die $ .param () -Methode jQuery.ajaxSettings.traditional nicht mehr als Standardeinstellung und wird standardmäßig auf false gesetzt.

Sie können auch hier mehr lesen: http://michaelsync.net/2012/04/05/tips-asp-net-mvc-javascriptserializer-3-questions-and-3-answers und http://haacked.com/archive /2008/10/23/model-binding-to-a-list.aspx

HTH

Tom Gerken
quelle
2

WENN ALLE STRICKE REISSEN...

Keine der anderen Antworten hier hat mein Problem gelöst. Ich habe versucht, einen GET-Methodenaufruf von JavaScript an einen MVC-Web-API-Controller durchzuführen und ein Array von Ganzzahlen als Parameter innerhalb dieser Anforderung zu senden. Ich habe alle Lösungen hier ausprobiert, aber der Parameter auf meinem Controller wurde immer noch NULL angezeigt (oder Nothing for you VB-Benutzer).

Ich fand meine Lösung schließlich in einem anderen SO-Beitrag , und es war eigentlich ganz einfach: Fügen Sie einfach die [FromUri]Anmerkung vor dem Array-Parameter im Controller hinzu ( ich musste den Aufruf auch mit der "traditionellen" AJAX-Einstellung tätigen, um Klammeranmerkungen zu vermeiden ). Unten finden Sie den tatsächlichen Code, den ich in meiner Anwendung verwendet habe.


Controller-Signatur:

Controller-Signatur HINWEIS: Die Anmerkung in C # wäre [FromUri]


JavaScript:

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

Aktuelle URL-Zeichenfolge:

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

Ein bisschen spät hier, aber ich könnte die SNag-Lösung weiter in $ .ajax () verwenden. Hier ist der Code, wenn er jemandem helfen würde:

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
}
Saket
quelle
1

Wenn Sie wie ich von .Net Framework MVC auf ASP.NET Core MVC migrieren, haben sich die Dinge geringfügig geändert. Der Ajax-Aufruf muss sich mit stringify auf dem Rohobjekt befinden, damit die Daten { vals: arrayOfValues }nicht JSON.stringify(arrayOfValues)wie folgt übergeben werden:

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

Die andere Änderung, die in ASP.NET Core vorgenommen wurde, besteht darin, die Fälschung von standortübergreifenden Anforderungen zu verhindern. Bei Aufrufen einer MVC-Aktion von einer Ajax-Methode [FromBody]muss das Attribut wie folgt auf den Aktionsparameter angewendet werden:

public ActionResult MyAction([FromBody] IEnumerable<int> arrayOfValues )
Michael Armitage
quelle
Vielen Dank, dies war unglaublich hilfreich, nachdem jede andere Permutation von Möglichkeiten zum Senden der Daten fehlgeschlagen ist!
NibblyPig
0

Wenn Sie ASP.NET Core MVC verwenden und die eckigen Klammern verwenden müssen (anstatt die "traditionelle" jQuery-Option zu verwenden), habe ich nur die Option gefunden, die IEnumerablein der Contoller-Methode manuell zu erstellen.

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

Ich arbeite mit asp.net Core 2.2 und jquery und muss ein komplexes Objekt ('Hauptklasse') aus einer Sicht an einen Controller mit einfachen Datenfeldern und einigen Arrays senden.
Sobald ich das Array in der c # -Definition 'Hauptklasse' hinzugefügt habe (siehe unten) und das (korrekt gefüllte) Array über Ajax (Post) gesendet habe, war das gesamte Objekt im Controller null.
Zuerst dachte ich, das fehlende "traditionell: wahr" für meinen Ajax-Aufruf sei der Grund, aber das ist nicht der Fall.
In meinem Fall war der Grund die Definition in der c # 'Hauptklasse'.
In der 'Hauptklasse' hatte ich:

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

und EreignisTagNeu wurde definiert als:

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

Ich musste die Definition in der 'Hauptklasse' ändern in:

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

Jetzt gehts.
Also ... für mich scheint es, dass der asp.net-Kern ein Problem hat (mit post), wenn die Liste für ein Array nicht vollständig in der 'Hauptklasse' definiert ist.
Hinweis: In meinem Fall funktioniert dies mit oder ohne "traditionell: wahr" für den Ajax-Aufruf

FredyWenger
quelle
-3

Sie müssen Array in String konvertieren:

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

Dies funktioniert sogar in Form von int, long oder string

public ActionResult MyAction(int[] arrayOfValues )
dr.Crow
quelle
Dies ist nicht einmal die richtige Syntax, um ein Array an den Server zu senden. Sie übergeben nur ein Objekt und nehmen an, dass es sich um ein Array handelt, was bei dem, was Sie bereitgestellt haben, niemals der Fall ist. Dies ist ein STRING.
Twister1002