¿Cómo convertir un diccionario a una cadena JSON en C#?


Quiero convertir mi Dictionary<int,List<int>> a cadena JSON. ¿Alguien sabe cómo lograr esto en C#?

Author: George Stocker, 2011-04-08

11 answers

Serializar estructuras de datos que contengan solo valores numéricos o booleanos es bastante sencillo. Si no tienes mucho que serializar, puedes escribir un método para tu tipo específico.

Para un Dictionary<int, List<int>> como 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 de buena reputación que ya sabe cómo manejar cosas como personajes de escape y saltos de línea. Json.NET es una opción popular.

 102
Author: gilly3,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-08-31 21:13:37

Json.NET probablemente serializa los diccionarios de C# adecuadamente ahora, pero cuando el OP publicó originalmente esta pregunta, muchos desarrolladores MVC pueden haber estado usando la clase JavaScriptSerializer porque esa era la opción predeterminada.

Si está trabajando en un proyecto heredado (MVC 1 o MVC 2), y no puede usar Json.NET, Le recomiendo que utilice un List<KeyValuePair<K,V>> en lugar de un Dictionary<K,V>>. La clase legacy JavaScriptSerializer serializará este tipo muy bien, pero tendrá problemas con un diccionario.

Documentación: Serialización de Colecciones con Json.NET

 64
Author: Jim G.,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-01-30 22:17:51

Esta respuesta menciona Json.NET pero no te dice cómo puedes 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.

 56
Author: David Kennedy,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 11:54:53
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]}]
 16
Author: Merritt,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-04-08 15:45:34

Lo siento si la sintaxis es la más pequeña, 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);
 12
Author: riwalk,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-04-08 15:46:32

Respuesta simple de Una Línea

(using System.Web.Script.Serialization )

Este código convertirá cualquier Dictionary<Key,Value> a Dictionary<string,string> y luego lo serializará 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 como Dictionary<int, MyClass> también puede ser serializado de esta manera mientras se preserva el tipo/objeto complejo.


Explicación (desglose)

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 de escriba string, como requisito para la serialización de un 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.
 10
Author: HowlinWulf,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-03-13 17:02:41

Puedes usar 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
Author: Salim,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-03-13 12:31:16

En Asp.net Uso del núcleo:

using Newtonsoft.Json

var obj = new { MyValue = 1 };
var json = JsonConvert.SerializeObject(obj);
var obj2 = JsonConvert.DeserializeObject(json);
 5
Author: Skorunka František,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-10-15 10:48:18
 1
Author: Twelve47,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-04-08 15:47:50

Parece una gran cantidad de bibliotecas diferentes y lo que no tienen parecen ir y venir durante los años anteriores. Sin embargo, a partir de abril de 2016, esta solución funcionó bien para mí. Cadenas fácilmente reemplazadas por ints.

TL / DR; Copia esto si eso es para lo que viniste aquí:

    //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 el sistema.Ejecución.Serliazation como referencia en su proyecto dentro del Explorador de soluciones de Visual Studio. En segundo lugar, añadir esta línea,

using System.Runtime.Serialization.Json;

En la parte superior del archivo con el resto de sus usos, por lo que la clase DataContractJsonSerializer se puede encontrar. Esta entrada de blog tiene más información sobre este método de serialización.

Formato de datos (Entrada / salida)

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"]
 }]
 1
Author: mwjohnson,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-04-27 08:00:40

Esto es Similar a lo que Meritt ha publicado anteriormente. solo 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;
    }
 0
Author: Karshan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-05 15:10:17