web-dev-qa-db-fra.com

Comment convertir un dictionnaire en chaîne JSON en C #?

Je veux convertir mon Dictionary<int,List<int>> en chaîne JSON. Est-ce que quelqu'un sait comment y parvenir en C #?

106
daehaai

La sérialisation des structures de données ne contenant que des valeurs numériques ou booléennes est relativement simple. Si vous n'avez pas beaucoup à sérialiser, vous pouvez écrire une méthode pour votre type spécifique.

Pour un Dictionary<int, List<int>> comme vous l'avez spécifié, vous pouvez utiliser Linq:

string MyDictionaryToJson(Dictionary<int, List<int>> dict)
{
    var entries = dict.Select(d =>
        string.Format("\"{0}\": [{1}]", d.Key, string.Join(",", d.Value)));
    return "{" + string.Join(",", entries) + "}";
}

Mais, si vous sérialisez plusieurs classes différentes, ou des structures de données plus complexes, ou particulièrement si vos données contiennent des valeurs de chaîne, il serait préférable d'utiliser une bibliothèque JSON réputée gérer des choses comme les caractères d'échappement et les sauts de ligne. Json.NET est une option populaire.

103
gilly3

Json.NET sérialise probablement les dictionnaires C # de manière adéquate à présent, mais lorsque le PO a posé cette question à l'origine, de nombreux développeurs MVC utilisaient peut-être la classe JavaScriptSerializer car il s'agissait de l'option par défaut.

Si vous travaillez sur un projet hérité (MVC 1 ou MVC 2) et que vous ne pouvez pas utiliser Json.NET, je vous recommande d'utiliser un List<KeyValuePair<K,V>> au lieu d'un Dictionary<K,V>>. La classe JavaScriptSerializer existante va sérialiser ce type, mais elle aura des problèmes avec un dictionnaire.

Documentation: Sérialisation des collections avec Json.NET

67
Jim G.

Cette réponse mentionne Json.NET mais ne vous dit pas comment utiliser Json.NET pour sérialiser un dictionnaire:

return JsonConvert.SerializeObject( myDictionary );

Contrairement à JavaScriptSerializer, il n'est pas nécessaire que myDictionary soit un dictionnaire de type <string, string> pour que JsonConvert fonctionne.

64
David Kennedy
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.Serialization.Json;
using System.IO;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            Dictionary<int, List<int>> foo = new Dictionary<int, List<int>>();

            foo.Add(1, new List<int>( new int[] { 1, 2, 3, 4 }));
            foo.Add(2, new List<int>(new int[] { 2, 3, 4, 1 }));
            foo.Add(3, new List<int>(new int[] { 3, 4, 1, 2 }));
            foo.Add(4, new List<int>(new int[] { 4, 1, 2, 3 }));

            DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(Dictionary<int, List<int>>));

            using (MemoryStream ms = new MemoryStream())
            {
                serializer.WriteObject(ms, foo);
                Console.WriteLine(Encoding.Default.GetString(ms.ToArray()));
            }
        }
    }
}

Cela va écrire sur la console:

