AJAX aracılığıyla diziyi mvc Action'a geçirme


124

AJAX üzerinden bir MVC eylemine bir dizi (veya IEnumerable) girmeye çalışıyorum ve biraz yardıma ihtiyacım var.

javascript

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

ve denetleyici eylemi

public ActionResult MyAction(IEnumerable<int> arrayOfValues )

Şu anda istek şu şekilde biçimlendirilmiştir:

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

Yani neredeyse oradayım, köşeli parantezleri kaldırırsam doğru yanıtı alıyorum. Denetleyicinin ne olduğunu anlayabilmesi için bu diziyi get'ime nasıl geçirmeliyim?

Yardımın için çok teşekkürler

Dave

Yanıtlar:


149

Get call yapmadan önce geleneksel özelliği true olarak ayarlayın. yani:

jQuery.ajaxSettings.traditional = true

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

3
teşekkür ederim! geleneksel ve geleneksel olmayan ajax arasındaki farkları özetleyebilir misiniz? Başvurumun geri kalanında ne yaptığımı daha iyi anlamak istiyorum.
Tom Beech

5
ayrıca geleneksel ayarı tek bir aramaya da ekleyebilirsiniz. O zaman geri kalanı etkilemeyecek
Gluip

1
Bu cevap doğrudur, ancak tek bir arama için "geleneksel" ayarlamayı tercih ediyorsanız @RionWilliams cevabını kontrol edin. İkisine de oy veriyor. Teşekkürler!
kzfabi

@Tom Beech jQuery 1.4'ten itibaren, $ .param () yöntemi, PHP ve Ruby on Rails gibi modern betik dilleri ve çerçevelerini barındırmak için derin nesneleri özyinelemeli olarak serileştirir. JQuery.ajaxSettings.traditional = true; ayarlayarak bu işlevi genel olarak devre dışı bırakabilirsiniz.
Alexey Shevelyov

Bu yanıtların hiçbiri benim için işe yaramadı (belki de denetleyicim bir API denetleyicisi olduğu için?), Ancak çözümümü şu SO yanıtında buldum: stackoverflow.com/a/11100414/1751792
Lopsided

119

Geçmişte bir POST gerçekleştirmeye çalışırken sorunlar yaşadım (tam olarak yaptığınızdan emin değilim, ancak bir dizi geçirirken hatırlıyorum, geleneksel doğru olarak ayarlanmalıdır .

 var arrayOfValues = new Array();

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

4
Bu, bazılarının önerdiği gibi, bir web.config dosyasında körü körüne global olarak ayarlamaktan çok daha iyidir. Diğerinin kendi iyi günleri vardır, ancak sizinki varsayılan çözüm olmalıdır.
Panzercrisis

Bu sadece ActionResult'a parametre olarak veri gönderiyor, ActionResult Inside kodunu çağıracak mı? Örneğin, veritabanına arrayofvalues ​​eklemek için bazı kodlar varsa, bu kod çalışır mı?
Saurabh

Bu tam olarak ihtiyacım olan şeyi çözdü. Dizilerim, bunu ekleyip denetleyicime şu şekilde gelene kadar denetleyicimde boş olarak geri gelmeye devam etti: IEnumerable <string> dizisi
SeanMC

52

Oldukça geç ama farklı burada zaten mevcut olanlara cevap:

Bunun yerine $.ajaxstenografi işlevlerini kullanmak isterseniz $.getveya $.postdizileri şu şekilde geçirebilirsiniz:


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
}

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


Notlar:

  • Boolean parametre $.paramiçindir traditionalözelliği, OLMALIDIR trueişe bunun için .

2
Geleneksel mülkle ilgili ipucu için teşekkürler. C # parametimin neden boş olduğunu anlayamadım. "İnt []" türünün C # Action yönteminde de çalışacağını buldum.
Dan Randolph

9

Bunu gayet iyi yapabilmelisin:

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

O zaman eylem yönteminiz şöyle olacaktır:

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

Sizin için, sadece değerlerinizi belirlemeniz gerekiyor gibi görünüyor. MVC'deki JSONValueProvider, bunu sizin için bir IEnumerable'a dönüştürecektir.


Cevabınız için teşekkürler ama sanırım geleneksel olanı doğruya ayarlamam gerekiyor gibi görünüyor. Bunun da işe yarayacağını düşündüğüm için oy verdim.
Dave

9

'Geleneksel' seçeneği kullanmanın cevabı doğrudur. Daha fazlasını öğrenmek isteyenler için biraz daha arka plan bilgisi veriyorum.

JQuery belgelerinden:

