積み上げる無駄知識

無駄ではないと信じる

【VB.net】Newtonsoft.Jsonで任意のJsonオブジェクトを三枚卸にする

.NET Framework上でJsonファイルを解析するとき、便利なのがNewtonsoft.Jsonライブラリです。

ただ、公式ドキュメントは全部英語でしかも何やってるのかさっぱりわかりませんでした。マジで。

初見で使ったときなにがなんだか分からなかったので、せめてデシリアライズの方法くらいを書きます。

ポイントは型指定です。

言語は推しのVB.netです。これしか知らないとも言います。

それでは、こいつで任意のJsonファイルを三枚卸にしてやりましょう。

はじめに

前提として、Newtonsoft.JsonをNugetしておいてください。 また、

Imports Newtonsoft.Json

を先頭に書いておいてください。 さて、サンプルとして以下のJsonオブジェクトを考えます。

{
    "key1":"key1Value",
    "key2":"key2Value",
    "Array1":[
        {"ArrayKey1":"ArrayValue1"},
        {"ArrayKey2":"ArrayValue2"}
    ],
    "InnerObject":{
        "InnerKey1":"InnerValue1",
        "InnerArray":[
            {"InnerArray1":"InnerArrayValue1"},
            {"InnerArray2":"InnerArrayValue2"}
        ]
    }
}

シンプルなキー・バリュー値、配列、入れ子になったオブジェクトが含まれています。

こいつのデシリアライズをするだけなら1行で済みます。

Dim JsonString As String = "上述のJson文字列を代入してください"
Dim Deserialized As Object = JsonConvert.DeserializeObject(JsonString)

Deserialized変数にデシリアライズされたJsonオブジェクトが入っています。

が、こいつがObject型でもう全くもって操作ができません。不便極まりない。

そこで、主題となる型指定へ話を進めます。

Jsonフォーマットクラス

型を指定する

さっき使ったDeserializeObjectはいくつかのオーバーロードメソッドが存在します。

その中に、指定した型でデシリアライズするものがあります。

JsonConvert.DeselializeObject(Of T)(value As String)

型を指定してやると、うまく内部データにアクセスできそうですね。

ただ、この型の書き方を理解するのにかなりハマってしまいました。

基本的には簡単な原則に従ってクラスを定義していくだけです。

それでは見ていきましょう。

具体的な型の定義方法

一番初めにすること

クラスを定義します。

ここで定義したクラスはデシリアライズしたいJsonファイルのフォーマットクラスになります。

Public Class SampleFormatClass

End Class
キー・バリュー

キー・バリュー値はクラスのプロパティとして定義することで表現します。

プロパティ名は、そのJsonファイルと同名が良いでしょう。

Public Class SampleFormatClass
    Public Property Key1 As String
    Public Property Key2 As String
End Class
配列

配列は、内部に配列要素のクラスを作成し、そのリストをプロパティとして定義することで表現します。

なんのこっちゃ分からないかもしれませんが、上で定義したものに付け足して書くとこんな感じです。

  Public Class SampleFormatClass
    Public Property Key1 As String
    Public Property Key2 As String
    Public Property Array1 As List(Of ArrayData)
      
      Public Class ArrayData
        Public Property ArrayKey1 As String
        Public Property ArrayKey2 As String
      End Class
  End Class

マジかって感じの構造ですが、マジです。

入れ子になったオブジェクト

内部にオブジェクトのクラスを作成し、その型で値をプロパティとして定義することで表現します。 最初にフォーマットクラスを定義したのを内部でやる感じです。 オブジェクト自体は配列のように複数の項目を持ちませんので、リストとして定義はしません。 上で定義したものに付け足して書くとこんな感じです。

    Public Class SampleFormatClass
      Public Property Key1 As String
      Public Property Key2 As String
      
      Public Property Array1 As List(Of ArrayData)  
      Public Class ArrayData
          Public Property ArrayKey1 As String
          Public Property ArrayKey2 As String
      End Class
      
      Public Property InnerObject As InnerObjectData
      Public Class InnerObjectData
          Public Property InnerKey1 As String
              
          Public Property InnerArray As List(Of InnerArrayData)
          Public Class InnerArrayData
              Public Property InnerArray1 As String
              Public Property InnerArray2 As String
          End Class
      End Class
    End Class

InnerObjectクラスは中身を一気に書いていますが、基本的には上記原則に従っているだけです。 さて、この出来上がったヤバい構造のSampleFormatClassを使ってサンプルJsonをデシリアライズしてみましょう!

  Dim DeserializedUsingFormat As SampleFormatClass = _
          JsonConvert.DeselializeObject(Of SampleFormatClass)(JsonString)
  
  Console.Writeline(DeserializedUsingFormat.Key1)
  '出力は"Key1Value"

型指定されていると、そのプロパティで中のデータにすべてアクセスできます! もうObject型とはおさらばです。やったね。