Come posso inviare un array di stringhe al controller MVC ASP.NET senza un modulo?


185

Sto creando una piccola app per insegnarmi ASP.NET MVC e JQuery e una delle pagine è un elenco di elementi in cui alcuni possono essere selezionati. Quindi vorrei premere un pulsante e inviare un Elenco (o qualcosa di equivalente) al mio controller contenente gli ID degli elementi che sono stati selezionati, usando la funzione Post di JQuery.

Sono riuscito a ottenere un array con gli ID degli elementi che sono stati selezionati, e ora voglio pubblicarlo. Un modo in cui ho potuto farlo è avere un modulo fittizio nella mia pagina, con un valore nascosto, quindi impostare il valore nascosto con gli elementi selezionati e pubblicare quel modulo; sembra però croccante.

Esiste un modo più pulito per raggiungere questo obiettivo, inviando l'array direttamente al controller? Ho provato alcune cose diverse ma sembra che il controller non sia in grado di mappare i dati che sta ricevendo. Ecco il codice finora:

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

E poi il mio controller appare così

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

Tutto quello che sono riuscito a ottenere è un "null" nel parametro controller ...

Qualche consiglio?


Tuttavia, è possibile accedere agli stessi dati utilizzandoRequest["values[]"]
Tocco il

Risposte:


247

Ho modificato la mia risposta per includere il codice per un'app di test che ho fatto.

Aggiornamento: ho aggiornato jQuery per impostare l'impostazione "tradizionale" su true, in modo che funzioni nuovamente (per la risposta di @DustinDavis).

Innanzitutto il 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
    });
}

Ed ecco il codice nella mia classe di controller:

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

Quando chiamo quella funzione javascript, ricevo un avviso che dice "Primo elemento nell'elenco: 'item1'". Spero che questo ti aiuti!


3
È bello che ho trovato questa risposta, ora sono in grado di inviare una serie di Guid e Action li riceve in List <Guid>. Grazie
Tx3

43
Ci sono due cose importanti da notare qui. 1) dataType: "json" 2.) Tradizionale: vero. Senza di essi l'array di stringhe non verrà passato ai metodi di azione
Thanigainathan,

1
Notare che dataType: 'JSON'fa sì che jQuery tenti di analizzare la risposta come JSON e genererà un errore se non è JSON valido.
Sennett,

8
@Thanigainathan dataType: 'json'è per il tipo restituito e non è necessario per inviare l'array ad Action. contentType: "application/json; charset=utf-8", è quello, ma in alcuni casi come questo non è richiesto.
Ruchan,

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

108

Cordiali saluti: JQuery ha cambiato il modo in cui serializzano i dati dei post.

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

Devi settare l'impostazione "Tradizionale" su vero, altro saggio

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

verrà fuori come

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

invece di

Values=1&Values=2&Values=3

8
Questo è qualcosa che mi ha fatto grattarmi la testa per un po '. l'impostazione $.ajax({ ..., traditional: true});aiuterà a ripristinare la serializzazione tradizionale.
juhan_h

Ne avevo bisogno perché una route ASP.NET MVC consumasse correttamente un semplice array js di valori stringa.
BrandonG

La tua risposta è davvero utile. Ho la stessa situazione ma è con ints. Quando uso traditional: true, funziona, la tua risposta e il tuo link spiegano il perché . Funziona anche quando uso type: "POST", senza usare traditional: true. Perché? Potresti per favore elaborare. Cordiali saluti, sto usando Asp.Net Mvc.
barnes,

Esiste un modo in ASP.NET per analizzare un array anonimo come questo senza indici? Valori [] = 1 e Valori [] = 2 e Valori [] = 3
Charles Owen,

24

Grazie a tutti per le risposte. Un'altra soluzione rapida sarà quella di utilizzare il metodo jQuery.param con il parametro tradizionale impostato su true per convertire l'oggetto JSON in stringa:

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

Funziona bene e si adatta perfettamente a me mentre sto usando $ .post () invece di $ .ajax (). Grazie !
AFract,


6

In .NET4.5,MVC 5

Javascript:

oggetto in JS: inserisci qui la descrizione dell'immagine

meccanismo che pubblica.

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

C #

Oggetti:

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

controller:

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

Oggetto ricevuto:

inserisci qui la descrizione dell'immagine

Spero che questo ti faccia risparmiare un po 'di tempo.


4

Un'altra implementazione che funziona anche con un elenco di oggetti, non solo stringhe:

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);
    }
});

Supponendo che 'selectedValues' sia Array of Objects.

Nel controller il parametro è un elenco di ViewModels corrispondenti.

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

1

Come ho discusso qui ,

se si desidera passare l'oggetto JSON personalizzato all'azione MVC, è possibile utilizzare questa soluzione, funziona come un incantesimo.

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

Il vero vantaggio di questa soluzione è che non è necessario definire una nuova classe per ogni combinazione di argomenti e, a parte ciò, è possibile trasmettere facilmente i propri oggetti ai loro tipi originali.

Puoi utilizzare un metodo di supporto come questo per facilitare il tuo lavoro:

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

È possibile impostare i parametri globali con

jQuery.ajaxSettings.traditional = true;

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.