WebSurfer's Home

トップ > Blog 1   |   Login
Filter by APML

異種の要素を含む JSON 配列のデシリアライズ

by WebSurfer 5. March 2023 13:14

JSON の配列で string, number, true/false, null, array, object など異種の要素が混ざったものを、デシリアライザに Newtonsoft.Json および System.Text.Json を使って .NET のオブジェクトに変換するとどうなるかを書きます。

デシリアライズ結果

上の画像の前者 result1.Data が Newtonsoft.Json を使った結果、後者 result2.Data が System.Text.Json を使った結果です。

Data は両方とも object[] 型で、その各要素も object 型ですが、その中身が違うところに注目してください。それがこの記事で書きたかったことです。

この例ほど多種の要素が混じっている配列というケースは実際にはないかもしれませんが、"NaN" という文字列と number ぐらいならあるかもしれません。なので、違いを覚えておくと役に立つかもしれないと思って備忘録として残しておくことにしました。

上の画像を表示するのに具体的のどのようにしたかを以下に書いておきます。

まず、元になる JSON 文字列ですが、以下の通りです。

{
  "Header": {
    "Id": 10,
    "Name": "Test Data"
  },
  "Data": [
    "NaN",
    -0.010565,
    true,
    10,
    1.02e2,
    null,
    [ "abc", "def", "ghi" ],
    { "Object": "test" }
  ]
}

Visual Studio の機能を使って上の JSON 文字列から C# のクラス定義を生成すると以下のようになります。やり方は先の記事「JSON 文字列から C# のクラス定義生成」を見てください。

public class Rootobject
{
    public Header Header { get; set; }
    public object[] Data { get; set; }
}

public class Header
{
    public int Id { get; set; }
    public string Name { get; set; }
}

"Data" は object[] 型にデシリアライズするという点に注目してください。

Newtonsoft.Json および System.Text.Json を使って JSON 文字列を上の C# のオブジェクトにデシリアライズします。コードは以下の通りです。ターゲットフレームワーク .NET 7.0 のコンソールアプリを使いました。

string filepath = @"C:\Users\...\json1.json";
string jsonString = "";
using (StreamReader sr = File.OpenText(filepath))
{
    jsonString = sr.ReadToEnd();
}

// Newtonsoft.Json
var result1 = Newtonsoft.Json.JsonConvert
              .DeserializeObject<Rootobject>(jsonString);

// System.Text.Json
var result2 = System.Text.Json.JsonSerializer
              .Deserialize<Rootobject>(jsonString);

上のコードを Visual Studio 2022 でデバッグ実行し、ブレークポイントで止めて変数 result1 と result2 の中身を表示したのがこの記事の一番上の画像です。

Tags: , ,

.NET Framework

.NET の多次元配列の JSON シリアル化

by WebSurfer 14. December 2022 18:06

Newtonsoft.Json のシリアライザなら .NET の多次元配列を JSON 文字列にシリアライズできるという話を書きます。何を今さらと言われそうですが。(汗)

Newtonsoft.Json

System.Text.Json 名前空間のシリアライザは多次元配列の JSON シリアル化をサポートしていないようで、試してみましたが System.NotSupportedException がスローされ "The type 'System.String[,,]' is not supported." というエラーメッセージが出ます。(ジャグ配列ならサポートしていることは確認しました)

なので、調べもしないで Newtonsoft.Json も同じだと思っていたのですが、Json.NET 4.5 Release 8 – Multidimensional Array Support, Unicode Improvements によると 10 年も前から多次元配列のシリアライズをサポートしているとのことです。

Microsoft のドキュメント「Newtonsoft.Json と System.Text.Json を比較して、System.Text.Json に移行する」にもいろいろ書いてありますが、多次元配列のサポートについては言及してないです。「さまざまな型のサポート ⚠」に含むのでしょうか?

実際にコードを書いて、Newtonsoft.Json が多次元配列とジャグ配列の両方のシリアライズ/デシリアライズをサポートしていることは確認しました。以下に検証に使ったコードを載せておきます。.NET Framework 4.8.1 のコンソールアプリです。

using Newtonsoft.Json;
using System;

