Json.NET VS ASP.NET Ajax Extensions

以前、Json.NETっていう.NETオブジェクトをJSON形式に変換するライブラリを使ってみたけど、ASP.NET Ajax Extensionsにもこれと同等の機能を実現する「JavaScriptSerializer」というのがあった。
ASP.NET Ajax ExtensionsはMicrosoftが作ったフレームワークで.NET 3.5からは標準搭載される代物なので同等の機能を持つなら、標準である方を使っていくべきだと思うけど、せっかくなんで機能を比較してみた。

シリアル

使用する環境:

まずは以下のエンティティクラスを定義する。

class Person {
    private string firstName;
    private string lastName;

    public string FirstName {
        get { return firstName; }
        set { firstName = value; }
    }
    public string LastName {
        get { return lastName; }
        set { lastName = value; }
    }

    public Person() { }
    public Person(string firstName, string lastName) {
        this.firstName = firstName;
        this.lastName = lastName;
    }
}

このクラスのインスタンスJSON文字列に変換する。

static void Main(string[] args) {
    List<Person> dataSet = new List<Person>();
    dataSet.Add(new Person("イングヴェイ", "マルムスティーン"));
    dataSet.Add(new Person("リッチー", "ブラックモア"));
    dataSet.Add(new Person("コージー", "パウエル"));
    dataSet.Add(new Person("ザック", "ワイルド"));
    dataSet.Add(new Person("ランディ", "ローズ"));

    JavaScriptSerializer jsSerializer = new JavaScriptSerializer();
    // ASP.NET
    string aspResult = jsSerializer.Serialize(dataSet);
    // Json.NET
    string jsnResult = JavaScriptConvert.SerializeObject(dataSet);

    Console.WriteLine("ASP.NET:\r\n{0}", aspResult);
    Console.WriteLine("Json.NET:\r\n{0}", jsnResult);
    Console.WriteLine();
    Console.WriteLine("同値?:{0}", aspResult == jsnResult);

    Console.Read();
}

出力:

ASP.NET:
[{"FirstName":"イングヴェイ","LastName":"マルムスティーン"},{"FirstName":"リッチー","LastName":"ブラックモア"},{"FirstName":"コージー","LastName":"パウエル"},{"FirstName":"ザック","LastName":"ワイルド"},{"FirstName":"ランディ","LastName":"ローズ"}]
Json.NET:
[{"FirstName":"イングヴェイ","LastName":"マルムスティーン"},{"FirstName":"リッチー","LastName":"ブラックモア"},{"FirstName":"コージー","LastName":"パウエル"},{"FirstName":"ザック","LastName":"ワイルド"},{"FirstName":"ランディ","LastName":"ローズ"}]

同値?:True

Json.NETでは「JavaScriptConvert」のスタティックメソッド「SerializeObject」を使って変換するのに対して、ASP.NETでは「JavaScriptSerializer」クラスをインスタンス化してから「Serialize」メソッドで変換する。
これは.NETの他のシリアライザ(XmlSerializerとか)と仕様を合わせているからだと思う。

ちなみにそれぞれのシリアル化を10000回ループして時間を計測したら、

ASP.NET
2.3871411秒
Json.NET
2.7162091秒

となって、ASP.NETの方が若干速かった。

逆シリアル化

次はJSON文字列からの逆シリアル化。

static void Main(string[] args) {
    // ...省略

    // ASP.NET
    List<Person> aspObjects = jsSerializer.Deserialize<List<Person>>(aspResult);
    // Json.NET
    List<Person> jsnObjects = JavaScriptConvert.DeserializeObject<List<Person>>(jsnResult);

    Console.WriteLine("ASP.NET:");
    aspObjects.ForEach(delegate(Person o) {
        Console.WriteLine("FirstName: {0}, LastName: {1}", o.FirstName, o.LastName);
    });
    Console.WriteLine("Json.NET:");
    jsnObjects.ForEach(delegate(Person o) {
        Console.WriteLine("FirstName: {0}, LastName: {1}", o.FirstName, o.LastName);
    });
    Console.Read();
}

出力:

ASP.NET:
FirstName: イングヴェイ, LastName: マルムスティー
FirstName: リッチー, LastName: ブラックモア
FirstName: コージー, LastName: パウエル
FirstName: ザック, LastName: ワイルド
FirstName: ランディ, LastName: ローズ
Json.NET:
FirstName: イングヴェイ, LastName: マルムスティー
FirstName: リッチー, LastName: ブラックモア
FirstName: コージー, LastName: パウエル
FirstName: ザック, LastName: ワイルド
FirstName: ランディ, LastName: ローズ

ASP.NETは「Deserialize」メソッドで変換する。Json.NETでは「DeserializeObject」で変換する。両方とも型パラメータで変換先の型を指定するのは同じ。両方ともにジェネリックでないバージョンもある。

こちらも10000回ループして時間を計測してみた。

ASP.NET
3.9397806秒
Json.NET
3.6011121秒

こちらはJson.NETの方が若干速いという結果になった。

カスタマイズ性

○シリアル化/逆シリアル化されるプロパティの制御

ASP.NET
ScriptIgnoreAttribute
Json.NET
JsonIgnoreAttribute

これは両方ともカスタム属性を利用する。

[ScriptIgnore]  // ASP.NET
[JsonIgnore]    // Json.NET
public string FirstName {
    get { return firstName; }
    set { firstName = value; }
}

これをシリアル化すると、

[{"LastName":"マルムスティーン"},{"LastName":"ブラックモア"},{"LastName":"パウエル"},{"LastName":"ワイルド"},{"LastName":"ローズ"}]

FirstNameプロパティがシリアル化されなくなる。

○.NETオブジェクトとJavaScriptオブジェクトのプロパティ名のマッピング

ASP.NET
なし
Json.NET
JsonPropertyAttribute

これはJson.NETにだけある機能。

[JsonProperty("name")]
public string FirstName {
    get { return firstName; }
    set { firstName = value; }
}

これをシリアル化すると、

[{"name":"イングヴェイ","LastName":"マルムスティーン"},{"name":"リッチー","LastName":"ブラックモア"},{"name":"コージー","LastName":"パウエル"},{"name":"ザック","LastName":"ワイルド"},{"name":"ランディ","LastName":"ローズ"}]

FirstNameプロパティが「name」プロパティとしてシリアル化される。その逆もしかり。

・・・

その他

Json.NETだけにある機能

  • XMLJSON形式へのシリアル化/逆シリアル化

・・・