C#でJsonシリアライズについてのメモ

C#を触り始めて、Jsonシリアライズする必要があったのでいくつかライブラリを調べたのでメモ.
C#ははじめてまだ数日なので全然慣れてないけど、なるべく直感的に扱えそうなのを探してみた。

標準でサポートされているJsonライブラリ

System.Runtime.Serialization.Json

.Net Framework 3.5以上でサポート.
最初に使ってハマったのが、参照の追加でSystem.ServiceModelを追加しなければならないこと.
その後using System.Runtime.Serialization.Json;と定義すればOK.名前を統一してほしい...

JavaScriptSerializerクラス

.Net Framwork 4.5からサポート
System.Web.Extensions.dllを参照して使用することができる.


すべて調査したわけではないけれど、標準ライブラリの場合は、基本的にオブジェクトのプロパティがJsonのキーになり,その値がそのままJsonの値に変換されるといった感じ。動的にキーを追加したい場合は使いにくい印象。

3rdパーティ製Jsonライブラリ

DynamicJson

Ms-PLライセンス
候補の一つで使ってみたJsonライブラリ. C#4.0のdynamicを用いたJsonライブラリ.軽量.

JSON.NET

MITライセンス
.Net Framework 2/3.5/4

やりたかったこと

とりあえずJsonの配列を動的に作成できること。Pythonの辞書のように、dic["foo"] = "bar" としてリストにいれて,シリアライズしたらそのままJson文字列になるようなことがやりたい。 下記のような感じで,配列に動的に生成した要素を入れたい。


{ "hoge" : [ { "key1" : "val1" }, { "key2" : "val2" } ] }

DynamicJson

まだきちんと理解していないので、使い方が間違っているかもしれないです。
DynamicJsonを用いる場合は、参照の追加からダウンロードしたDynamicJson.dllを追加し、行頭で以下を定義する。


using Codeplex.Data;

DynamicJsonはオブジェクトからJson変換もできるけど、Jsonオブジェクトを直接生成することもできるようだ。


dynamic fac1 = new DynamicJson() {};
dynamic fac2 = new DynamicJson() {};

fac1["key1"] = "val1";
fac2["key2"] = "val2";

ただ、このfac1,fac2をあるキーの値として代入したり、配列の要素にしようとするとシリアライズができない。

dynamic test = new DynamicJson() {};

test["hoge"] = fac1;
test["geho"] = fac2;

Console.WriteLine(test.ToString());

結果は以下のようになった.

{ "hoge" : { "IsObject" : true, "IsArray" : false }, "geho" : { "IsObject" : true, "IsArray" : false } }

以下のように配列に入れた場合も、オブジェクトの内容がシリアライズされない。


test["array"] = new [] { fac1, fac2 }

辞書オブジェクトを入れた場合だと、辞書のキーが値として展開されてシリアライズされる。


IDictionary dic = new Dictionary();

dic.Add("foo", "bar");
var json = DynamicJson.Serialize(dic);

Console.WriteLine(json);

結果は以下のようになり、辞書のキーと値がJsonのキーと値に対応するわけではないようだ。


{ "Key" : "foo", "Value" : "bar" }

JSON.NET

JSON.NETを用いる場合は、参照の追加からダウンロードしたNewtonsoft.Json.dllを追加する。
そして以下を定義。


using Newtonsoft.Json;

辞書オブジェクトをJsonシリアライズしてみる.


string json;
IDictionary dic = new Dictionary();

dic.Add("foo", "bar");

json = JsonConvert.SerializeObject(dic);

Console.WriteLine(json);

結果は、辞書のキー/値がJsonのキーと値に対応されてシリアライズされた。

{ "foo" : "bar" }

辞書オブジェクトを配列にいれてシリアライズしてみる.


string json;
IDictionary dic = new Dictionary();
IDictionary[] array = new Dictionary[1];

dic.Add("foo", "bar");

array[0] = dic;

json = JsonConvert.SerializeObject(array);
Console.WriteLine(json);

結果は以下のようになり、Jsonの配列がシリアライズされた.


[ {"foo" : "bar"} ]