Question Comment puis-je désérialiser JSON en un simple Dictionary dans ASP.NET?


J'ai une simple liste clé / valeur dans JSON renvoyé à ASP.NET via POST. Exemple:

{ "key1": "value1", "key2": "value2"}

JE NE ESSAYE PAS DE DESERIALISER EN OBJETS .NET FORTEMENT TYPÉS

J'ai simplement besoin d'un vieux Dictionary (Of String, String), ou un équivalent (table de hachage, Dictionary (Of String, Object), StringDictionary old-school - hell, un tableau de chaînes à deux dimensions travaillerait pour moi.

Je peux utiliser tout ce qui est disponible dans ASP.NET 3.5, ainsi que le populaire Json.NET (que j'utilise déjà pour la sérialisation à le client).

Apparemment, ni l'une ni l'autre de ces librairies JSON n'ont cette capacité évidente d'avant-garde, elles sont entièrement axées sur la désérialisation basée sur la réflexion via des contrats solides.

Des idées?

Limites:

  1. Je ne veux pas implémenter mon propre analyseur JSON
  2. Impossible d'utiliser ASP.NET 4.0 pour le moment
  3. Je préférerais rester loin de l'ancienne classe ASP.NET obsolète pour JSON

557
2017-07-30 16:28


origine


Réponses:


Json.NET fait cela ...

string json = @"{""key1"":""value1"",""key2"":""value2""}";

var values = JsonConvert.DeserializeObject<Dictionary<string, string>>(json);

Plus d'exemples: Sérialisation des collections avec Json.NET


734
2017-07-31 11:51



J'ai découvert. NET a construit un moyen de lancer la chaîne JSON dans un Dictionary<String, Object> via le System.Web.Script.Serialization.JavaScriptSerializer tapez dans le 3.5 System.Web.Extensions Assemblée. Utilisez la méthode DeserializeObject(String).

Je suis tombé sur cela quand faire un post ajax (via jquery) du type de contenu 'application / json' à une méthode .net page statique et vu que la méthode (qui avait un seul paramètre de type Object) a reçu ce dictionnaire par magie.


93
2018-01-29 01:54



Pour ceux qui recherchent sur Internet et trébucher sur ce post, j'ai écrit un billet de blog sur la façon d'utiliser la classe JavaScriptSerializer.

Lire la suite... http://procbits.com/2011/04/21/quick-json-serializationdeserialization-in-c/

Voici un exemple:

var json = "{\"id\":\"13\", \"value\": true}";
var jss = new JavaScriptSerializer();
var table = jss.Deserialize<dynamic>(json);
Console.WriteLine(table["id"]);
Console.WriteLine(table["value"]);

49
2018-04-21 18:41



J'ai essayé de ne pas utiliser d'implémentation JSON externe, donc j'ai désérialisé comme ceci:

string json = "{\"id\":\"13\", \"value\": true}";

var serializer = new JavaScriptSerializer(); //using System.Web.Script.Serialization;

Dictionary<string, string> values = serializer.Deserialize<Dictionary<string, string>>(json);

38
2018-01-12 10:51



J'ai eu le même problème, alors je l'ai écrit moi-même. Cette solution se différencie des autres réponses car elle peut se désérialiser à plusieurs niveaux.

Envoyez simplement une chaîne JSON à désérialiserToDictionary fonction, il retournera non fortement typé Dictionary<string, object> objet.

Ancien code

private Dictionary<string, object> deserializeToDictionary(string jo)
{
    var values = JsonConvert.DeserializeObject<Dictionary<string, object>>(jo);
    var values2 = new Dictionary<string, object>();
    foreach (KeyValuePair<string, object> d in values)
    {
        // if (d.Value.GetType().FullName.Contains("Newtonsoft.Json.Linq.JObject"))
        if (d.Value is JObject)
        {
            values2.Add(d.Key, deserializeToDictionary(d.Value.ToString()));
        }
        else
        {
            values2.Add(d.Key, d.Value);
        }
    }
    return values2;
}

Ex: Cela reviendra Dictionary<string, object> objet d'une réponse Facebook JSON.

Tester

private void button1_Click(object sender, EventArgs e)
{
    string responsestring = "{\"id\":\"721055828\",\"name\":\"Dasun Sameera Weerasinghe\",\"first_name\":\"Dasun\",\"middle_name\":\"Sameera\",\"last_name\":\"Weerasinghe\",\"username\":\"dasun\",\"gender\":\"male\",\"locale\":\"en_US\",  hometown: {id: \"108388329191258\", name: \"Moratuwa, Sri Lanka\",}}";
    Dictionary<string, object> values = deserializeToDictionary(responsestring);
}

Remarque: ville natale plus désertifier dans un Dictionary<string, object>   objet.

Mettre à jour

Ma vieille réponse fonctionne bien s'il n'y a pas de tableau sur une chaîne JSON. Celui-ci déserialise en plus dans un List<object> si un élément est un tableau.

Il suffit d'envoyer une chaîne JSON à deserializeToDictionaryOrList fonction, il retournera non fortement typé Dictionary<string, object> objet ou List<object>.

private static object deserializeToDictionaryOrList(string jo,bool isArray=false)
{
    if (!isArray)
    {
        isArray = jo.Substring(0, 1) == "[";
    }
    if (!isArray)
    {
        var values = JsonConvert.DeserializeObject<Dictionary<string, object>>(jo);
        var values2 = new Dictionary<string, object>();
        foreach (KeyValuePair<string, object> d in values)
        {
            if (d.Value is JObject)
            {
                values2.Add(d.Key, deserializeToDictionary(d.Value.ToString()));
            }
            else if (d.Value is JArray)
            {
                values2.Add(d.Key, deserializeToDictionary(d.Value.ToString(), true));
            }
            else
            {
                values2.Add(d.Key, d.Value);
            }
        }
        return values2;
    }else
    {
        var values = JsonConvert.DeserializeObject<List<object>>(jo);
        var values2 = new List<object>();
        foreach (var d in values)
        {
            if (d is JObject)
            {
                values2.Add(deserializeToDictionary(d.ToString()));
            }
            else if (d is JArray)
            {
                values2.Add(deserializeToDictionary(d.ToString(), true));
            }
            else
            {
                values2.Add(d);
            }
        }
        return values2;
    }
}

28
2017-07-25 11:19



Si vous recherchez une approche légère, sans aucune référence, peut-être que ce code que je viens d'écrire fonctionnera (je ne peux pas garantir la robustesse à 100%).

using System;
using System.Collections.Generic;
using System.Text;
using System.Text.RegularExpressions;

public Dictionary<string, object> ParseJSON(string json)
{
    int end;
    return ParseJSON(json, 0, out end);
}
private Dictionary<string, object> ParseJSON(string json, int start, out int end)
{
    Dictionary<string, object> dict = new Dictionary<string, object>();
    bool escbegin = false;
    bool escend = false;
    bool inquotes = false;
    string key = null;
    int cend;
    StringBuilder sb = new StringBuilder();
    Dictionary<string, object> child = null;
    List<object> arraylist = null;
    Regex regex = new Regex(@"\\u([0-9a-z]{4})", RegexOptions.IgnoreCase);
    int autoKey = 0;
    for (int i = start; i < json.Length; i++)
    {
        char c = json[i];
        if (c == '\\') escbegin = !escbegin;
        if (!escbegin)
        {
            if (c == '"')
            {
                inquotes = !inquotes;
                if (!inquotes && arraylist != null)
                {
                    arraylist.Add(DecodeString(regex, sb.ToString()));
                    sb.Length = 0;
                }
                continue;
            }
            if (!inquotes)
            {
                switch (c)
                {
                    case '{':
                        if (i != start)
                        {
                            child = ParseJSON(json, i, out cend);
                            if (arraylist != null) arraylist.Add(child);
                            else
                            {
                                dict.Add(key, child);
                                key = null;
                            }
                            i = cend;
                        }
                        continue;
                    case '}':
                        end = i;
                        if (key != null)
                        {
                            if (arraylist != null) dict.Add(key, arraylist);
                            else dict.Add(key, DecodeString(regex, sb.ToString()));
                        }
                        return dict;
                    case '[':
                        arraylist = new List<object>();
                        continue;
                    case ']':
                        if (key == null)
                        {
                            key = "array" + autoKey.ToString();
                            autoKey++;
                        }
                        if (arraylist != null && sb.Length > 0)
                        {
                            arraylist.Add(sb.ToString());
                            sb.Length = 0;
                        }
                        dict.Add(key, arraylist);
                        arraylist = null;
                        key = null;
                        continue;
                    case ',':
                        if (arraylist == null && key != null)
                        {
                            dict.Add(key, DecodeString(regex, sb.ToString()));
                            key = null;
                            sb.Length = 0;
                        }
                        if (arraylist != null && sb.Length > 0)
                        {
                            arraylist.Add(sb.ToString());
                            sb.Length = 0;
                        }
                       continue;
                    case ':':
                        key = DecodeString(regex, sb.ToString());
                        sb.Length = 0;
                        continue;
                }
            }
        }
        sb.Append(c);
        if (escend) escbegin = false;
        if (escbegin) escend = true;
        else escend = false;
    }
    end = json.Length - 1;
    return dict; //theoretically shouldn't ever get here
}
private string DecodeString(Regex regex, string str)
{
    return Regex.Unescape(regex.Replace(str, match => char.ConvertFromUtf32(Int32.Parse(match.Groups[1].Value, System.Globalization.NumberStyles.HexNumber))));
}

[Je me rends compte que cela viole la limitation OP # 1, mais techniquement, vous ne l'avez pas écrit, je l'ai fait]


16
2017-11-02 09:26



J'avais juste besoin d'analyser imbriqué dictionnaire, comme

{
    "x": {
        "a": 1,
        "b": 2,
        "c": 3
    }
}

JsonConvert.DeserializeObjectn'aide pas. J'ai trouvé l'approche suivante:

var dict = JObject.Parse(json).SelectToken("x").ToObject<Dictionary<string, int>>();

le SelectToken vous permet de creuser dans le champ désiré. Vous pouvez même spécifier un chemin comme "x.y.z" pour descendre plus loin dans l'objet JSON.


9
2017-08-11 18:46