C # dilinde bir sözlüğü JSON Dizesine nasıl dönüştürebilirim?


131

Dictionary<int,List<int>>JSON dizgemi dönüştürmek istiyorum . Bunu C # ile nasıl başaracağını bilen var mı?


3
NewtonSoft.json nuget paketini kullanın. JsonConvert.SerializeObject (yourObject)
RayLoveless

Yanıtlar:


119

Yalnızca sayısal veya boole değerleri içeren veri yapılarını serileştirmek oldukça basittir. Serileştirecek çok şeyiniz yoksa, kendi türünüz için bir yöntem yazabilirsiniz.

A için Dictionary<int, List<int>>belirttiğiniz gibi, sen Linq kullanabilirsiniz:

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

Ancak, birkaç farklı sınıfı veya daha karmaşık veri yapılarını serileştiriyorsanız veya özellikle verileriniz dize değerleri içeriyorsa , kaçış karakterleri ve satır kesmeleri gibi şeylerin nasıl işleneceğini zaten bilen saygın bir JSON kitaplığı kullanmanız daha iyi olur. Json.NET popüler bir seçenektir.


67
Bu çözüm en iyi ihtimalle saftır. Gerçek bir json serileştirme kitaplığı kullanın.
jacobsimeon

131
@Jacob - Naif? Ahh. Şahsen, yapmam gereken her şey kısa ve basit bir yöntemle gerçekleştirilebilirken, başka bir montaj dahil etmeyi haklı gösteremem .
gilly3

16
Gilly3 yorumunda bir + daha. Bazen Windows Phone'da kod yazıyorsunuz. Zlip, twitter, google, ses işleme öğeleri, görüntü işleme öğeleri ekliyorsunuz. Bunun gibi basit bir yöntemi ve kullanımınız basitse sosyal medya etkileşimi için bazı temel HttpRequests'i daha iyi uygulayabilirsiniz. Bir montaj eklerken, her zaman hatalarla ve hafif bir sürüm almanın imkansızlığı ile uğraşmanız gerekir. Bu arada, json libs içinde bunun gibi saf yöntemler var ve sihir yok.
Léon Pelletier

14
Her açık projede size şunu söyleyen bir sayfa olmalı: "Hey, çoğu zaman, bu 10 satırı algo çalıştırmak isteyeceksiniz. İşte kod."
Léon Pelletier

32
dict.add ("RandomKey \" "," RandomValue \ ""); BOOOOOOOOOOOOOOOOM. En iyi ihtimalle saf. Gerçek bir json serileştirme kitaplığı kullanın.
Sleeper Smith

112

Bu cevap Json.NET'ten bahseder, ancak bir sözlüğü serileştirmek için Json.NET'i nasıl kullanabileceğinizi söylemekten vazgeçer:

return JsonConvert.SerializeObject( myDictionary );

JavaScriptSerializer'ın aksine, JsonConvert'ın çalışması için myDictionarybir tür sözlüğü olması <string, string>gerekmez.


71

Json.NET muhtemelen C # sözlüklerini yeterince seri hale getiriyor , ancak OP bu soruyu ilk başta gönderdiğinde, birçok MVC geliştiricisi JavaScriptSerializer kullanıyor olabilir sınıfını çünkü bu, kutudan çıkan varsayılan seçenek idi.

Eski bir proje (MVC 1 veya MVC 2) üzerinde çalışıyorsanız ve Json.NET kullanamıyorsanız, a List<KeyValuePair<K,V>>yerine a kullanmanızı öneririm Dictionary<K,V>>. Eski JavaScriptSerializer sınıfı, bu türü iyi bir şekilde serileştirecektir, ancak bir sözlükle ilgili sorunları olacaktır.

Belgeler: Koleksiyonları Json.NET ile Seri Hale Getirme


3
Asp.net mvc3 ve mvc4 kullanıcıları için mükemmel cevap
Gomes

JsonConvert.SerializeObject, Javascript'e geri okunduğunda c # sözlüklerini numaralandırılabilir bir koleksiyon türüne serileştirmeyi işliyor gibi görünmüyor. Bunun yerine, C # koleksiyonundaki her bir çiftin artık bir nesnede düz bir özellik / değer olduğu ve bir koleksiyon gibi kolayca numaralandırılamayan bir nesne oluşturur. Bu nedenle, nuget'ten kötü bir sürümüm olmadıkça, Json.NET hala yeterli değil. Bu konuda.
StingyJack

Oh evet. Zaten benzer bir şey yapıyordum ama başka bir yol bulmaya çalışıyordum ve bununla karşılaştım. Bu öğe için Json.NET tavşan deliğinden kaçınmaları gerektiğini başkalarına bildirmenin yararlı olabileceğini düşündüm (aksi halde harika çalışıyor).
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()));
            }
        }
    }
}

Bu konsola yazacak:

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

19

Basit Tek Satır Cevap

( using System.Web.Script.Serialization)

Bu kod herhangi dönüştürür Dictionary<Key,Value>için Dictionary<string,string>ve daha sonra bir JSON dizesi olarak serialize:

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

