匿名型にデシリアライズする
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=(音楽,料理,写真)