web-dev-qa-db-ja.com

辞書をC#でJSON文字列に変換するにはどうすればよいですか?

Dictionary<int,List<int>>をJSON文字列に変換したい。誰でもC#でこれを達成する方法を知っていますか?

110
daehaai

数値またはブール値のみを含むデータ構造のシリアル化は非常に簡単です。シリアライズするものがあまりない場合は、特定のタイプのメソッドを作成できます。

指定したDictionary<int, List<int>>には、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) + "}";
}

しかし、いくつかの異なるクラス、またはより複雑なデータ構造をシリアル化する場合、、または特にデータに文字列値が含まれる場合、エスケープ文字や改行などの処理方法をすでに知っている評判の良いJSONライブラリを使用する方が良いでしょう。 Json.NET は人気のあるオプションです。

107
gilly3

この回答 はJson.NETに言及していますが、Json.NETを使用して辞書をシリアル化する方法を説明するまでには至っていません。

return JsonConvert.SerializeObject( myDictionary );

JavaScriptSerializerとは対照的に、myDictionaryは、JsonConvertが機能するためにタイプ<string, string>の辞書である必要はありません。

70
David Kennedy

Json.NET おそらく今ではC#辞書を適切にシリアル化していますが、OPが最初にこの質問を投稿したとき、多くのMVC開発者はデフォルトオプションであったため JavaScriptSerializer クラスを使用していた可能性がありますボックスの。

レガシープロジェクト(MVC 1またはMVC 2)で作業していて、Json.NETを使用できない場合は、List<KeyValuePair<K,V>>ではなくDictionary<K,V>>を使用することをお勧めします。従来のJavaScriptSerializerクラスはこの型を適切にシリアル化しますが、辞書に問題があります。

ドキュメント:Json.NETでのコレクションのシリアル化

70
Jim G.
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()));
            }
        }
    }
}

これはコンソールに書き込みます:

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

シンタックスが最も小さい場合は申し訳ありませんが、私がこれを取得しているコードは元々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
riwalk

簡単な1行の回答

using System.Web.Script.Serialization

このコードは、Dictionary<Key,Value>Dictionary<string,string>に変換し、それをJSON文字列としてシリアル化します:

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

Dictionary<int, MyClass>のようなものも、複雑な型/オブジェクトを保持しながら、この方法でシリアル化できることに注意する価値があります。


説明(内訳)

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

変数yourDictionaryを実際の変数に置き換えることができます。

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.

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.
11
HowlinWulf

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
Salim

Asp.net Coreでは次を使用します。

using Newtonsoft.Json

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

多くの異なるライブラリがあり、過去何年も行き来していないようです。しかし、2016年4月の時点で、このソリューションはうまく機能しました。 文字列はintに簡単に置き換えられます。

TL/DR;あなたがここに来たのであれば、これをコピーしてください:

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

2つのインポートポイント。まず、Visual Studioのソリューションエクスプローラー内のプロジェクトの参照としてSystem.Runtime.Serliazationを必ず追加してください。次に、この行を追加し、

using System.Runtime.Serialization.Json;

残りの使用方法を含むファイルの先頭にあるため、DataContractJsonSerializerクラスが見つかります。この ブログ投稿 には、このシリアル化の方法に関する詳細情報があります。

データ形式(入力/出力)

私のデータは、それぞれが文字列のリストを指す3つの文字列を持つ辞書です。文字列のリストの長さは3、4、および1です。データは次のようになります。

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

ファイルに書き込まれる出力は1行になります。フォーマットされた出力は次のとおりです。

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

JavaScriptSerializer を使用できます。

1
Twelve47

これは、以前にMerittが投稿したものに似ています。完全なコードを投稿するだけ

    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
Karshan