Lulus array ke Action MVC melalui AJAX

124

Saya mencoba untuk melewatkan array (atau IEnumerable) int dari melalui AJAX ke tindakan MVC dan saya butuh sedikit bantuan.

javascript-nya

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

dan tindakan pengontrol adalah

public ActionResult MyAction(IEnumerable<int> arrayOfValues )

Saat ini permintaan diformat sebagai

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

Jadi saya hampir sampai, jika saya melepas tanda kurung siku, saya mendapatkan jawaban yang benar. Bagaimana saya harus meneruskan array itu ke get saya sehingga pengontrol dapat mengenali apa itu?

Terima kasih banyak atas bantuanmu

Dave

Dave
sumber

Jawaban:

149

Setel properti tradisional ke true sebelum melakukan panggilan get. yaitu:

jQuery.ajaxSettings.traditional = true

$.get('/controller/MyAction', { vals: arrayOfValues }, function (data) {... 
Chandu
sumber
3
Terima kasih! Bisakah Anda menjelaskan perbedaan antara ajax tradisional dan non tradisional? saya ingin lebih memahami apa yang saya lakukan untuk aplikasi saya lainnya.
Tom Beech
5
Anda juga dapat menambahkan pengaturan tradisional ke satu panggilan. Maka itu tidak akan mempengaruhi sisanya
Gluip
1
Jawaban ini benar, tetapi jika Anda lebih suka menyetel "tradisional" untuk satu panggilan, periksa jawaban @RionWilliams. Memilih keduanya. Terima kasih!
kzfabi
@Tom Beech Pada jQuery 1.4, metode $ .param () membuat serial objek dalam secara rekursif untuk mengakomodasi bahasa skrip dan kerangka kerja modern seperti PHP dan Ruby on Rails. Anda dapat menonaktifkan fungsionalitas ini secara global dengan mengatur jQuery.ajaxSettings.traditional = true;
Alexey Shevelyov
Tak satu pun dari jawaban ini berhasil untuk saya (mungkin karena pengontrol saya adalah pengontrol API?), Tetapi saya menemukan solusi saya di jawaban SO berikut: stackoverflow.com/a/11100414/1751792
miring
119

Saya memiliki masalah di masa lalu ketika mencoba melakukan POST (tidak yakin apakah itu yang Anda lakukan, tetapi saya ingat ketika mengirimkan array, tradisional harus disetel ke true .

 var arrayOfValues = new Array();

 //Populate arrayOfValues 
 $.ajax({ 
      type: "POST",
      url: "<%= Url.Action("MyAction","Controller")%>",
      traditional: true,
      data: { 'arrayOfValues': arrayOfValues }              
 });
Rion Williams
sumber
4
Ini jauh lebih baik daripada hanya mengaturnya secara global dalam file web.config, seperti yang disarankan beberapa orang. Yang lain memiliki rangkaian acara bagusnya sendiri, tetapi milik Anda harus menjadi solusi default.
Panzercrisis
Ini hanya mengirim data sebagai parameter ke ActionResult, akankah itu memanggil kode Inside ActionResult? Misalnya jika ada beberapa kode untuk memasukkan nilai array ke dalam database, apakah kode itu akan berjalan?
Saurabh
Ini menyelesaikan apa yang saya butuhkan. Array saya terus kembali sebagai null di pengontrol saya sampai saya menambahkan ini dan mendapatkannya di pengontrol saya seperti: IEnumerable <string> array
SeanMC
52

Jawaban yang agak terlambat, tetapi berbeda dengan yang sudah ada di sini:

Jika alih-alih $.ajaxAnda ingin menggunakan fungsi singkatan $.getatau $.post, Anda dapat meneruskan array dengan cara ini:


Singkatan 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 Singkatan

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
}


Catatan:

  • Parameter boolean di $.paramadalah untuk traditionalproperti, yang HARUS digunakan trueuntuk ini .
Merobek
sumber
2
Terima kasih atas tip tentang properti tradisional. Saya tidak tahu mengapa parameter C # saya nol. Saya menemukan bahwa tipe "int []" juga akan bekerja dalam metode C # Action.
Dan Randolph
9

Anda seharusnya dapat melakukan ini dengan baik:

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

Maka metode tindakan Anda akan seperti ini:

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

Bagi Anda, sepertinya Anda hanya perlu merangkai nilai-nilai Anda. JSONValueProvider di MVC akan mengubahnya kembali menjadi IEnumerable untuk Anda.

Tejs
sumber
Terima kasih atas jawabannya, tetapi saya pikir sepertinya saya perlu menyetel tradisional menjadi benar. Telah memberi suara positif karena saya pikir ini akan berhasil juga.
Dave
9

Jawaban untuk menggunakan opsi 'tradisional' benar. Saya hanya memberikan beberapa info latar belakang lainnya untuk ini yang ingin mempelajari lebih lanjut.

Dari dokumentasi jQuery:

Mulai jQuery 1.8, metode $ .param () tidak lagi menggunakan jQuery.ajaxSettings.traditional sebagai pengaturan default dan akan default ke false.

Anda juga dapat membaca lebih lanjut di sini: http://michaelsync.net/2012/04/05/tips-asp-net-mvc-javascriptserializer-3-questions-and-3-answers dan http://haacked.com/archive /2008/10/23/model-binding-to-a-list.aspx

HTH

Tom Gerken
sumber
2

JIKA SEMUA ORANG LAIN GAGAL ...

Tidak ada jawaban lain di sini yang memecahkan masalah saya. Saya mencoba membuat panggilan metode GET dari JavaScript ke pengontrol MVC Web API, dan mengirim array bilangan bulat sebagai parameter dalam permintaan itu. Saya mencoba semua solusi di sini, tetapi parameter pada pengontrol saya tetap muncul NULL (atau Tidak ada untuk Anda pengguna VB).

Saya akhirnya menemukan solusi saya di posting SO yang berbeda , dan itu sebenarnya sangat sederhana: Cukup tambahkan [FromUri]penjelasan sebelum parameter array di controller ( saya juga harus membuat panggilan menggunakan pengaturan AJAX "tradisional" untuk menghindari penjelasan braket ). Lihat di bawah untuk kode sebenarnya yang saya gunakan dalam aplikasi saya.


Tanda Tangan Pengontrol:

Tanda Tangan Pengontrol CATATAN: Anotasi di C # adalah [FromUri]


JavaScript:

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

String URL Sebenarnya:

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

Agak terlambat di sini, tetapi saya bisa menggunakan solusi SNag lebih jauh ke $ .ajax (). Inilah kodenya jika itu akan membantu siapa pun:

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
sumber
1

Jika Anda bermigrasi ke ASP.NET Core MVC dari .Net Framework MVC seperti saya, banyak hal telah berubah sedikit. Panggilan ajax harus berada pada objek mentah menggunakan stringify jadi daripada meneruskan datanya { vals: arrayOfValues }harus JSON.stringify(arrayOfValues)seperti berikut:

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

Perubahan lain yang telah dibuat di ASP.NET Core adalah untuk mencegah pemalsuan permintaan lintas situs sehingga untuk panggilan ke tindakan MVC dari metode ajax [FromBody]atribut harus diterapkan ke parameter tindakan sebagai berikut:

public ActionResult MyAction([FromBody] IEnumerable<int> arrayOfValues )
Michael Armitage
sumber
Terima kasih, ini sangat membantu setelah setiap permutasi cara lain untuk mengirim data gagal!
NibblyPig
0

Jika Anda menggunakan ASP.NET Core MVC dan perlu menangani tanda kurung siku (daripada menggunakan opsi "tradisional" jQuery), satu-satunya opsi yang saya temukan adalah secara manual membangun IEnumerabledalam metode contoller.

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

Saya bekerja dengan asp.net core 2.2 dan jquery dan harus mengirimkan objek kompleks ('kelas utama') dari pandangan ke pengontrol dengan bidang data sederhana dan beberapa larik.
Segera setelah saya menambahkan array dalam definisi c # 'kelas utama' (lihat di bawah) dan mengirimkan array (terisi dengan benar) melalui ajax (post), seluruh objek adalah null di controller.
Pertama, saya pikir, "tradisional: benar" yang hilang, pada panggilan ajax saya adalah alasannya, tetapi ini tidak terjadi.
Dalam kasus saya, alasannya adalah definisi di c # 'kelas utama'.
Di 'kelas utama', saya memiliki:

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

dan EreignisTagNeu didefinisikan sebagai:

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

Saya harus mengubah definisi di 'kelas utama' menjadi:

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

Sekarang berhasil.
Jadi ... bagi saya sepertinya inti asp.net memiliki masalah (dengan posting), jika daftar untuk array tidak sepenuhnya ditentukan di 'kelas utama'.
Catatan: Dalam kasus saya ini bekerja dengan atau tanpa "tradisional: true", ke panggilan ajax

FredyWenger
sumber
-3

Anda perlu mengubah Array menjadi string:

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

ini bekerja bahkan dalam bentuk int, long atau string

public ActionResult MyAction(int[] arrayOfValues )
dr. Crow
sumber
Ini bahkan bukan sintaks yang benar untuk mengirim array ke server. Anda hanya meneruskan sebuah objek dan menganggapnya sebagai sebuah larik, yang tidak akan pernah menjadi masalah dengan apa yang telah Anda berikan, yaitu STRING.
Twister1002