Respuestas:
Serializar estructuras de datos que contienen solo valores numéricos o booleanos es bastante sencillo. Si no tiene mucho para serializar, puede escribir un método para su tipo específico.
Para Dictionary<int, List<int>>
lo que ha especificado, puede usar 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) + "}";
}
Pero, si está serializando varias clases diferentes, o estructuras de datos más complejas, o especialmente si sus datos contienen valores de cadena , sería mejor usar una biblioteca JSON confiable que ya sepa cómo manejar cosas como caracteres de escape y saltos de línea. Json.NET es una opción popular.
Esta respuesta menciona Json.NET pero no le dice cómo puede usar Json.NET para serializar un diccionario:
return JsonConvert.SerializeObject( myDictionary );
A diferencia de JavaScriptSerializer, myDictionary
no tiene que ser un diccionario de tipo <string, string>
para que JsonConvert funcione.
Json.NET probablemente serializa los diccionarios de C # de manera adecuada ahora, pero cuando el OP originalmente publicó esta pregunta, muchos desarrolladores de MVC pueden haber estado utilizando la clase JavaScriptSerializer porque esa era la opción predeterminada lista para usar .
Si está trabajando en un proyecto heredado (MVC 1 o MVC 2) y no puede usar Json.NET, le recomiendo que use un en List<KeyValuePair<K,V>>
lugar de un Dictionary<K,V>>
. La clase JavaScriptSerializer heredada serializará este tipo muy bien, pero tendrá problemas con un diccionario.
Documentación: serialización de colecciones 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()));
}
}
}
}
Esto escribirá en la consola:
[{\"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
)
Este código será convertir cualquier Dictionary<Key,Value>
a Dictionary<string,string>
y luego serializarlo como una cadena JSON:
var json = new JavaScriptSerializer().Serialize(yourDictionary.ToDictionary(item => item.Key.ToString(), item => item.Value.ToString()));
Vale la pena señalar que algo así Dictionary<int, MyClass>
también se puede serializar de esta manera mientras se preserva el tipo / objeto complejo.
var yourDictionary = new Dictionary<Key,Value>(); //This is just to represent your current Dictionary.
Puede reemplazar la variable yourDictionary
con su variable real.
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.
Hacemos esto, porque tanto la clave como el valor deben ser de tipo cadena, como requisito para la serialización de 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
no está en la versión de Client Framework, pero también requiere la versión completa.
Lo siento si la sintaxis es mínima, pero el código del que obtengo esto estaba originalmente 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);
En Asp.net Core use:
using Newtonsoft.Json
var obj = new { MyValue = 1 };
var json = JsonConvert.SerializeObject(obj);
var obj2 = JsonConvert.DeserializeObject(json);
System.Core
y luego intenté hacer referencia using Newtonsoft.Json
y sin alegría. Creo que Newtonsoft
es una biblioteca de terceros.
Aquí le mostramos cómo hacerlo utilizando solo bibliotecas .Net estándar 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>
y tener todos los tipos primitivos JSON como números enteros, flotantes, booleanos, cadenas, incluso nulos y dentro de un objeto. +1
Puedes usar JavaScriptSerializer .
string
. He publicado una respuesta aquí que incluye eso, si quieres echar un vistazo.
Parece que hay muchas bibliotecas diferentes y lo que no parece haber ido y venido en los años anteriores. Sin embargo, a partir de abril de 2016, esta solución funcionó bien para mí. Cadenas fácilmente reemplazables por 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();
}
Dos puntos de importación. Primero, asegúrese de agregar System.Runtime.Serliazation como referencia en su proyecto dentro del Explorador de soluciones de Visual Studio. Segundo, agrega esta línea,
using System.Runtime.Serialization.Json;
en la parte superior del archivo con el resto de sus usos, para que DataContractJsonSerializer
pueda encontrar la clase. Esta publicación de blog tiene más información sobre este método de serialización.
Mis datos son un diccionario con 3 cadenas, cada una apuntando a una lista de cadenas. Las listas de cadenas tienen longitudes 3, 4 y 1. Los datos se ven así:
StringKeyofDictionary1 => ["abc","def","ghi"]
StringKeyofDictionary2 => ["String01","String02","String03","String04"]
Stringkey3 => ["someString"]
La salida escrita en el archivo estará en una línea, aquí está la salida formateada:
[{
"Key": "StringKeyofDictionary1",
"Value": ["abc",
"def",
"ghi"]
},
{
"Key": "StringKeyofDictionary2",
"Value": ["String01",
"String02",
"String03",
"String04",
]
},
{
"Key": "Stringkey3",
"Value": ["SomeString"]
}]
Esto es similar a lo que Meritt ha publicado anteriormente. simplemente publicando el código 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;
}
Si su contexto lo permite (restricciones técnicas, etc.), use el JsonConvert.SerializeObject
método de Newtonsoft.Json : le facilitará la vida.
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"}