Wie konvertiere ich ein Wörterbuch in einen JSON-String in C #?

130

Ich möchte meine Dictionary<int,List<int>>in JSON-Zeichenfolge konvertieren . Weiß jemand, wie man dies in C # erreicht?

daehaai
quelle
3
Verwenden Sie das Nuget-Paket newtonSoft.json. JsonConvert.SerializeObject (yourObject)
RayLoveless

Antworten:

118

Das Serialisieren von Datenstrukturen, die nur numerische oder boolesche Werte enthalten, ist ziemlich einfach. Wenn Sie nicht viel zu serialisieren haben, können Sie eine Methode für Ihren spezifischen Typ schreiben.

Für a, Dictionary<int, List<int>>wie Sie angegeben haben, können Sie Linq verwenden:

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) + "}";
}

Wenn Sie jedoch mehrere verschiedene Klassen oder komplexere Datenstrukturen serialisieren oder insbesondere wenn Ihre Daten Zeichenfolgenwerte enthalten , ist es besser, eine seriöse JSON-Bibliothek zu verwenden, die bereits weiß, wie man mit Escapezeichen und Zeilenumbrüchen umgeht. Json.NET ist eine beliebte Option.

gilly3
quelle
66
Diese Lösung ist bestenfalls naiv. Verwenden Sie eine echte JSON-Serialisierungsbibliothek.
Jacobsimeon
131
@ Jacob - Naiv? Autsch. Persönlich kann ich es nicht rechtfertigen, eine weitere Baugruppe aufzunehmen, wenn alles, was ich tun muss, mit einer kurzen und einfachen Methode erreicht werden kann.
gilly3
16
Noch ein + auf gilly3 Kommentar. Manchmal codieren Sie unter Windows Phone. Sie fügen Zlip, Twitter, Google, Audioverarbeitungsmaterial und Bildverarbeitungsmaterial hinzu. Sie sollten eine einfache Methode wie diese und einige grundlegende HttpRequests für die Interaktion mit sozialen Medien implementieren, wenn Ihre Verwendung einfach ist. Wenn Sie eine Assembly hinzufügen, müssen Sie sich immer mit Fehlern und der Unmöglichkeit befassen, eine Lite-Version zu erhalten. Übrigens gibt es in json libs solche naiven Methoden und keine Magie.
Léon Pelletier
14
Auf jedem offenen Projekt sollte eine Seite stehen, auf der steht: "Hey, die meiste Zeit möchten Sie nur diese 10 Zeilen algo ausführen. Hier ist der Code."
Léon Pelletier
31
dict.add ("RandomKey", "RandomValue"); BOOOOOOOOOOOOOOOOM. Bestenfalls naiv. Verwenden Sie eine echte JSON-Serialisierungsbibliothek.
Sleeper Smith
112

In dieser Antwort wird Json.NET erwähnt, es wird jedoch nicht näher erläutert, wie Sie mit Json.NET ein Wörterbuch serialisieren können:

return JsonConvert.SerializeObject( myDictionary );

Im Gegensatz zu JavaScriptSerializer myDictionarymuss es kein Wörterbuch vom Typ sein, <string, string>damit JsonConvert funktioniert.

Big McLargeHuge
quelle
71

Json.NET serialisiert C # -Wörterbücher jetzt wahrscheinlich angemessen, aber als das OP diese Frage ursprünglich stellte, haben viele MVC-Entwickler möglicherweise die JavaScriptSerializer- Klasse verwendet, da dies die Standardoption war.

Wenn Sie an einem Legacy-Projekt (MVC 1 oder MVC 2) arbeiten und Json.NET nicht verwenden können, empfehle ich die Verwendung von a List<KeyValuePair<K,V>>anstelle von a Dictionary<K,V>>. Die ältere JavaScriptSerializer-Klasse serialisiert diesen Typ einwandfrei, hat jedoch Probleme mit einem Wörterbuch.

Dokumentation: Serialisieren von Sammlungen mit Json.NET

