Je crée une petite application pour m'apprendre à utiliser ASP.NET MVC et JQuery, et l'une des pages contient une liste d'éléments dans lesquels certains peuvent être sélectionnés. Ensuite, j'aimerais appuyer sur un bouton et envoyer à mon contrôleur une liste (ou quelque chose d'équivalent) contenant les identifiants des éléments sélectionnés à l'aide de la fonction Post de JQuery.
J'ai réussi à obtenir un tableau avec les identifiants des éléments sélectionnés, et maintenant je veux le poster. Une façon de le faire est d’avoir un formulaire factice dans ma page, avec une valeur cachée, puis de définir la valeur cachée avec les éléments sélectionnés et d’envoyer ce formulaire; cela a l'air cruel, cependant.
Existe-t-il un moyen plus simple d’atteindre cet objectif en envoyant la matrice directement au contrôleur? J'ai essayé différentes choses, mais il semble que le contrôleur ne puisse pas mapper les données qu'il reçoit. Voici le code jusqu'à présent:
function generateList(selectedValues) {
var s = {
values: selectedValues //selectedValues is an array of string
};
$.post("/Home/GenerateList", $.toJSON(s), function() { alert("back") }, "json");
}
Et puis mon contrôleur ressemble à ceci
public ActionResult GenerateList(List<string> values)
{
//do something
}
Tout ce que j'ai réussi à obtenir est un "null" dans le paramètre du contrôleur ...
Des conseils?
J'ai modifié ma réponse pour inclure le code d'une application test que j'ai créée.
Mise à jour: jQuery a été mis à jour pour définir le paramètre "traditionnel" sur true afin que cela fonctionne à nouveau (selon la réponse de @DustinDavis).
D'abord le 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
});
}
Et voici le code dans ma classe de contrôleur:
public JsonResult SaveList(List<String> values)
{
return Json(new { Result = String.Format("Fist item in list: '{0}'", values[0]) });
}
Lorsque j'appelle cette fonction javascript, je reçois une alerte disant "Premier élément de la liste:" élément1 "". J'espère que cela t'aides!
FYI: JQuery a changé la façon dont ils sérialisent les données de publication.
http://forum.jquery.com/topic/nested-param-serialization
Vous devez définir le paramètre "Traditionnel" sur true, sinon
{ Values : ["1", "2", "3"] }
sortira comme
Values[]=1&Values[]=2&Values[]=3
au lieu de
Values=1&Values=2&Values=3
Merci à tous pour les réponses. Une autre solution rapide consiste à utiliser la méthode jQuery.param avec le paramètre traditionnel défini sur true pour convertir un objet JSON en chaîne:
$.post("/your/url", $.param(yourJsonObject,true));
Ne postez pas les données sous forme de tableau. Pour se lier à une liste, les paires clé/valeur doivent être soumises avec la même valeur pour chaque clé.
Vous ne devriez pas avoir besoin d'un formulaire pour le faire. Vous avez juste besoin d'une liste de paires clé/valeur, que vous pouvez inclure dans l'appel à $ .post.
Dans .NET4.5
, MVC 5
Javascript:
objet dans JS:
mécanisme qui poste.
$('.button-green-large').click(function() {
$.ajax({
url: 'Quote',
type: "POST",
dataType: "json",
data: JSON.stringify(document.selectedProduct),
contentType: 'application/json; charset=utf-8',
});
});
C #
Objets:
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; }
}
Manette:
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Quote(WillsQuoteViewModel data)
{
....
}
Objet reçu:
J'espère que cela vous fait gagner du temps.
Une autre implémentation qui fonctionne également avec une liste d'objets, pas seulement des chaînes:
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);
}
});
En supposant que 'selectedValues' est un tableau d'objets.
Dans le contrôleur, le paramètre est une liste des ViewModels correspondants.
public JsonResult SaveList(List<ViewModel> values)
{
return Json(new {
Result = String.Format("Fist item in list: '{0}'", values[0].Name)
});
}
Comme j'ai discuté ici ,
si vous souhaitez passer d'un objet JSON personnalisé à une action MVC, vous pouvez utiliser cette solution, elle fonctionne comme un charme.
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;
}
L'avantage réel de cette solution est que vous n'avez pas besoin de définir une nouvelle classe pour chaque combinaison d'arguments. De plus, vous pouvez facilement convertir les objets en leurs types d'origine.
et vous pouvez utiliser une méthode d'assistance comme celle-ci pour faciliter votre travail
public static Dictionary<string, dynamic> GetDic(HttpRequestBase request)
{
String jsonString = new StreamReader(request.InputStream).ReadToEnd();
return Newtonsoft.Json.JsonConvert.DeserializeObject<Dictionary<string, dynamic>>(jsonString);
}
Vous pouvez configurer un paramètre global avec
jQuery.ajaxSettings.traditional = true;