11
votes

Comment passer un dictionnaire comme paramètre à une méthode ActionResulte de JQuery / Ajax?

J'utilise jQuery pour créer un appel Ajax à l'aide d'un message HTTP dans ASP.NET MVC. J'aimerais pouvoir passer un dictionnaire de valeurs.

La chose la plus proche que je puisse penser était de passer dans une gamme multidimensionnelle de chaînes, mais le résultat qui est réellement transmis à la méthode ActionResult est un dimension unique. Array de chaîne contenant une concaténation de chaîne de la paire "Key / Valeur". P>

Par exemple, le premier élément du tableau "Valeurs" ci-dessous contient la valeur ci-dessous: p>

values[0] = "id,200,300";
values[1] = "FirstName,Chris";


3 commentaires

Je ne pense pas qu'il y ait un moyen de faire ça. Je peux me tromper, mais il sera trivial d'analyser les données transmises dans une matrice de chaîne et créez-vous vous-même le dictionnaire à l'intérieur de la méthode Additems.


Je ne sais pas ce que les problèmes d'analyse seraient causés par les virgules dans les valeurs.


Enfin, je l'ai compris, merci à tous ceux qui ont fait des suggestions! J'ai ajouté ma solution finale comme une réponse ci-dessous. Je vais le marquer comme la bonne réponse dès que je me laisse. Merci tout le monde!


6 Réponses :


1
votes

Il est possible avec des liants de modèle personnalisés ou des filtres. Dans les coulisses - vous devrez le faire manuellement de toute façon (demande.form.form, analyses, créer du dictionnaire tralala), mais au moins - votre contrôleur sera propre et le code sera réutilisable pour une autre action.


0 commentaires

1
votes

Je ne pense pas qu'il soit possible de passer dans un dictionnaire de JQuery / Ajax à une méthode ActionResult via un poste HTTP. Une chose que j'ai imaginée qui semble être la plus facile à travailler consiste à passer dans un objet JSON, puis à analyser dans un dictionnaire.

Voici la version modifiée de l'appel ci-dessus "$ .post" de jQuery que Envoie JSON en tant que pseudo-dictionnaire: xxx

la fonction "sys.serialization.javascriptserializer.rialize" est une méthode de la bibliothèque ASP.NET AJAX JavaScript.

Voici la version modifiée de la méthode d'actionRésulte ci-dessus: xxx

Je pense que cela facilite le test de l'unité en passant à JSON, au lieu d'utiliser la collection de formulaires à envoyer / Récupérez la collection de paires de clés / de valeur. En outre, il est plus facile de travailler que de déterminer comment construire un imodelbinder personnalisé et une imodelbinder personnalisée peut causer des problèmes avec d'autres méthodes d'actionRésults lorsque c'est le seul que je dois faire cela.


1 commentaires

Chris, vois mon commentaire ci-dessus. Je pense toujours que vous allez à ce sujet la dure. Je ne suis pas sûr à 100% mais j'ai ce sentiment de nigging que vous êtes.



0
votes

DefaultModelbinder est capable de lier votre message au tableau ou au dictionnaire. Par exemple:

pour les tableaux: p> xxx pré>

ou: p> xxx pré>

pour les dictionnaires: p>

