Bagaimana cara mengonversi kamus ke String JSON dalam C #?

130

Saya ingin mengonversi Dictionary<int,List<int>>string saya ke JSON. Adakah yang tahu cara mencapai ini di C #?

daehaai
sumber
3
Gunakan paket nuget newtonSoft.json. JsonConvert.SerializeObject (yourObject)
RayLoveless

Jawaban:

118

Menialisasi struktur data yang hanya berisi nilai numerik atau boolean cukup mudah. Jika Anda tidak memiliki banyak serialisasi, Anda dapat menulis metode untuk tipe spesifik Anda.

Untuk Dictionary<int, List<int>>seperti yang telah Anda tentukan, Anda dapat menggunakan 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) + "}";
}

Tetapi, jika Anda membuat serial beberapa kelas yang berbeda, atau struktur data yang lebih kompleks, atau terutama jika data Anda berisi nilai string , Anda akan lebih baik menggunakan perpustakaan JSON yang memiliki reputasi baik yang sudah tahu bagaimana menangani hal-hal seperti karakter pelarian dan pemisah baris. Json.NET adalah opsi yang populer.

gilly3
sumber
66
Solusi ini naif di terbaik. Gunakan perpustakaan serialisasi json nyata.
jacobsimeon
131
@ Jacob - Naif? Aduh. Secara pribadi, saya tidak bisa membenarkan termasuk perakitan lain ketika semua yang perlu saya lakukan dapat diselesaikan dengan satu metode pendek dan sederhana.
gilly3
16
Satu lagi + di komentar gilly3. Terkadang Anda mengkode di Windows Phone. Anda menambahkan zlip, twitter, google, hal-hal pemrosesan audio, hal-hal pemrosesan gambar. Anda lebih baik menerapkan metode sederhana seperti itu, dan beberapa HttpRequests dasar untuk interaksi media sosial jika penggunaan Anda sederhana. Saat menambahkan rakitan, Anda selalu harus berurusan dengan bug, dan dengan ketidakmungkinan mendapatkan versi lite. Ngomong-ngomong, di dalam json libs, ada metode naif seperti ini dan tidak ada sihir.
Léon Pelletier
14
Seharusnya ada halaman di setiap proyek terbuka yang memberi tahu Anda: "Hei, sebagian besar waktu, Anda hanya ingin mengeksekusi 10 baris ini. Ini kodenya."
Léon Pelletier
31
dict.add ("RandomKey \" "," RandomValue \ ""); BOOOOOOOOOOOOOOOOM. Naif di terbaik. Gunakan perpustakaan serialisasi json nyata.
Sleeper Smith
112

Jawaban ini menyebutkan Json.NET tetapi berhenti memberi tahu Anda bagaimana Anda dapat menggunakan Json.NET untuk membuat serialisasi kamus:

return JsonConvert.SerializeObject( myDictionary );

Berbeda dengan JavaScriptSerializer, myDictionarytidak harus menjadi kamus tipe <string, string>untuk JsonConvert agar berfungsi.

McLarge Besar
sumber
71

Json.NET mungkin membuat serialisasi kamus C # dengan memadai sekarang, tetapi ketika OP awalnya memposting pertanyaan ini, banyak pengembang MVC mungkin telah menggunakan kelas JavaScriptSerializer karena itu adalah opsi default di luar kotak.

Jika Anda sedang mengerjakan proyek lawas (MVC 1 atau MVC 2), dan Anda tidak dapat menggunakan Json.NET, saya sarankan Anda menggunakan List<KeyValuePair<K,V>>bukan Dictionary<K,V>>. Kelas JavaScriptSerializer lama akan membuat serialisasi jenis ini dengan baik, tetapi akan memiliki masalah dengan kamus.

Dokumentasi: Melakukan Serialisasi Koleksi dengan Json.NET

Jim G.
sumber
3
Jawaban sempurna untuk pengguna asp.net mvc3 dan mvc4
Gomes
JsonConvert.SerializeObject tampaknya tidak menangani serialisasi kamus c # ke jenis koleksi yang dapat dihitung saat dibaca kembali ke dalam Javascript. Sebaliknya, itu membuat objek di mana setiap pasangan dalam koleksi C # sekarang menjadi properti / nilai polos dalam objek, yang tidak dapat dengan mudah disebutkan seperti koleksi. Jadi, kecuali saya memiliki versi buruk dari nuget, Json.NET masih tidak memadai. Dalam hal ini.
StingyJack
Oh ya. Saya sudah melakukan hal yang sama, tetapi mencoba mencari cara lain, dan menemukan ini. Saya merasa mungkin berguna untuk memberi tahu orang lain untuk menghindari lubang kelinci Json.NET untuk item ini (berfungsi sangat baik jika tidak).
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()));
            }
        }
    }
}

Ini akan menulis ke konsol:

