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


130

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


3
newtonSoft.json nugetパッケージを使用します。JsonConvert.SerializeObject(yourObject)
RayLoveless

回答:


118

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

以下のために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は人気のあるオプションです。


66
このソリューションはせいぜい素朴です。実際のjsonシリアライゼーションライブラリを使用します。
jacobsimeon

131
@ジェイコブ-ナイーブ?痛い。個人的には、必要なすべてが1つの短くて簡単な方法で達成できる場合、別のアセンブリを含めることは正当化できません。
gilly3

16
もう1つ+ gilly3のコメント。Windows Phoneでコーディングしていることがあります。zlip、twitter、google、オーディオ処理、画像処理などを追加します。このような単純なメソッドと、使用法が単純な場合はソーシャルメディアとの対話のためのいくつかの基本的なHttpRequestを実装する方が適切です。アセンブリを追加するときは、常にバグに対処する必要があり、ライトバージョンを取得することは不可能です。ちなみに、json libsの中には、このような素朴なメソッドがあり、魔法はありません。
レオンペルティエ2013年

14
開いているすべてのプロジェクトに、「ほとんどの場合、この10行だけを実行するだけです。コードは次のとおりです。」というページがあります。
レオンペルティエ2013年

31
dict.add( "RandomKey \" "、" RandomValue \ ""); BOOOOOOOOOOOOOOOOM。せいぜい素朴。実際のjsonシリアライゼーションライブラリを使用します。
スリーパースミス

112

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

return JsonConvert.SerializeObject( myDictionary );

JavaScriptSerializerとmyDictionaryは異なり<string, string>、JsonConvertが機能するためには、型の辞書である必要はありません。


71

Json.NETはおそらくC#辞書を適切にシリアライズしますが、OPが最初にこの質問を投稿したとき、多くのMVC開発者がJavaScriptSerializerを使用していた可能性がありますクラスあります。

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

ドキュメント:Json.NETを使用したコレクションのシリアル化


3
asp.net mvc3およびmvc4ユーザーのための完全な回答
Gomes

JsonConvert.SerializeObjectは、JavaScriptに読み戻されたときに、列挙可能なコレクションのタイプへのc#辞書のシリアル化を処理しないようです。むしろ、C#コレクションの各ペアがオブジェクトのプレーンプロパティ/値になり、コレクションのように簡単に列挙できないオブジェクトを作成します。したがって、nugetからの不良バージョンがない限り、Json.NETはこの点でまだ十分ではありません。
StingyJack 2015年

ああ、そうです。私はすでに同じようなことをしていましたが、別の方法を見つけようとして、これに出くわしました。このアイテムのJson.NETのうさぎの穴を回避するために他の人に知らせることは便利だと感じました(そうでない場合はうまく機能します)。
StingyJack 2015年

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

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

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

シンプルな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.

C#にJavaScriptSerializerがありません。
Jonny

1
あなたは、参照アセンブリのSystem.Web.Extensionsが欠落している@Jonny msdn.microsoft.com/en-us/library/...
aminhotob

System.Web.Extensionsクライアントフレームワークバージョンにはないことを読みましたが、フルバージョンも必要です。
vapcguy 2017年

限られたアプリケーションの解決策になる可能性がありますが、オブジェクトのプロパティが文字列型でない場合、すべての値を文字列型に強制しても正しいJSONが生成されません。
Suncat2000 2017

1
このトピックに関する最良の回答。
T.Todua 2018年

12

構文がほんの少しずれているだけで申し訳ありませんが、これを取得しているコードはもともと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);

2
ArgumentExceptionがスローされます。タイプ 'System.Collections.Generic.Dictionary`2は、辞書のシリアル化/逆シリアル化ではサポートされていません。キーは文字列またはオブジェクトである必要があります。
Pavel Chuchuva、2011


7

Asp.net Coreで:

using Newtonsoft.Json

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

私は参照しSystem.Core、参照しようusing Newtonsoft.Jsonとしたが喜びはなかった。Newtonsoftサードパーティのライブラリだと思います。
vapcguy

2
@vapcguyはい、Newtonsoftはサードパーティですが、MSの製品でも広く使用および採用されています。nuget.org/packages/Newtonsoft.Json
SkorunkaFrantišek

7

使用できます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

ここでは、Microsoftの標準.Netライブラリのみを使用して行う方法を説明します。

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

これを組み合わせて、Dictionary<string, dynamic>整数、浮動小数点数、ブール値、文字列、nullのようなすべてのJSONプリミティブ型を1つのオブジェクト内に含めることができます。+1
クリストスリトラス

1

辞書はシリアライズ可能ですか?
Numenor

私はこれがうまくいくと思っていたでしょう-string json = serializer.Serialize((object)dict);
Twelve47

1
@Numenorはい、そうです。ただし、キーと値のタイプがの場合のみですstring。ご覧になりたい場合は、それを含む回答をこちらに投稿しました。
HowlinWulf 14

@HowlinWulfより正確には、値は文字列である必要はありません。しかし、キーにとって、それは間違いなくintになることはできません。文字列はキーとして最適です。
Gyum Fox

1
@ Twelve47リンクが移動した場合に備えて、サンプルの使用法を含める必要があります。そうでなければ、この答えはいつか役に立たなくなるかもしれません。
vapcguy 2017

1

それは多くの異なるライブラリーのようであり、過去数年にわたって行き来していないように見えます。ただし、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"]
 }]

0

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

    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

コンテキストで許可されている場合(技術的な制約など)、Newtonsoft.JsonJsonConvert.SerializeObjectメソッドを使用します。これにより、作業が楽になります。

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"}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.