var postData = $('input#id1, input#id2, ..., input#idN").serialize();
// or
var postData = $('input.classOfYourInputs").serialize();

$.post("/Controller/AddItems", { values: postData }, function(data) { }, "json");


2 commentaires

J'ai essayé votre exemple de dictionnaire, mais cela ne finit pas de remplir le paramètre "valeurs"; Il finit juste être un dictionnaire vide.


Avez-vous essayé dictionnaire valeurs plutôt dictionnaire . Vérifiez également si votre index de valeurs [n] est à base de zéro et ininterrompue. Vérifiez Stackoverflow.com/questions/1031416/... aussi



10
votes

enfin, je l'ai compris !! Merci à tous pour les suggestions! J'ai finalement compris que la meilleure solution consiste à transmettre JSON via le poteau HTTP et à utiliser un modèle de modèle personnalisé pour convertir le JSON en un dictionnaire. Une chose que j'ai faite dans ma solution est créée un objet djondictionnel qui hérite d'un dictionnaire afin de pouvoir joindre le modèle de modèle personnalisé au type Jsondictionner, et il ne provoquera pas de conflit à l'avenir si j'utilise le dictionnaire comme paramètre d'actionResult ultérieurement pour un Objet différent de JSON.

Voici la méthode finale d'actionResulte: p> xxx pré>

et la jQuery "$ .post" appelez: p>

public class JsonDictionary : Dictionary<string, object>
{
    public JsonDictionary() { }

    public void Add(JsonDictionary jsonDictionary)
    {
        if (jsonDictionary != null)
        {
            foreach (var k in jsonDictionary.Keys)
            {
                this.Add(k, jsonDictionary[k]);
            }
        }
    }
}

public class JsonDictionaryModelBinder : IModelBinder
{
    #region IModelBinder Members

    public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
    {
        if (bindingContext.Model == null) { bindingContext.Model = new JsonDictionary(); }
        var model = bindingContext.Model as JsonDictionary;

        if (bindingContext.ModelType == typeof(JsonDictionary))
        {
            // Deserialize each form/querystring item specified in the "includeProperties"
            // parameter that was passed to the "UpdateModel" method call

            // Check/Add Form Collection
            this.addRequestValues(
                model,
                controllerContext.RequestContext.HttpContext.Request.Form,
                controllerContext, bindingContext);

            // Check/Add QueryString Collection
            this.addRequestValues(
                model,
                controllerContext.RequestContext.HttpContext.Request.QueryString,
                controllerContext, bindingContext);
        }

        return model;
    }

    #endregion

    private void addRequestValues(JsonDictionary model, NameValueCollection nameValueCollection, ControllerContext controllerContext, ModelBindingContext bindingContext)
    {
        foreach (string key in nameValueCollection.Keys)
        {
            if (bindingContext.PropertyFilter(key))
            {
                var jsonText = nameValueCollection[key];
                var newModel = deserializeJson(jsonText);
                // Add the new JSON key/value pairs to the Model
                model.Add(newModel);
            }
        }
    }

    private JsonDictionary deserializeJson(string json)
    {
        // Must Reference "System.Web.Extensions" in order to use the JavaScriptSerializer
        var serializer = new System.Web.Script.Serialization.JavaScriptSerializer();
        return serializer.Deserialize<JsonDictionary>(json);
    }
}


0 commentaires

0
votes

C'est un ancien poste mais je ne peux pas m'empêcher de quelques remarques de toute façon.

@ EU-GE-NE: "DefaultModelbinder est capable de lier votre message au tableau ou au dictionnaire." Vrai mais au moins pour les dictionnaires, je trouve la notation de formulaire requise plutôt contre-intuitive.

@chris: hier, j'avais exactement le même problème tout en essayant de poster un dictionnaire JavaScript (JSON) à une méthode d'action du contrôleur. J'ai élaboré un classeur de modèle personnalisé totalement différent qui traite des dictionnaires génériques avec des arguments de type différents. Je l'ai seulement testé en MVC 3 et a probablement eu l'avantage d'un cadre amélioré.

Pour les détails de mes expériences et du code source du classeur de modèle personnalisé, veuillez consulter mon article de blog sur http://buildingwebapps.blogspot.com/2012/01/passing-javascript-json-dictionary-a.html


0 commentaires

4
votes

C'est ce que j'ai essayé. Économise beaucoup de travail. JavaScript: xxx pré>

Méthode d'action: p>

public ActionResult MethodName(DictionaryModel obj)
    {
       //Action method logic
    }

public class DictionaryModel
{
    public Dictionary<string, string> dict { get; set; }

}


1 commentaires

Pas exactement ce que je voulais, car il n'ya pas de point de passer un objet, si vous pouviez simplement passer le dictionnaire lui-même, mais cela fonctionne assez bien. Upvoted. :)