0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

System.Text.JsonでDeserializeAnonymousType(匿名型にデシリアライズ)

Last updated at Posted at 2024-07-23

匿名型にデシリアライズする

Json.NET

Json.NET(Newtonsoft.Json)には匿名型にデシリアライズするDeserializeAnonymousTypeというメソッドがあります。
APIのレスポンスから欲しいデータだけをサクッと取りたい場合などに便利です。

using Newtonsoft.Json;

var json = """
{
  "name": "山田太郎",
  "age": 30,
  "address": {
    "country": "日本",
    "city": "東京",
    "postalCode": "100-0001"
  },
  "hobbies": ["読書", "映画", "旅行"]
}

var item = JsonConvert.DeserializeAnonymousType(json, 
    new { name = "", address = new { country = "" }});
Console.WriteLine($"name={item.name}, country={item.address.country}");

//name=山田太郎, country=日本

System.Text.Json

System.Text.JsonにはDeserializeAnonymousTypeに相当するメソッドはありませんが、下記の様のようなジェネリックメソッドで実現可能です。

ジェネリックメソッドの型推論を使う

T? DeserializeAnonymousType<T>(string value, T _) => JsonSerializer.Deserialize<T>(value);

このメソッドでは、第2引数に渡されたオブジェクトの型を基に、型引数Tが推論されます。この機能により、型名を明示的に指定できない匿名型でも、JsonSerializer.Deserializeメソッドを利用することが可能となります。

using System.Text.Json;

var json = """
{
  "name": "山田太郎",
  "age": 30,
  "address": {
    "country": "日本",
    "city": "東京",
    "postalCode": "100-0001"
  },
  "hobbies": ["読書", "映画", "旅行"]
}
""";

static T? DeserializeAnonymousType<T>(string value, T _) => JsonSerializer.Deserialize<T>(value);

var item = DeserializeAnonymousType(json, 
    new { name = "", address = new { country = "" }, hobbies = new[] { "" } });

if (item != null)
{
  Console.WriteLine($"name={item.name}, country={item.address.country}, hobbies=({string.Join(",", item.hobbies)})");
}

//name=山田太郎, country=日本, hobbies=(読書,映画,旅行)

配列の場合

ルートの要素が配列の場合も下記の様に書いてもいけますが

var jsonArray = """
[
  {
    "name": "山田太郎",
    "age": 30,
    "address": {
      "country": "日本",
      "city": "東京",
      "postalCode": "100-0001"
    },
    "hobbies": ["読書", "映画", "旅行"]
  },
  {
    "name": "鈴木花子",
    "age": 25,
    "address": {
      "country": "日本",
      "city": "大阪",
      "postalCode": "530-0001"
    },
    "hobbies": ["音楽", "料理", "写真"]
  }
]
""";

var items2 = DeserializeAnonymousType(jsonArray, 
    new[] { 
       new { name = "", address = new { country = "" }, hobbies = new[] { "" } } 
    });

次の様に、渡す匿名型は単一のままJsonSerializer.Deserialize<T>の型引数で対応する方がスッキリ書けます。

  • 配列用
IEnumerable<T> DeserializeAnonymousArray<T>(string value, T _) =>
    JsonSerializer.Deserialize<IEnumerable<T>>(value) ?? [];
using System.Text.Json;

var jsonArray = """
[
  {
    "name": "山田太郎",
    "age": 30,
    "address": {
      "country": "日本",
      "city": "東京",
      "postalCode": "100-0001"
    },
    "hobbies": ["読書", "映画", "旅行"]
  },
  {
    "name": "鈴木花子",
    "age": 25,
    "address": {
      "country": "日本",
      "city": "大阪",
      "postalCode": "530-0001"
    },
    "hobbies": ["音楽", "料理", "写真"]
  }
]
""";

static IEnumerable<T> DeserializeAnonymousArray<T>(string value, T _) =>
    JsonSerializer.Deserialize<IEnumerable<T>>(value) ?? [];
    
var items = DeserializeAnonymousArray(jsonArray, 
    new { name = "", age = 0, address = new { city = "" } });
foreach (var item in items)
{
  Console.WriteLine($"name={item.name}, age={item.age}, city={item.address.city}");
}

//name=山田太郎, country=日本, hobbies=(読書,映画,旅行)
//name=鈴木花子, country=日本, hobbies=(音楽,料理,写真)

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?