Jim G.
quelle
3
Perfekte Antwort für asp.net mvc3 und mvc4 Benutzer
Gomes
JsonConvert.SerializeObject scheint das Serialisieren von c # -Wörterbüchern in einen Typ von Aufzählungssammlungen beim Zurücklesen in Javascript nicht zu handhaben. Vielmehr wird ein Objekt erstellt, bei dem jedes Paar in der C # -Sammlung jetzt eine einfache Eigenschaft / ein einfacher Wert in einem Objekt ist, der nicht einfach wie eine Sammlung aufgelistet werden kann. Wenn ich also keine schlechte Version von Nuget habe, ist Json.NET in dieser Hinsicht immer noch nicht ausreichend.
StingyJack
Oh ja. Ich habe schon etwas Ähnliches gemacht, aber versucht, einen anderen Weg zu finden, und bin darauf gestoßen. Ich hielt es für nützlich, andere wissen zu lassen, um das Json.NET-Kaninchenloch für diesen Artikel zu vermeiden (funktioniert ansonsten hervorragend).
StingyJack
20
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()));
            }
        }
    }
}

Dies wird in die Konsole schreiben:

[{\"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]}]
Merritt
quelle
18

Einfache einzeilige Antwort

( using System.Web.Script.Serialization)

Dieser Code konvertiert jeden Dictionary<Key,Value>in Dictionary<string,string>und serialisiert ihn dann als JSON-Zeichenfolge:

var json = new JavaScriptSerializer().Serialize(yourDictionary.ToDictionary(item => item.Key.ToString(), item => item.Value.ToString()));

Es ist anzumerken, dass so etwas Dictionary<int, MyClass>auch auf diese Weise serialisiert werden kann, während der komplexe Typ / das komplexe Objekt erhalten bleibt .


Erklärung (Aufschlüsselung)

var yourDictionary = new Dictionary<Key,Value>(); //This is just to represent your current Dictionary.

Sie können die Variable yourDictionarydurch Ihre tatsächliche Variable ersetzen .

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.

Wir tun dies, weil sowohl der Schlüssel als auch der Wert vom Typ string sein müssen, als Voraussetzung für die Serialisierung von 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.
HowlinWulf
quelle
Ich habe kein JavaScriptSerializer in meinem C #.
Jonny
1
@Jonny Sie vermissen Referenz Assembly System.Web.Extensions msdn.microsoft.com/en-us/library/…
aminhotob
Ich habe gelesen, dass dies System.Web.Extensionsnicht in der Client Framework-Version enthalten ist, sondern auch die Vollversion erfordert.
Vapcguy
Könnte eine Lösung für eingeschränkte Anwendungen sein, aber wenn alle Werte zum Typ string gezwungen werden, wird nicht der richtige JSON-Wert ausgegeben, wenn Objekteigenschaften keine Typzeichenfolge sind.
Suncat2000
1
beste Antwort zu diesem Thema.
T.Todua
12

Tut mir leid, wenn die Syntax das kleinste bisschen abweicht, aber der Code, von dem ich das bekomme, war ursprünglich 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);
Riwalk
quelle
2
Es löst eine ArgumentException aus: Der Typ 'System.Collections.Generic.Dictionary`2 wird für die Serialisierung / Deserialisierung eines Wörterbuchs nicht unterstützt. Schlüssel müssen Zeichenfolgen oder Objekte sein.
Pavel Chuchuva
7

In Asp.net Core verwenden Sie:

using Newtonsoft.Json

var obj = new { MyValue = 1 };
var json = JsonConvert.SerializeObject(obj);
var obj2 = JsonConvert.DeserializeObject(json);
Skorunka František
quelle
Ich bezog mich System.Coreund versuchte dann zu referenzieren using Newtonsoft.Jsonund keine Freude. Ich denke, es Newtonsoftist eine Bibliothek von Drittanbietern.
Vapcguy
2
@vapcguy Ja, Newtonsoft ist ein Drittanbieter, der jedoch weit verbreitet ist und auch von MS in seinen Produkten übernommen wird. nuget.org/packages/Newtonsoft.Json
Skorunka František
7

Sie können verwenden 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);
MaxEcho
quelle
2

