Risposte:
La serializzazione di strutture di dati contenenti solo valori numerici o booleani è abbastanza semplice. Se non hai molto da serializzare, puoi scrivere un metodo per il tuo tipo specifico.
Per un Dictionary<int, List<int>>
come specificato, è possibile utilizzare 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) + "}";
}
Ma se stai serializzando più classi diverse, o strutture di dati più complesse, o specialmente se i tuoi dati contengono valori di stringa , sarebbe meglio usare una libreria JSON affidabile che sappia già come gestire cose come caratteri di escape e interruzioni di riga. Json.NET è un'opzione popolare.
Questa risposta menziona Json.NET ma non ti dice come puoi usare Json.NET per serializzare un dizionario:
return JsonConvert.SerializeObject( myDictionary );
A differenza di JavaScriptSerializer, myDictionary
non deve essere un dizionario di tipo <string, string>
affinché JsonConvert funzioni.
Probabilmente Json.NET ora serializza adeguatamente i dizionari C #, ma quando l'OP originariamente ha pubblicato questa domanda, molti sviluppatori MVC potrebbero aver usato la classe JavaScriptSerializer perché quella era l'opzione predefinita pronta all'uso .
Se stai lavorando a un progetto legacy (MVC 1 o MVC 2) e non riesci a utilizzare Json.NET, ti consiglio di utilizzare un List<KeyValuePair<K,V>>
anziché un Dictionary<K,V>>
. La classe legacy JavaScriptSerializer serializzerà questo tipo bene, ma avrà problemi con un dizionario.
Documentazione: serializzazione delle raccolte con 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()));
}
}
}
}
Questo scriverà sulla 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
)
Questo codice convertirà qualsiasi Dictionary<Key,Value>
in Dictionary<string,string>
e quindi lo serializzerà come una stringa JSON:
var json = new JavaScriptSerializer().Serialize(yourDictionary.ToDictionary(item => item.Key.ToString(), item => item.Value.ToString()));
Vale la pena notare che qualcosa di simile Dictionary<int, MyClass>
può anche essere serializzato in questo modo preservando il tipo / oggetto complesso.
var yourDictionary = new Dictionary<Key,Value>(); //This is just to represent your current Dictionary.
È possibile sostituire la variabile yourDictionary
con la variabile effettiva.
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.
Facciamo questo, perché sia la chiave che il valore devono essere di tipo stringa, come requisito per la serializzazione di a 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
non è nella versione Client Framework, ma richiede anche la versione completa.
Scusate se la sintassi è la più piccola, ma il codice da cui sto ottenendo era originariamente in 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);
In Asp.net Core utilizzare:
using Newtonsoft.Json
var obj = new { MyValue = 1 };
var json = JsonConvert.SerializeObject(obj);
var obj2 = JsonConvert.DeserializeObject(json);
System.Core
e quindi ho cercato di fare riferimento using Newtonsoft.Json
e nessuna gioia. Penso che Newtonsoft
sia una libreria di terze parti.
Ecco come farlo utilizzando solo le librerie .Net standard di 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>
e avere tutti i tipi primitivi JSON come interger, float, booleani, stringhe, anche null e all'interno di un oggetto. +1
È possibile utilizzare JavaScriptSerializer .
string
. Ho pubblicato qui una risposta che lo include, se vuoi dare un'occhiata.
Sembra un sacco di librerie diverse e ciò che non è sembrato andare e venire negli anni precedenti. Tuttavia, a partire da aprile 2016, questa soluzione ha funzionato bene per me. Stringhe facilmente sostituibili da 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();
}
Due punti di importazione. Innanzitutto, assicurarsi di aggiungere System.Runtime.Serliazation come riferimento nel progetto all'interno di Esplora soluzioni di Visual Studio. Secondo, aggiungi questa riga,
using System.Runtime.Serialization.Json;
nella parte superiore del file con il resto dei tuoi utilizzi, quindi la DataContractJsonSerializer
classe può essere trovata. Questo post sul blog contiene ulteriori informazioni su questo metodo di serializzazione.
I miei dati sono un dizionario con 3 stringhe, ognuna che punta a un elenco di stringhe. Gli elenchi di stringhe hanno lunghezze 3, 4 e 1. I dati si presentano così:
StringKeyofDictionary1 => ["abc","def","ghi"]
StringKeyofDictionary2 => ["String01","String02","String03","String04"]
Stringkey3 => ["someString"]
L'output scritto nel file sarà su una riga, ecco l'output formattato:
[{
"Key": "StringKeyofDictionary1",
"Value": ["abc",
"def",
"ghi"]
},
{
"Key": "StringKeyofDictionary2",
"Value": ["String01",
"String02",
"String03",
"String04",
]
},
{
"Key": "Stringkey3",
"Value": ["SomeString"]
}]
Questo è simile a quello che Meritt ha pubblicato in precedenza. basta pubblicare il codice completo
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;
}
Se il tuo contesto lo consente (vincoli tecnici, ecc.), Utilizza il JsonConvert.SerializeObject
metodo di Newtonsoft.Json : ti semplificherà la vita.
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"}