namespace ConsoleAppArrayJson
{
    internal class Program
    {
        static void Main(string[] args)
        {
            // 多次元配列
            var mdArray = new string[30, 12, 31];
            for (int i = 0; i < 30; i++)
            {
                for (int j = 0; j < 12; j++)
                {
                    for (int k = 0; k < 31; k++)
                    {
                        mdArray[i, j, k] = $"e-{i}-{j}-{k}";
                    }
                }
            }

            // ジャグ配列
            var jArray = new string[30][][];
            for (int i = 0; i < 30; i++)
            {
                jArray[i] = new string[12][];
                for (int j = 0; j < 12; j++)
                {
                    jArray[i][j] = new string[31];
                    for (int k = 0; k < 31; k++)
                    {
                        jArray[i][j][k] = $"e-{i}-{j}-{k}";
                    }
                }
            }

            // 多次元配列を JSON 文字列にシリアライズ
            var json1 = JsonConvert.SerializeObject(mdArray);

            // ジャグ配列を JSON 文字列にシリアライズ
            var json2 = JsonConvert.SerializeObject(jArray);

            // json1 == json2 は true になる
            Console.WriteLine($"json1 == json2: {json1 == json2}");

            // JSON 文字列を多次元配列にデシリアライズ
            var array1 = JsonConvert.DeserializeObject<string[,,]>(json1);
            Console.WriteLine($"array1[0,1,2]: {array1[0, 1, 2]}");

            // JSON 文字列をジャグ配列にデシリアライズ
            var array2 = JsonConvert.DeserializeObject<string[][][]>(json2);
            Console.WriteLine($"array2[0][1][2]: {array2[0][1][2]}");
        }
    }
}

上のコードの実行結果は以下のようになります。

実行結果

Tags: , , ,

.NET Framework

PostgreSQL とデータソース構成ウィザード

by WebSurfer 5. October 2022 16:14

PostgreSQL の既存のデータベースから Visual Studio 2022 のデータソース構成ウィザードを利用して型付 DataSet / DataTable + TableAdapter を作ることができます。それを使って、DB のレコードの一覧表示・編集ができる Windows Forms + GataGridView アプリを容易に作成できます。

Windows Forms + GataGridView アプリ

SQL Server の場合は当たり前の話なので何をいまさらと言われるかもしれませんが、先日初めて PostgreSQL をインストールしたので試してみた次第です。

(ASP.NET MVC5 アプリで Entity Framework 6 を使って PostgreSQL の既存の DB の CRUD を行う場合については、先の記事「PostgreSQL で EF6 DB First」に書きましたので、興味があれば見てください)

この記事を書いた時の環境は以下の通りです。

  • PostgreSQL 14.4
  • Visual Studio Community 2022 17.3.5
  • Npgsql PostgreSQL Integration 4.1.12
  • Npgsql 6.0.7
  • .NET Framework 4.8
  • Windows フォームアプリケーション (.NET Framework)

Visual Studio で PostgreSQL に対してデータソース構成ウィザードが使えるようにするには Npgsql PostgreSQL Integration という拡張機能の追加が必要です。下の画像のバージョン 4.1.12 は Visual Studio 2022 用にリリースされたものだそうです。

Npgsql PostgreSQL Integration

拡張機能の追加後、Microsoft のドキュメント「新しいデータ ソースの追加」のようにデータソース構成ウィザードを起動すれば、「データ接続の選択」で PostgreSQL Database を選択できるようになります。

データ接続の選択

以下のように PostgreSQL への接続情報を設定して接続できれば、

接続情報を設定

そのあとは SQL Server とほぼ同様な手順で DataSet(xsd ファイル)を作成できます。

DataSet(xsd ファイル)

xsd ファイルが作成できると、デザイン画面でデータソースウィンドウに DataSet / DataTable が表示されるので (下の画像で MovieDataSet / Movie)、DataTable (Movie) の DataGridView を選択してから Form にドラッグ&ドロップします。

データソースウィンドウの DataSet / DataTable

上の画像はドラッグ&ドロップして必要なコードがすべて生成された後、DataGridView.Dock プロパティを Fill に設定したものです。

次に NuGet から Npgsql をインストールします。

NuGet から Npgsql をインストール

その後ソリューションをビルドして実行すればこの記事の一番上の画像のようなアプリが動きます。DataGridView を編集した結果も期待通り DB に反映されます。

ただ、微妙なところがあって、なぜか Npgsql のインストールのタイミングが問題で、自分の環境で試した時は以下の順番で行う必要がありましたので注意してください。

  1. データソース構成ウィザードを起動し型付 DataSet / DataTable + TableAdapter を生成
  2. 「データソース」ウィンドウから作成した DataTable を Form にドラッグ&ドロップ
  3. NuGet から Npgsql をインストール
  4. ソリューションをビルド

想像ですが、データソース構成ウィザードが使う Npgsql と NuGet からインストールする Npgsql やその他の関係 dll とのバージョンの不整合が問題ではないかと思われます。

Tags: , ,

.NET Framework

About this blog

2010年5月にこのブログを立ち上げました。その後ブログ2を追加し、ここはプログラミング関係、ブログ2はそれ以外のトピックスに分けました。

Calendar

<<  March 2023  >>
MoTuWeThFrSaSu
272812345
6789101112
13141516171819
20212223242526
272829303112
3456789

View posts in large calendar