Hier erfahren Sie, wie Sie nur Standard-.NET-Bibliotheken von Microsoft verwenden.

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());
}
David Young
quelle
Wir können dies mit Dictionary<string, dynamic>allen primitiven JSON-Typen wie Intergern, Floats, Booleschen Werten, Zeichenfolgen, sogar Nullen und innerhalb eines Objekts kombinieren und haben. +1
Christos Lytras
1

Sie können JavaScriptSerializer verwenden .

Zwölf47
quelle
Sind Wörterbücher serialisierbar?
Numenor
Ich hätte gedacht, dass dies funktionieren würde - string json = serializer.Serialize ((Objekt) dict);
Zwölf47
1
@Numenor Ja, aber nur, wenn der Schlüssel UND der Wert vom Typ sind string. Ich habe hier eine Antwort gepostet, die diese enthält, wenn Sie einen Blick darauf werfen möchten.
HowlinWulf
@HowlinWulf um genauer zu sein, der Wert muss keine Zeichenfolge sein. Aber für den Schlüssel kann es nicht definitiv ein Int sein. Saiten funktionieren am besten als Schlüssel.
Gyum Fox
1
@ Twelve47 Sollte eine Beispielverwendung enthalten, falls dieser Link jemals verschoben wird. Andernfalls könnte diese Antwort eines Tages unbrauchbar werden.
Vapcguy
1

Es scheint viele verschiedene Bibliotheken zu geben und was in den letzten Jahren nicht zu kommen und zu gehen schien. Ab April 2016 hat diese Lösung für mich jedoch gut funktioniert. Saiten können leicht durch Ints ersetzt werden .

TL / DR; Kopieren Sie dies, wenn Sie dafür hierher gekommen sind:

    //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();
    }

Zwei Importpunkte. Stellen Sie zunächst sicher, dass Sie System.Runtime.Serliazation als Referenz in Ihrem Projekt im Projektmappen-Explorer von Visual Studio hinzufügen. Zweitens fügen Sie diese Zeile hinzu,

using System.Runtime.Serialization.Json;

oben in der Datei mit dem Rest Ihrer Verwendungen, damit die DataContractJsonSerializerKlasse gefunden werden kann. Dieser Blog-Beitrag enthält weitere Informationen zu dieser Serialisierungsmethode.

Datenformat (Eingabe / Ausgabe)

Meine Daten sind ein Wörterbuch mit 3 Zeichenfolgen, die jeweils auf eine Liste von Zeichenfolgen verweisen. Die Listen der Zeichenfolgen haben die Längen 3, 4 und 1. Die Daten sehen folgendermaßen aus:

StringKeyofDictionary1 => ["abc","def","ghi"]
StringKeyofDictionary2 => ["String01","String02","String03","String04"]
Stringkey3 => ["someString"]

Die in die Datei geschriebene Ausgabe befindet sich in einer Zeile. Hier ist die formatierte Ausgabe:

 [{
     "Key": "StringKeyofDictionary1",
     "Value": ["abc",
     "def",
     "ghi"]
 },
 {
     "Key": "StringKeyofDictionary2",
     "Value": ["String01",
     "String02",
     "String03",
     "String04",
 ]
 },
 {
     "Key": "Stringkey3",
     "Value": ["SomeString"]
 }]
mwjohnson
quelle
0

Dies ähnelt dem, was Meritt zuvor gepostet hat. poste einfach den kompletten Code

    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;
    }
Karshan
quelle
0

Wenn Ihr Kontext dies zulässt (technische Einschränkungen usw.), verwenden Sie die JsonConvert.SerializeObjectMethode von Newtonsoft.Json : Dies erleichtert Ihnen das Leben.

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"}
Ishikawa
quelle