[{\"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
sumber
19

Jawaban Satu Baris Sederhana

( using System.Web.Script.Serialization)

Kode ini akan mengonversi apa saja Dictionary<Key,Value>menjadi Dictionary<string,string>dan kemudian membuat serial sebagai string JSON:

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

Penting untuk dicatat bahwa sesuatu seperti Dictionary<int, MyClass>juga dapat diserialisasi dengan cara ini sambil mempertahankan tipe / objek yang kompleks.


Penjelasan (gangguan)

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

Anda dapat mengganti variabel yourDictionarydengan variabel aktual Anda.

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.

Kami melakukan ini, karena Kunci dan Nilai harus bertipe string, sebagai persyaratan untuk serialisasi 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
sumber
Saya tidak memiliki JavaScriptSerializer di C # saya.
Jonny
1
@Jonny Anda kehilangan referensi perakitan System.Web.Extensions msdn.microsoft.com/en-us/library/…
aminhotob
Saya pernah membaca bahwa System.Web.Extensionsitu bukan dalam versi Kerangka Klien, tetapi membutuhkan versi lengkap juga.
vapcguy
Bisa jadi solusi untuk aplikasi terbatas, tetapi memaksa semua nilai untuk mengetik string tidak akan menghasilkan JSON yang benar jika properti objek apa pun tidak mengetik string.
Suncat2000
1
jawaban terbaik untuk topik ini.
T.Todua
12

Maaf jika sintaksnya adalah bit terkecil, tetapi kode yang saya peroleh berasal dari 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
sumber
2
Melempar ArgumentException: Ketik 'System.Collections.Generic.Dictionary`2 tidak didukung untuk serialisasi / deserialisasi kamus, kunci harus berupa string atau objek.
Pavel Chuchuva
7

Di Asp.net Core, gunakan:

using Newtonsoft.Json

var obj = new { MyValue = 1 };
var json = JsonConvert.SerializeObject(obj);
var obj2 = JsonConvert.DeserializeObject(json);
Skorunka František
sumber
Saya referensi System.Coredan kemudian mencoba referensi using Newtonsoft.Jsondan tidak ada sukacita. Saya pikir Newtonsoftadalah perpustakaan pihak ke-3.
vapcguy
2
@ vapcguy Ya, Newtonsoft adalah pihak ketiga tetapi banyak digunakan dan diadopsi juga oleh MS dalam produk mereka. nuget.org/packages/Newtonsoft.Json
Skorunka František
7

Anda bisa menggunakan 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
sumber
2

Berikut cara melakukannya hanya menggunakan pustaka .Net standar dari 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());
}
David Young
sumber
Kita dapat menggabungkan ini dengan Dictionary<string, dynamic>dan memiliki semua tipe primitif JSON seperti intergers, float, boolean, string, bahkan nulls dan dalam satu objek. +1
Christos Lytras
1

Anda bisa menggunakan JavaScriptSerializer .

Dua Belas47
sumber
apakah kamus bisa serial?
Numenor
Saya akan berpikir ini akan bekerja - string json = serializer.Serialize ((objek) dict);
Twelve47
1
@Numenor Ya, benar, tetapi hanya jika Kunci DAN Nilai bertipe string. Saya telah mengirim jawaban di sini yang mencakup itu, jika Anda ingin melihatnya.
HowlinWulf
@ HowlinWulf lebih tepatnya, nilainya tidak harus berupa string. Tapi untuk kuncinya, itu tidak bisa menjadi int. String berfungsi paling baik sebagai kunci.
Gyum Fox
1
@ Twelve47 Sebaiknya sertakan penggunaan sampel, jika tautan itu pernah dipindahkan. Kalau tidak, jawaban ini bisa menjadi tidak berguna, suatu hari.
vapcguy
1

Tampaknya banyak perpustakaan berbeda dan apa yang tampaknya tidak datang dan pergi tahun-tahun sebelumnya. Namun pada April 2016, solusi ini bekerja dengan baik untuk saya. String mudah diganti oleh int .

TL / DR; Salin ini jika Anda datang ke sini untuk:

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

Dua poin impor. Pertama, pastikan untuk menambahkan System.Runtime.Serliazation sebagai referensi dalam proyek Anda di dalam Visual Studio's Solution Explorer. Kedua, tambahkan baris ini,

using System.Runtime.Serialization.Json;

di bagian atas file dengan sisa usings Anda, sehingga DataContractJsonSerializerkelas dapat ditemukan. Posting blog ini memiliki informasi lebih lanjut tentang metode serialisasi ini.

Format Data (Input / Output)

Data saya adalah kamus dengan 3 string, masing-masing menunjuk ke daftar string. Daftar string memiliki panjang 3, 4, dan 1. Data terlihat seperti ini:

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

Output yang ditulis ke file akan berada pada satu baris, berikut adalah output yang diformat:

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

Ini mirip dengan apa yang diposting Meritt sebelumnya. hanya memposting kode lengkap

    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
sumber
0

Jika konteks Anda mengizinkannya (kendala teknis, dll.), Gunakan JsonConvert.SerializeObjectmetode dari Newtonsoft.Json : itu akan membuat hidup Anda lebih mudah.

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
sumber