Je veux convertir mon Dictionary<int,List<int>>
en chaîne JSON. Est-ce que quelqu'un sait comment y parvenir en C #?
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.
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
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.
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]}]
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);
(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.
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.
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);
Dans Asp.net Core, utilisez:
using Newtonsoft.Json
var obj = new { MyValue = 1 };
var json = JsonConvert.SerializeObject(obj);
var obj2 = JsonConvert.DeserializeObject(json);
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.
//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.
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"]
}]
Vous pouvez utiliser JavaScriptSerializer .
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;
}