2017年12月08日
川俣晶の縁側ソフトウェア技術雑記total 608 count

C#で使用できるJSONシリアライザで配列を扱えるかを調べる

Written By: 川俣 晶連絡先

問題 §

 JSONシリアライザで配列が正しくシリアライズされない現象に遭遇したので目に付いたシリアライザで一通りチェックしてみた。

前提条件 §

  • 確認日当日(2017/12/08)の状況である
  • DynamicJsonObjectとDynamicJsonArrayとJson.Encodeは同じモジュールに含まれている兄弟クラスである
  • Json.Encodeは下請けとしてJavaScriptSerializerを使用している (ソースコードで確認)

検証ソース §

using System;

using System.Collections.Generic;

using System.Web.Script.Serialization;

using System.Web.Helpers;

using Codeplex.Data;

using Newtonsoft.Json;

class Program

{

    static void Main()

    {

        var obj1 = new

        {

            array1 = new object[] { 123 },

            array2 = new DynamicJsonArray(new object[] { 123 })

        };

        dynamic obj2 = new DynamicJsonObject(new Dictionary<string, object>());

        obj2.array1 = new object[] { 123 };

        obj2.array2 = new DynamicJsonArray(new object[] { 123 });

        foreach (var item in new object[] { obj1, obj2 })

        {

            Console.WriteLine($"target type is {item.GetType().Name}");

            // case of JavaScriptSerializer

            JavaScriptSerializer s = new JavaScriptSerializer();

            var str = s.Serialize(item);

            Console.WriteLine($"JavaScriptSerializer: {str}");

            // case of Json.Encode

            var str2 = Json.Encode(item);

            Console.WriteLine($"Json.Encode:          {str2}");

            // case of DynamicJson

            var str4 = DynamicJson.Serialize(item);

            Console.WriteLine($"DynamicJson:          {str4}");

            // case of Newtonsoft.JSON

            var str5 = JsonConvert.SerializeObject(item);

            Console.WriteLine($"Newtonsoft.JSON:      {str5}");

        }

    }

}

  • System.Web.Helperの参照を追加
  • System.Web.Extensionの参照を追加
  • DynamicJsonをnugetで追加
  • Newtonsoft.JSONをnugetで追加

実行結果 §

target type is <>f__AnonymousType1`2

JavaScriptSerializer: {"array1":[123],"array2":[123]}

Json.Encode:          {"array1":[123],"array2":{}}

DynamicJson:          {"array1":[123],"array2":[123]}

Newtonsoft.JSON:      {"array1":[123],"array2":[123]}

target type is DynamicJsonObject

JavaScriptSerializer: {}

Json.Encode:          {"array1":{},"array2":{}}

DynamicJson:          {}

Newtonsoft.JSON:      {"array1":[123],"array2":[123]}

考察 §

  • Json.EncodeはDynamicJsonArrayを扱うことができないようだ
  • DynamicJsonObjectは配列を受け取ったときにDynamicJsonArrayに変換してしまうため、DynamicJsonObject+Json.Encodeの組み合わせだと配列すら扱えなくなってしまう
  • DynamicJsonObjectはSystem.Web.Helperを利用しないときには使われることはまずあり得ないので、シリアライズできないことは問題ではない。つまり、target type is DynamicJsonObjectのケースで正常に出力できないことは欠陥ではない

結論 §

  • この結果から見る限り、全てのケースにおいてNewtonsoft.JSONが最も優秀である
  • ほぼあり得ないケースを除外すれば、JavaScriptSerializer、DynamicJson、Newtonsoft.JSONの3者のいずれかがお勧めである
  • Json.Encodeを使う場合は、DynamicJsonObjectとDynamicJsonArrayを併用すべきではない
  • Json.Encodeは下請けにJavaScriptSerializerを呼び出しているので、Json.Encodeの利用を取りやめてJavaScriptSerializerに乗り換えても結果は大差ないと推定できる

感想 §

「なぜこんなことを調べた?」

「変な現象を突きつめたらいろいろと変な問題が出てきてね」

「君の個人的なお勧めはなんだい?」

「ここまで調べた範囲では、標準ライブラリにこだわるならJavaScriptSerializer。基本機能だけで良ければシンプルさでDynamicJson、豪華てんこ盛りが欲しければNewtonsoft.JSONが良いのではないかと感じた」

「他には何かあるかい?」

「ネットを検索するとNewtonsoft.JSONの情報が最も多く出てくるから調べやすい。でも、DynamicJsonは作者が日本人なので日本語で質問できる可能性がある。どちらが良いかは決めがたい」

「単なる個人的な印象で好感を持ったのはどれだい?」

「やはりDynamicJsonだな。Newtonsoft.JSONは高機能すぎて迷宮に入りやすい。シンプルですぐソースを見ることができ、適応能力も意外と高いDynamicJsonの評価が跳ね上がった」

Facebook

キーワード【 川俣晶の縁側ソフトウェア技術雑記
【技術雑記】の次のコンテンツ
2017年
12月
15日
LazyInitializer.EnsureInitializedメソッドで初期化しているのにコンストラクタが2回走る
3days 113 count
total 241 count
【技術雑記】の前のコンテンツ
2017年
12月
01日
Skype for Businessで音が出ない問題
3days 63 count
total 816 count
2017年12月08日
川俣晶の縁側ソフトウェア技術雑記total 608 count

C#で使用できるJSONシリアライザで配列を扱えるかを調べる

Written By: 川俣 晶連絡先

問題 §

 JSONシリアライザで配列が正しくシリアライズされない現象に遭遇したので目に付いたシリアライザで一通りチェックしてみた。

前提条件 §

  • 確認日当日(2017/12/08)の状況である
  • DynamicJsonObjectとDynamicJsonArrayとJson.Encodeは同じモジュールに含まれている兄弟クラスである
  • Json.Encodeは下請けとしてJavaScriptSerializerを使用している (ソースコードで確認)

検証ソース §

using System;

using System.Collections.Generic;

using System.Web.Script.Serialization;

using System.Web.Helpers;

using Codeplex.Data;

using Newtonsoft.Json;

class Program

{

    static void Main()

    {

        var obj1 = new

        {

            array1 = new object[] { 123 },

            array2 = new DynamicJsonArray(new object[] { 123 })

        };

        dynamic obj2 = new DynamicJsonObject(new Dictionary<string, object>());

        obj2.array1 = new object[] { 123 };

        obj2.array2 = new DynamicJsonArray(new object[] { 123 });

        foreach (var item in new object[] { obj1, obj2 })

        {

            Console.WriteLine($"target type is {item.GetType().Name}");

            // case of JavaScriptSerializer

            JavaScriptSerializer s = new JavaScriptSerializer();

            var str = s.Serialize(item);

            Console.WriteLine($"JavaScriptSerializer: {str}");

            // case of Json.Encode

            var str2 = Json.Encode(item);

            Console.WriteLine($"Json.Encode:          {str2}");

            // case of DynamicJson

            var str4 = DynamicJson.Serialize(item);

            Console.WriteLine($"DynamicJson:          {str4}");

            // case of Newtonsoft.JSON

            var str5 = JsonConvert.SerializeObject(item);

            Console.WriteLine($"Newtonsoft.JSON:      {str5}");

        }

    }

}

  • System.Web.Helperの参照を追加
  • System.Web.Extensionの参照を追加
  • DynamicJsonをnugetで追加
  • Newtonsoft.JSONをnugetで追加

実行結果 §

target type is <>f__AnonymousType1`2