JQuery 1.8'den itibaren, $ .param () yöntemi artık jQuery.ajaxSettings.traditional'ı varsayılan ayarı olarak kullanmamaktadır ve varsayılan ayar olarak false olacaktır.

Ayrıca buradan daha fazla bilgi edinebilirsiniz: http://michaelsync.net/2012/04/05/tips-asp-net-mvc-javascriptserializer-3-questions-and-3-answers ve http://haacked.com/archive /2008/10/23/model-binding-to-a-list.aspx

HTH


2

EĞER HEPSİ HATAYSA...

Buradaki diğer cevapların hiçbiri sorunumu çözmedi. JavaScript'ten bir MVC Web API denetleyicisine bir GET yöntemi çağrısı yapmaya ve bu istek içinde bir parametre olarak bir tamsayı dizisi göndermeye çalışıyordum. Buradaki tüm çözümleri denedim, ancak yine de denetleyicimdeki parametre NULL geliyordu (veya siz VB kullanıcıları için hiçbir şey).

Sonunda çözümümü farklı bir SO gönderisinde buldum ve gerçekten çok basitti: [FromUri]Ek açıklamayı denetleyicideki dizi parametresinden önce eklemeniz yeterli ( ayrıca parantez açıklamalarını önlemek için çağrıyı "geleneksel" AJAX ayarını kullanarak yapmak zorunda kaldım ). Başvurumda kullandığım gerçek kod için aşağıya bakın.


Denetleyici İmzası:

Denetleyici İmzası NOT: C # 'daki ek açıklama [FromUri]


JavaScript:

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

Gerçek URL Dizesi:

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

2

Burada biraz geç, ancak SNag'ın çözümünü $ .ajax () için kullanabilirim. Kimseye yardımcı olacaksa kod şu:

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

NET Framework MVC'den ASP.NET Core MVC'ye geçiş yapıyorsanız benim gibi işler biraz değişti. Ajax çağrısı, stringify kullanılarak ham nesne üzerinde olmalıdır, bu nedenle { vals: arrayOfValues }onun verilerini iletmek yerine JSON.stringify(arrayOfValues)aşağıdaki gibi olmalıdır :

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

ASP.NET Core'da yapılan diğer değişiklik, siteler arası istek sahteciliğini önlemektir, bu nedenle bir ajax yönteminden bir MVC eylemine yapılan çağrılar için [FromBody]atribute, eylem parametresine aşağıdaki gibi uygulanmalıdır:

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

Teşekkür ederiz, bu, verileri göndermenin diğer tüm yolları permütasyonu başarısız olduktan sonra inanılmaz derecede yardımcı oldu!
NibblyPig

0

ASP.NET Core MVC kullanıyorsanız ve köşeli parantezleri işlemeniz gerekiyorsa (jQuery "geleneksel" seçeneğini kullanmak yerine), bulduğum tek seçenek kontrol IEnumerableyönteminde manuel olarak oluşturmaktır .

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

0

Birlikte çalışan asp.net çekirdek 2.2 ve jquery ve basit veri alanları ve bir dizi en olan bir denetleyiciye bir görünümden kompleks nesnesi ( 'ana sınıfı') göndermek zorunda.
Diziyi c # 'ana sınıf' tanımına eklediğimde (aşağıya bakın) ve ajax (post) üzerinden (doğru doldurulmuş) diziyi gönderdikten sonra, tüm nesne denetleyicide boştu.
İlk olarak, ajax çağrımın eksik "geleneksel: doğru" olmasının nedeni olduğunu düşündüm, ama durum bu değil.
Benim durumumda neden c # 'ana sınıf' tanımıydı.
'Ana sınıfta' şunlara sahiptim:

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

ve EreignisTagNeu şu şekilde tanımlandı:

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

'Ana sınıftaki' tanımı şu şekilde değiştirmem gerekti:

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

Şimdi çalışıyor.
Yani ... benim için asp.net çekirdeğinin bir sorunu var gibi görünüyor (postayla ilgili), eğer bir dizinin listesi tamamen 'ana sınıfta' tanımlanmamışsa.
Not: Benim durumumda bu, ajax çağrısı için "geleneksel: doğru" ile veya olmadan çalışır


-3

Diziyi dizeye dönüştürmeniz gerekir:

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

bu int, long veya string biçiminde bile çalışır

public ActionResult MyAction(int[] arrayOfValues )

Bu, sunucuya bir dizi göndermek için doğru sözdizimi bile değildir. Sadece bir nesneyi iletiyorsunuz ve bunun bir dizi olduğunu varsayıyorsunuz, bu hiçbir zaman sağladığınız şeyle durum olmayacak, ki bu bir STRING.
Twister1002
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.