Dictionary<int, MyClass>Karmaşık türü / nesneyi korurken benzer bir şeyin bu şekilde serileştirilebileceğini belirtmekte fayda var.


Açıklama (arıza)

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

Değişkeni yourDictionarygerçek değişkeninizle değiştirebilirsiniz.

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.

Bunu yapıyoruz, çünkü hem Anahtar hem de Değer, bir 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.

C # cihazımda JavaScriptSerializer yok.
Jonny

1
@Jonny referans derleme System.Web.Extensions msdn.microsoft.com/en-us/library/…
aminhotob

Bunun System.Web.ExtensionsClient Framework sürümünde olmadığını okudum , ancak tam sürümü de gerektiriyor.
vapcguy

Sınırlı uygulamalar için bir çözüm olabilir, ancak tüm değerleri string türüne zorlamak, herhangi bir nesne özelliği tür dizesi değilse doğru JSON'u vermez.
Suncat2000

1
bu konuyla ilgili en iyi cevap.
T.Todua

12

Sözdizimi en küçük bitse özür dilerim ama bunu aldığım kod aslında VB'deydi :)

using System.Web.Script.Serialization;

...

Dictionary<int,List<int>> MyObj = new Dictionary<int,List<int>>();

//Populate it here...

string myJsonString = (new JavaScriptSerializer()).Serialize(MyObj);

2
ArgumentException atar: Type 'System.Collections.Generic.Dictionary`2 bir sözlüğün serileştirilmesi / serileştirilmesi için desteklenmez, anahtarlar dizeler veya nesneler olmalıdır.
Pavel Chuchuva


7

Asp.net Core kullanımında:

using Newtonsoft.Json

var obj = new { MyValue = 1 };
var json = JsonConvert.SerializeObject(obj);
var obj2 = JsonConvert.DeserializeObject(json);

Referans verdim System.Coreve sonra referans vermeye çalıştım using Newtonsoft.Jsonve neşe yok. NewtonsoftÜçüncü taraf bir kitaplık olduğunu düşünüyorum .
vapcguy

2
@vapcguy Evet, Newtonsoft 3. taraftır ancak ürünlerinde MS tarafından da yaygın olarak kullanılmaktadır ve benimsenmektedir. nuget.org/packages/Newtonsoft.Json
Skorunka František

7

Şunları kullanabilirsiniz 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);

2

Bunu yalnızca Microsoft'un standart .Net kitaplıklarını kullanarak nasıl yapacağınız aşağıda açıklanmıştır…

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

Bunu Dictionary<string, dynamic>intergers, floats, booleanlar, stringler, hatta null'lar gibi tüm JSON ilkel türleriyle birleştirebilir ve tek bir nesne içinde kullanabiliriz. +1
Christos Lytras

1

JavaScriptSerializer'ı kullanabilirsiniz .


sözlükler serileştirilebilir mi?
Numenor

Bunun işe yarayacağını düşünürdüm - string json = serializer.Serialize ((object) dict);
Twelve47

1
@Numenor Evet, öyledir, ancak yalnızca Anahtar VE Değer türü ise string. Bakmak isterseniz, burada bunu içeren bir cevap gönderdim.
HowlinWulf

@HowlinWulf daha kesin olmak gerekirse, değerin bir dizge olması gerekmez. Ancak anahtar için kesinlikle bir int olamaz. Dizeler en iyi anahtar olarak çalışır.
Gyum Fox

1
@ Twelve47 Bağlantının taşınması durumunda örnek bir kullanım içermelidir. Aksi takdirde bu cevap bir gün işe yaramaz hale gelebilir.
vapcguy

1

Görünüşe göre pek çok farklı kütüphane var ve önceki yıllarda gelip geçmemiş gibi görünüyor. Ancak Nisan 2016 itibariyle bu çözüm benim için iyi çalıştı. Dizeler kolayca ints ile değiştirilebilir .

TL / DR; Buraya bunun için geldiyseniz bunu kopyalayın:

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

İki ithalat noktası. Öncelikle, Visual Studio'nun Çözüm Gezgini içindeki projenize System.Runtime.Serliazation'ı referans olarak eklediğinizden emin olun. İkincisi, bu satırı ekleyin,

using System.Runtime.Serialization.Json;

Geri kalan kullanımlarınızla birlikte dosyanın en üstünde, böylece DataContractJsonSerializersınıf bulunabilir. Bu blog yazısı , bu serileştirme yöntemi hakkında daha fazla bilgi içermektedir.

Veri Formatı (Giriş / Çıkış)

Verilerim, her biri bir dizgi listesine işaret eden 3 dizeli bir sözlüktür. Dizge listelerinin uzunlukları 3, 4 ve 1'dir. Veriler aşağıdaki gibi görünür:

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

Dosyaya yazılan çıktı tek satırda olacak, işte biçimlendirilmiş çıktı:

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

0

Bu, Meritt'in daha önce yayınladığı şeye benzer. sadece kodun tamamını gönderiyorum

    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

Bağlamınız buna izin veriyorsa (teknik kısıtlamalar, vb.), Newtonsoft.Json'dakiJsonConvert.SerializeObject yöntemi kullanın : hayatınızı kolaylaştıracaktır.

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"}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.