JavaScriptSerializer: {"array1":[123],"array2":[123]}

Json.Encode:          {"array1":[123],"array2":{}}

DynamicJson:          {"array1":[123],"array2":[123]}

Newtonsoft.JSON:      {"array1":[123],"array2":[123]}

target type is DynamicJsonObject

JavaScriptSerializer: {}

Json.Encode:          {"array1":{},"array2":{}}

DynamicJson:          {}

Newtonsoft.JSON:      {"array1":[123],"array2":[123]}

考察 §

  • Json.EncodeはDynamicJsonArrayを扱うことができないようだ
  • DynamicJsonObjectは配列を受け取ったときにDynamicJsonArrayに変換してしまうため、DynamicJsonObject+Json.Encodeの組み合わせだと配列すら扱えなくなってしまう
  • DynamicJsonObjectはSystem.Web.Helperを利用しないときには使われることはまずあり得ないので、シリアライズできないことは問題ではない。つまり、target type is DynamicJsonObjectのケースで正常に出力できないことは欠陥ではない

結論 §

  • この結果から見る限り、全てのケースにおいてNewtonsoft.JSONが最も優秀である
  • ほぼあり得ないケースを除外すれば、JavaScriptSerializer、DynamicJson、Newtonsoft.JSONの3者のいずれかがお勧めである
  • Json.Encodeを使う場合は、DynamicJsonObjectとDynamicJsonArrayを併用すべきではない
  • Json.Encodeは下請けにJavaScriptSerializerを呼び出しているので、Json.Encodeの利用を取りやめてJavaScriptSerializerに乗り換えても結果は大差ないと推定できる

感想 §

「なぜこんなことを調べた?」

「変な現象を突きつめたらいろいろと変な問題が出てきてね」

「君の個人的なお勧めはなんだい?」

「ここまで調べた範囲では、標準ライブラリにこだわるならJavaScriptSerializer。基本機能だけで良ければシンプルさでDynamicJson、豪華てんこ盛りが欲しければNewtonsoft.JSONが良いのではないかと感じた」

「他には何かあるかい?」

「ネットを検索するとNewtonsoft.JSONの情報が最も多く出てくるから調べやすい。でも、DynamicJsonは作者が日本人なので日本語で質問できる可能性がある。どちらが良いかは決めがたい」

「単なる個人的な印象で好感を持ったのはどれだい?」

「やはりDynamicJsonだな。Newtonsoft.JSONは高機能すぎて迷宮に入りやすい。シンプルですぐソースを見ることができ、適応能力も意外と高いDynamicJsonの評価が跳ね上がった」

Facebook

キーワード【 川俣晶の縁側ソフトウェア技術雑記
【技術雑記】の次のコンテンツ
2017年
12月
15日
LazyInitializer.EnsureInitializedメソッドで初期化しているのにコンストラクタが2回走る
3days 113 count
total 241 count
【技術雑記】の前のコンテンツ
2017年
12月
01日
Skype for Businessで音が出ない問題
3days 63 count
total 816 count
【技術雑記】のコンテンツ全リスト【技術雑記】の表紙

このコンテンツを書いた川俣 晶へメッセージを送る

[メッセージ送信フォームを利用する]

メッセージ送信フォームを利用することで、川俣 晶に対してメッセージを送ることができます。

この機能は、100%確実に川俣 晶へメッセージを伝達するものではなく、また、確実に川俣 晶よりの返事を得られるものではないことにご注意ください。

このコンテンツへトラックバックするためのURL

http://mag.autumn.org/tb.aspx/20171208163444
サイトの表紙【技術雑記】の表紙【技術雑記】のコンテンツ全リスト 【技術雑記】の入手全リスト 【技術雑記】のRSS1.0形式の情報このサイトの全キーワードリスト 印刷用ページ

管理者: 川俣 晶連絡先

Powered by MagSite2 Version 0.25 (Alpha-Test) Copyright (c) 2004-2017 Pie Dey.Co.,Ltd.