【VB.NET/.NET8】System.Text.JsonでJSON文字列をオブジェクトにデシリアライズする方法

こんにちは!

前回の記事では、.NET 8 における標準ライブラリ System.Text.Json を使って、VB.NETでオブジェクトをJSON文字列にシリアライズする方法をご紹介しました。

今日はその逆!
「JSON文字列をVB.NETのオブジェクトに変換する方法」=デシリアライズについて、詳しく解説していきたいと思います!

たとえばWeb APIから受け取ったJSONレスポンスを、自分のアプリケーションで扱いやすい形にしたいとき。
そんなときに役立つのが、JsonSerializer.Deserialize(Of T) メソッドです。


基本のデシリアライズ:JSONをオブジェクトに変換する

まずは、基本の Person クラスを用意します。

Public Class Person
    Public Property Id As Integer
    Public Property Name As String
End Class

そして、対応するJSON文字列がこちら。

{"Id":1,"Name":"Taro"}

これをVB.NETでデシリアライズしてみましょう。

Imports System.Text.Json

Dim json As String = "{\"Id\":1,\"Name\":\"Taro\"}"

Dim person As Person = JsonSerializer.Deserialize(Of Person)(json)

Console.WriteLine($"{person?.Id}, {person?.Name}")

出力結果:

1, Taro

すごく簡単ですね。
クラスとJSONの形さえ合っていれば、あっという間にオブジェクトに変換できます!


プロパティ名が小文字(camelCase)のJSONをデシリアライズする

JavaScriptでは、よくプロパティ名が小文字(camelCase)になっていることがあります。
例えばこんなJSON。

{"id":2,"name":"Jiro"}

でも、VB.NETのクラス側では IdName とPascalCaseで書いているので、そのままだとマッピングされません。

こんなときは、JsonSerializerOptions を使って「大文字小文字を無視する」設定をします!

Dim options As New JsonSerializerOptions With {
    .PropertyNameCaseInsensitive = True
}

Dim json As String = "{\"id\":2,\"name\":\"Jiro\"}"

Dim person As Person = JsonSerializer.Deserialize(Of Person)(json, options)

Console.WriteLine($"{person?.Id}, {person?.Name}")

出力結果:

2, Jiro

これならcamelCaseでも気にせず使えますね。


配列のデシリアライズ

複数の Person オブジェクトが入ったJSON配列も、もちろんデシリアライズできます!

こんなJSONを用意してみましょう。

[
  {"Id":1,"Name":"Taro"},
  {"Id":2,"Name":"Jiro"}
]

コードはこうなります。

Dim jsonArray As String = "[{\"Id\":1,\"Name\":\"Taro\"},{\"Id\":2,\"Name\":\"Jiro\"}]"

Dim people As Person() = JsonSerializer.Deserialize(Of Person())(jsonArray)

For Each p In people
    Console.WriteLine($"{p.Id}, {p.Name}")
Next

出力結果:

1, Taro
2, Jiro

もちろん、配列だけでなく List(Of Person) にもできます!

Dim peopleList As List(Of Person) = JsonSerializer.Deserialize(Of List(Of Person))(jsonArray)

柔軟ですね。


ネストされたオブジェクトのデシリアライズ

次は、オブジェクトの中に配列がある、ちょっと複雑なJSONにチャレンジしてみます!

{
  "GroupId": 1,
  "People": [
    { "Id": 1, "Name": "Taro" },
    { "Id": 2, "Name": "Jiro" }
  ]
}

これに対応するクラスはこんな感じです。

Public Class Group
    Public Property GroupId As Integer
    Public Property People As Person()
End Class

デシリアライズしてみましょう。

Dim json As String = "
{
  ""GroupId"": 1,
  ""People"": [
    { ""Id"": 1, ""Name"": ""Taro"" },
    { ""Id"": 2, ""Name"": ""Jiro"" }
  ]
}"

Dim group As Group = JsonSerializer.Deserialize(Of Group)(json)

Console.WriteLine($"Group ID: {group?.GroupId}")
For Each p In group?.People
    Console.WriteLine($"- {p.Id}, {p.Name}")
Next

出力結果:

Group ID: 1
- 1, Taro
- 2, Jiro

入れ子になったデータも、きちんとクラス構造を合わせれば問題なく扱えます!


JsonPropertyName属性を使ったマッピング

プロパティ名を自由にマッピングしたいときは、JsonPropertyName 属性が便利です。

例えば、クラスをこんなふうに書きます。

Imports System.Text.Json.Serialization

Public Class Person
    <JsonPropertyName("id")>
    Public Property Id As Integer

    <JsonPropertyName("name")>
    Public Property Name As String
End Class

すると、JSONがこんな感じでも…

{"id":3,"name":"Saburo"}

デシリアライズできちゃいます!

Dim json As String = "{\"id\":3,\"name\":\"Saburo\"}"

Dim person As Person = JsonSerializer.Deserialize(Of Person)(json)

Console.WriteLine($"{person?.Id}, {person?.Name}")

便利すぎますね。


デシリアライズの失敗と例外処理

もしJSONの形式が間違っていたら?
そんなときは JsonException が発生します。

例えば、こんな無茶なJSON。

Dim invalidJson As String = "{\"Id\": \"NotAnInt\", \"Name\": \"Taro\"}"

Try
    Dim person As Person = JsonSerializer.Deserialize(Of Person)(invalidJson)
Catch ex As JsonException
    Console.WriteLine("デシリアライズに失敗しました: " & ex.Message)
End Try

デシリアライズはわりと失敗しやすいので、Try-Catch でしっかりエラーハンドリングしておくと安心です!


nullの扱いに注意

Deserialize(Of T) は、うまくいかなかったときに Nothing を返すこともあります。
なので、使うときは必ず nullチェック(Nothingチェック)を入れるクセをつけておきましょう。


パフォーマンスとセキュリティの注意点

  • デシリアライズするJSONは「信頼できるデータ」だけにしましょう。
  • System.Text.Jsonは高速ですが、特殊なケース(型推論が必要なポリモーフィズムなど)には弱いです。
  • 外部から受け取ったJSONをそのままデシリアライズするのはちょっと危ない場面もあります。ちゃんとバリデーションしましょう。

まとめ

.NET 8の標準ライブラリ System.Text.Json を使えば、VB.NETでも簡単にJSONをデシリアライズできます!

  • JsonSerializer.Deserialize(Of T) で手軽にオブジェクト生成
  • camelCaseにも JsonSerializerOptionsJsonPropertyName 属性で柔軟に対応
  • 配列もネスト構造も問題なし
  • 例外処理とnullチェックは忘れずに!

標準機能だけでここまでできるなんて、本当に便利な時代ですね。
ぜひあなたのアプリにも、System.Text.Jsonをガンガン活用していきましょう!