ASP.NET MVC Denetleyicisine bir dize dizisini form olmadan nasıl gönderebilirim?


185

Kendime ASP.NET MVC ve JQuery öğretmek için küçük bir uygulama oluşturuyorum ve sayfalardan biri bazı seçilebilir öğeleri bir listesidir. Sonra bir düğmeye basın ve denetleyicime JQuery'nin Post işlevini kullanarak seçilen öğelerin kimliklerini içeren bir Liste (veya eşdeğer bir şey) göndermek istiyorum.

Seçilen öğelerin kimlikleriyle bir dizi almayı başardım ve şimdi bunu göndermek istiyorum. Bunu yapabilmemin bir yolu, sayfamda gizli bir değere sahip bir kukla formun bulunması ve ardından seçilen öğelerle gizli değeri ayarlayıp bu formu yayınlamaktır; bu acımasız görünüyor.

Diziyi doğrudan denetleyiciye göndererek bunu başarmanın daha temiz bir yolu var mı? Birkaç farklı şey denedim, ancak denetleyici aldığı verileri haritalayamıyor gibi görünüyor. İşte şimdiye kadar kod:

function generateList(selectedValues) {
   var s = {
      values: selectedValues //selectedValues is an array of string
   };
   $.post("/Home/GenerateList", $.toJSON(s), function() { alert("back") }, "json");
}

Ve sonra Denetleyicim şöyle görünüyor

public ActionResult GenerateList(List<string> values)
{
    //do something
}

Almayı başarabildiğim tek şey denetleyici parametresinde "null" ...

Herhangi bir ipucu?


Her ne kadar aynı verilere erişebilirsinizRequest["values[]"]
Tocco

Yanıtlar:


247

Yanıtımı, yaptığım bir test uygulamasının kodunu içerecek şekilde değiştirdim.

Güncelleme: jQuery 'geleneksel' ayarını true olarak ayarlamak için güncelledim, böylece bu tekrar çalışacak (@DustinDavis 'cevabına göre).

Önce javascript:

function test()
{
    var stringArray = new Array();
    stringArray[0] = "item1";
    stringArray[1] = "item2";
    stringArray[2] = "item3";
    var postData = { values: stringArray };

    $.ajax({
        type: "POST",
        url: "/Home/SaveList",
        data: postData,
        success: function(data){
            alert(data.Result);
        },
        dataType: "json",
        traditional: true
    });
}

Ve işte benim denetleyici sınıfımdaki kod:

public JsonResult SaveList(List<String> values)
{
    return Json(new { Result = String.Format("Fist item in list: '{0}'", values[0]) });
}

Bu javascript işlevini çağırdığımda, "Listedeki ilk öğe: 'item1'" uyarısı alıyorum. Bu yardımcı olur umarım!


3
Bu cevabı bulduğum iyi, şimdi bir dizi Guid gönderebilirim ve Action onları <Guid> Listesine alır. Teşekkürler
Tx3

43
Burada dikkat edilmesi gereken iki önemli nokta var. 1) dataType: "json" 2.) geleneksel: gerçek. Onlar olmadan dize dizi eylem yöntemlerine
geçmeyecek

1
dataType: 'JSON'JQuery'nin yanıtı JSON olarak ayrıştırma girişimine neden olduğunu ve geçerli JSON değilse hata vereceğini unutmayın.
sennett

8
@Thanigainathan dataType: 'json'dönüş türü içindir ve Eylem'e dizi göndermek için gerekli değildir. contentType: "application/json; charset=utf-8", ancak bu gibi bazı durumlarda gerekli değildir.
Ruchan

1
@emzero kullanımıvar postData = { id: 45, [{myClassProp1: 1, myClassProp2: 2}, {}...], anotherParam: "some string" };
Nick M

108

Bilginize: JQuery yayın verilerini serileştirme yöntemini değiştirdi.

http://forum.jquery.com/topic/nested-param-serialization

'Geleneksel' ayarını doğru, diğer akıllıca ayarlamanız gerekir.

{ Values : ["1", "2", "3"] }

olarak çıkacak

Values[]=1&Values[]=2&Values[]=3

onun yerine

Values=1&Values=2&Values=3

8
Bu bir süredir kafamı kazımamı sağlayan bir şey. ayarı $.ajax({ ..., traditional: true});geleneksel serileştirmeye geri dönmenize yardımcı olacaktır.
juhan_h

