Réponses:
La sérialisation des structures de données contenant uniquement des valeurs numériques ou booléennes est assez simple. Si vous n'avez pas grand-chose à 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 surtout si vos données contiennent des valeurs de chaîne , vous feriez mieux d'utiliser une bibliothèque JSON réputée qui sait déjà comment gérer des choses comme les caractères d'échappement et les sauts de ligne. Json.NET est une option populaire.
Cette réponse mentionne Json.NET mais s'arrête avant de vous dire comment vous pouvez utiliser Json.NET pour sérialiser un dictionnaire:
return JsonConvert.SerializeObject( myDictionary );
Contrairement à JavaScriptSerializer, il myDictionary
n'est pas nécessaire <string, string>
que JsonConvert fonctionne comme un dictionnaire de type .
Json.NET sérialise probablement correctement les dictionnaires C # maintenant, mais lorsque l'OP a initialement publié cette question, de nombreux développeurs MVC utilisaient peut-être la classe JavaScriptSerializer , car c'était l'option par défaut prête à l'emploi .
Si vous travaillez sur un projet existant (MVC 1 ou MVC 2), et vous ne pouvez pas utiliser Json.NET, je vous recommande d'utiliser un au List<KeyValuePair<K,V>>
lieu d'un Dictionary<K,V>>
. La classe héritée JavaScriptSerializer sérialisera très bien ce type, mais elle aura des problèmes avec un dictionnaire.
Documentation: sérialisation des collections avec Json.NET
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 écrira 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]}]
( 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, comme condition requise pour la sérialisation d'un fichier 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.
System.Web.Extensions
n'est pas dans la version Client Framework, mais nécessite également la version complète.
Désolé si la syntaxe est la plus petite, mais le code à partir duquel je l'obtiens était à l'origine en 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);
Dans Asp.net Core, utilisez:
using Newtonsoft.Json
var obj = new { MyValue = 1 };
var json = JsonConvert.SerializeObject(obj);
var obj2 = JsonConvert.DeserializeObject(json);
System.Core
et ensuite essayé de référencer using Newtonsoft.Json
et pas de joie. Je pense que Newtonsoft
c'est une bibliothèque tierce.
Voici comment procéder en utilisant uniquement les bibliothèques .Net standard de Microsoft…
using System.IO;
using System.Runtime.Serialization.Json;
private static string DataToJson<T>(T data)
{
MemoryStream stream = new MemoryStream();
DataContractJsonSerializer serialiser = new DataContractJsonSerializer(
data.GetType(),
new DataContractJsonSerializerSettings()
{
UseSimpleDictionaryFormat = true
});
serialiser.WriteObject(stream, data);
return Encoding.UTF8.GetString(stream.ToArray());
}
Dictionary<string, dynamic>
et avoir tous les types primitifs JSON tels que les entiers, les flottants, les booléens, les chaînes, même les valeurs nulles et dans un seul objet. +1
Vous pouvez utiliser JavaScriptSerializer .
string
. J'ai publié ici une réponse qui inclut cela, si vous voulez jeter un coup d'œil.
Il semble que beaucoup de bibliothèques différentes et ce qui n'a pas semblé aller et venir au cours des années précédentes. Cependant, en avril 2016, cette solution fonctionnait bien pour moi. Cordes facilement remplacées par des 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, assurez-vous d'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, afin que la DataContractJsonSerializer
classe puisse être trouvée. Ce billet 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 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"]
}]
Ceci est similaire à ce que Meritt a publié plus tôt. juste 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;
}
Si votre contexte le permet (contraintes techniques, etc.), utilisez la JsonConvert.SerializeObject
méthode de Newtonsoft.Json : cela vous facilitera la vie.
Dictionary<string, string> localizedWelcomeLabels = new Dictionary<string, string>();
localizedWelcomeLabels.Add("en", "Welcome");
localizedWelcomeLabels.Add("fr", "Bienvenue");
localizedWelcomeLabels.Add("de", "Willkommen");
Console.WriteLine(JsonConvert.SerializeObject(localizedWelcomeLabels));
// Outputs : {"en":"Welcome","fr":"Bienvenue","de":"Willkommen"}