[{\"Key\":1,\"Value\":[1,2,3,4]},{\"Key\":2,\"Value\":[2,3,4,1]},{\"Key\":3,\"Value\":[3,4,1,2]},{\"Key\":4,\"Value\":[4,1,2,3]}]
17
Merritt

Désolé si la syntaxe est la moindre, mais le code dont je tire ce code était à l'origine dans VB :)

using System.Web.Script.Serialization;

...

Dictionary<int,List<int>> MyObj = new Dictionary<int,List<int>>();

//Populate it here...

string myJsonString = (new JavaScriptSerializer()).Serialize(MyObj);
12
riwalk

Réponse simple en une ligne

(using System.Web.Script.Serialization)

Ce code convertira tout Dictionary<Key,Value> en Dictionary<string,string>, puis le sérialisera en tant que chaîne JSON:

var json = new JavaScriptSerializer().Serialize(yourDictionary.ToDictionary(item => item.Key.ToString(), item => item.Value.ToString()));

Il est intéressant de noter que quelque chose comme Dictionary<int, MyClass> peut également être sérialisé de cette manière tout en préservant le type/objet complexe.


Explication (panne)

var yourDictionary = new Dictionary<Key,Value>(); //This is just to represent your current Dictionary.

Vous pouvez remplacer la variable yourDictionary par votre variable réelle.

var convertedDictionary = yourDictionary.ToDictionary(item => item.Key.ToString(), item => item.Value.ToString()); //This converts your dictionary to have the Key and Value of type string.

Nous faisons cela, car la clé et la valeur doivent être de type chaîne, ce qui est une exigence de la sérialisation de Dictionary.

var json = new JavaScriptSerializer().Serialize(convertedDictionary); //You can then serialize the Dictionary, as both the Key and Value is of type string, which is required for serialization.
11
HowlinWulf

Vous pouvez utiliser System.Web.Script.Serialization.JavaScriptSerializer:

Dictionary<string, object> dictss = new Dictionary<string, object>(){
   {"User", "Mr.Joshua"},
   {"Pass", "4324"},
};

string jsonString = (new JavaScriptSerializer()).Serialize((object)dictss);
7
Salim

Dans Asp.net Core, utilisez:

using Newtonsoft.Json

var obj = new { MyValue = 1 };
var json = JsonConvert.SerializeObject(obj);
var obj2 = JsonConvert.DeserializeObject(json);
5

Il semble y avoir beaucoup de bibliothèques différentes et ce qui ne semble pas aller et venir au cours des années précédentes. Cependant, à partir d'avril 2016, cette solution a bien fonctionné pour moi. Les chaînes sont facilement remplacées par ints.

TL/DR; Copiez ceci si c'est pour ça que vous êtes venu ici:

    //outputfilename will be something like: "C:/MyFolder/MyFile.txt"
    void WriteDictionaryAsJson(Dictionary<string, List<string>> myDict, string outputfilename)
    {
        DataContractJsonSerializer js = new DataContractJsonSerializer(typeof(Dictionary<string, List<string>>));
        MemoryStream ms = new MemoryStream();
        js.WriteObject(ms, myDict); //Does the serialization.

        StreamWriter streamwriter = new StreamWriter(outputfilename);
        streamwriter.AutoFlush = true; // Without this, I've run into issues with the stream being "full"...this solves that problem.

        ms.Position = 0; //ms contains our data in json format, so let's start from the beginning
        StreamReader sr = new StreamReader(ms); //Read all of our memory
        streamwriter.WriteLine(sr.ReadToEnd()); // and write it out.

        ms.Close(); //Shutdown everything since we're done.
        streamwriter.Close();
        sr.Close();
    }

Deux points d'importation. Tout d'abord, veillez à ajouter System.Runtime.Serliazation comme référence dans votre projet dans l'explorateur de solutions de Visual Studio. Deuxièmement, ajoutez cette ligne, 

using System.Runtime.Serialization.Json;

en haut du fichier avec le reste de vos utilisations, ainsi la classe DataContractJsonSerializer peut être trouvée. Ce article de blog contient plus d'informations sur cette méthode de sérialisation.

Format de données (entrée/sortie)

Mes données sont un dictionnaire avec 3 chaînes, chacune pointant vers une liste de chaînes. Les listes de chaînes ont des longueurs de 3, 4 et 1 . Les données ressemblent à ceci:

StringKeyofDictionary1 => ["abc","def","ghi"]
StringKeyofDictionary2 => ["String01","String02","String03","String04"]
Stringkey3 => ["someString"]

La sortie écrite dans le fichier sera sur une ligne, voici la sortie formatée:

 [{
     "Key": "StringKeyofDictionary1",
     "Value": ["abc",
     "def",
     "ghi"]
 },
 {
     "Key": "StringKeyofDictionary2",
     "Value": ["String01",
     "String02",
     "String03",
     "String04",
 ]
 },
 {
     "Key": "Stringkey3",
     "Value": ["SomeString"]
 }]
1
mwjohnson

Vous pouvez utiliser JavaScriptSerializer .

1
Twelve47

Ceci est similaire à ce que Meritt a posté plus tôt. il suffit de poster le code complet

    string sJSON;
    Dictionary<string, string> aa1 = new Dictionary<string, string>();
    aa1.Add("one", "1"); aa1.Add("two", "2"); aa1.Add("three", "3");
    Console.Write("JSON form of Person object: ");

    sJSON = WriteFromObject(aa1);
    Console.WriteLine(sJSON);

    Dictionary<string, string> aaret = new Dictionary<string, string>();
    aaret = ReadToObject<Dictionary<string, string>>(sJSON);

    public static string WriteFromObject(object obj)
    {            
        byte[] json;
            //Create a stream to serialize the object to.  
        using (MemoryStream ms = new MemoryStream())
        {                
            // Serializer the object to the stream.  
            DataContractJsonSerializer ser = new DataContractJsonSerializer(obj.GetType());
            ser.WriteObject(ms, obj);
            json = ms.ToArray();
            ms.Close();
        }
        return Encoding.UTF8.GetString(json, 0, json.Length);

    }

    // Deserialize a JSON stream to object.  
    public static T ReadToObject<T>(string json) where T : class, new()
    {
        T deserializedObject = new T();
        using (MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes(json)))
        {

            DataContractJsonSerializer ser = new DataContractJsonSerializer(deserializedObject.GetType());
            deserializedObject = ser.ReadObject(ms) as T;
            ms.Close();
        }
        return deserializedObject;
    }
0
Karshan