ASP.NET MVC yolu düzgün dize değerleri basit bir js dizi tüketmek için bu gerekli.
BrandonG

Cevabınız gerçekten faydalı. Bende aynı durum var ama öyle ints. Kullandığımda traditional: trueişe yarıyor, cevabınız ve bağlantınız bunun nedenini açıklıyor . Ayrıca kullandığımda type: "POST", kullanmadan da çalışır traditional: true. Neden? Lütfen biraz açar mısınız? FYI Asp.Net Mvc kullanıyorum.
barnes

ASP.NET'te bu tür anonim bir dizini dizinler olmadan ayrıştırmanın bir yolu var mı? Değerler [] = 1 ve Değerler [] = 2 ve Değerler [] = 3
Charles Owen

24

Cevaplar için herkese teşekkürler. Başka bir hızlı çözüm, JSON nesnesini dizeye dönüştürmek için geleneksel parametre true olarak ayarlanmış jQuery.param yöntemini kullanmak olacaktır :

$.post("/your/url", $.param(yourJsonObject,true));

$ .Ajax () yerine $ .post () kullandığım için iyi ve mükemmel bir şekilde benim için çalışıyor. Teşekkür ederim !
AFract


6

İçinde .NET4.5,MVC 5

JavaScript:

JS'deki nesne: resim açıklamasını buraya girin

sonrası mekanizması.

    $('.button-green-large').click(function() {
        $.ajax({
            url: 'Quote',
            type: "POST",
            dataType: "json",
            data: JSON.stringify(document.selectedProduct),
            contentType: 'application/json; charset=utf-8',
        });
    });

C #

Nesneler:

public class WillsQuoteViewModel
{
    public string Product { get; set; }

    public List<ClaimedFee> ClaimedFees { get; set; }
}

public partial class ClaimedFee //Generated by EF6
{
    public long Id { get; set; }
    public long JourneyId { get; set; }
    public string Title { get; set; }
    public decimal Net { get; set; }
    public decimal Vat { get; set; }
    public string Type { get; set; }

    public virtual Journey Journey { get; set; }
}

Denetleyici:

[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Quote(WillsQuoteViewModel data)
{
....
}

Alınan nesne:

resim açıklamasını buraya girin

Umarım bu size biraz zaman kazandırır.


4

Yalnızca dizelerle değil, nesne listesiyle de çalışan başka bir uygulama:

JS:

var postData = {};
postData[values] = selectedValues ;

$.ajax({
    url: "/Home/SaveList",
    type: "POST",
    data: JSON.stringify(postData),
    dataType: "json",
    contentType: "application/json; charset=utf-8",
    success: function(data){
        alert(data.Result);
    }
});

'SeçiliDeğerler' öğesinin Nesne Dizisi olduğunu varsayarsak.

Denetleyicide parametre karşılık gelen ViewModels listesidir.

public JsonResult SaveList(List<ViewModel> values)
{    
    return Json(new { 
          Result = String.Format("Fist item in list: '{0}'", values[0].Name) 
    });
}

1

Ben bahsedildiği gibi burada ,

MVC eylemine özel JSON nesnesini geçmek istiyorsanız, bu çözümü kullanabilirsiniz, bir cazibe gibi çalışır.

public string GetData() {
  // InputStream contains the JSON object you've sent
  String jsonString = new StreamReader(this.Request.InputStream).ReadToEnd();

  // Deserialize it to a dictionary
  var dic =
    Newtonsoft.Json.JsonConvert.DeserializeObject < Dictionary < String,
    dynamic >> (jsonString);

  string result = "";

  result += dic["firstname"] + dic["lastname"];

  // You can even cast your object to their original type because of 'dynamic' keyword
  result += ", Age: " + (int) dic["age"];

  if ((bool) dic["married"])
    result += ", Married";

  return result;
}

Bu çözümün gerçek yararı, her bir argüman kombinasyonu için yeni bir sınıf tanımlamanız gerekmemesidir ve bunun yanında, nesnelerinizi orijinal türlerine kolayca aktarabilirsiniz.

İşinizi kolaylaştırmak için böyle bir yardımcı yöntem kullanabilirsiniz:

public static Dictionary < string, dynamic > GetDic(HttpRequestBase request) {
  String jsonString = new StreamReader(request.InputStream).ReadToEnd();
  return Newtonsoft.Json.JsonConvert.DeserializeObject < Dictionary < string, dynamic >> (jsonString);
}

0

Global parametresini

jQuery.ajaxSettings.traditional = true;

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.