JSON を .NET オブジェクトとして読み取る方法 (逆シリアル化)
この記事では、System.Text.Json 名前空間を使用して JavaScript Object Notation (JSON) の逆シリアル化を行う方法をご紹介します。 Newtonsoft.Json
から既存のコードを移植する場合は、Newtonsoft.Json
に関する記事を参照してください。
JSON を逆シリアル化する一般的な方法は、1 つまたは複数の JSON プロパティを表すプロパティとフィールドを持つ .NET クラスを作成することです。 その後、文字列またはファイルから逆シリアル化するには、JsonSerializer.Deserialize メソッドを呼び出します。 ジェネリック オーバーロードの場合、ジェネリック型パラメーターは .NET クラスです。 非ジェネリック オーバーロードの場合は、クラスの型をメソッド パラメーターとして渡します。 同期または非同期のいずれかで逆シリアル化することができます。
ヒント
GitHub Copilot では、AI の支援を使用して JSON 文字列を逆シリアル化できます。
クラスで表されていない JSON プロパティは既定ですべて無視されます。 また、型のプロパティは必須でも、JSON ペイロードに存在しない場合、逆シリアル化は失敗します。
例
次の例では、JSON 文字列を逆シリアル化する方法を示します。
using System.Text.Json;
namespace DeserializeExtra
{
public class WeatherForecast
{
public DateTimeOffset Date { get; set; }
public int TemperatureCelsius { get; set; }
public string? Summary { get; set; }
public string? SummaryField;
public IList<DateTimeOffset>? DatesAvailable { get; set; }
public Dictionary<string, HighLowTemps>? TemperatureRanges { get; set; }
public string[]? SummaryWords { get; set; }
}
public class HighLowTemps
{
public int High { get; set; }
public int Low { get; set; }
}
public class Program
{
public static void Main()
{
string jsonString =
"""
{
"Date": "2019-08-01T00:00:00-07:00",
"TemperatureCelsius": 25,
"Summary": "Hot",
"DatesAvailable": [
"2019-08-01T00:00:00-07:00",
"2019-08-02T00:00:00-07:00"
],
"TemperatureRanges": {
"Cold": {
"High": 20,
"Low": -10
},
"Hot": {
"High": 60,
"Low": 20
}
},
"SummaryWords": [
"Cool",
"Windy",
"Humid"
]
}
""";
WeatherForecast? weatherForecast =
JsonSerializer.Deserialize<WeatherForecast>(jsonString);
Console.WriteLine($"Date: {weatherForecast?.Date}");
Console.WriteLine($"TemperatureCelsius: {weatherForecast?.TemperatureCelsius}");
Console.WriteLine($"Summary: {weatherForecast?.Summary}");
}
}
}
// output:
//Date: 8/1/2019 12:00:00 AM -07:00
//TemperatureCelsius: 25
//Summary: Hot
weatherForecast = JsonSerializer.Deserialize(Of WeatherForecastWithPOCOs)(jsonString)
同期コードを使用してファイルから逆シリアル化するには、次の例に示すように、ファイルを文字列に読み取ります。
using System.Text.Json;
namespace DeserializeFromFile
{
public class WeatherForecast
{
public DateTimeOffset Date { get; set; }
public int TemperatureCelsius { get; set; }
public string? Summary { get; set; }
}
public class Program
{
public static void Main()
{
string fileName = "WeatherForecast.json";
string jsonString = File.ReadAllText(fileName);
WeatherForecast weatherForecast = JsonSerializer.Deserialize<WeatherForecast>(jsonString)!;
Console.WriteLine($"Date: {weatherForecast.Date}");
Console.WriteLine($"TemperatureCelsius: {weatherForecast.TemperatureCelsius}");
Console.WriteLine($"Summary: {weatherForecast.Summary}");
}
}
}
// output:
//Date: 8/1/2019 12:00:00 AM -07:00
//TemperatureCelsius: 25
//Summary: Hot
jsonString = File.ReadAllText(fileName)
weatherForecast1 = JsonSerializer.Deserialize(Of WeatherForecast)(jsonString)
非同期コードを使用してファイルから逆シリアル化するには、DeserializeAsync メソッドを呼び出します。
using System.Text.Json;
namespace DeserializeFromFileAsync
{
public class WeatherForecast
{
public DateTimeOffset Date { get; set; }
public int TemperatureCelsius { get; set; }
public string? Summary { get; set; }
}
public class Program
{
public static async Task Main()
{
string fileName = "WeatherForecast.json";
using FileStream openStream = File.OpenRead(fileName);
WeatherForecast? weatherForecast =
await JsonSerializer.DeserializeAsync<WeatherForecast>(openStream);
Console.WriteLine($"Date: {weatherForecast?.Date}");
Console.WriteLine($"TemperatureCelsius: {weatherForecast?.TemperatureCelsius}");
Console.WriteLine($"Summary: {weatherForecast?.Summary}");
}
}
}
// output:
//Date: 8/1/2019 12:00:00 AM -07:00
//TemperatureCelsius: 25
//Summary: Hot
Dim openStream As FileStream = File.OpenRead(fileName)
weatherForecast1 = Await JsonSerializer.DeserializeAsync(Of WeatherForecast)(openStream)
逆シリアル化の動作
JSON を逆シリアル化する場合、次の動作が適用されます。
- 既定では、プロパティ名の照合では大文字と小文字が区別されます。 大文字と小文字を区別しないことを指定できます。
- 非パブリック コンストラクターはシリアライザーにより無視されます。
- パブリック
set
アクセサーを持たない変更できないオブジェクトまたはプロパティへの逆シリアル化はサポートされていますが、既定では有効になっていません。 「不変の型とレコード」を参照してください。 - 既定では、列挙型は数値としてサポートされています。 文字列列挙型フィールドは逆シリアル化できます。
- 既定では、フィールドは無視されます。 フィールドを含めることができます。
- 既定では、JSON にコメントまたは末尾のコンマがあると例外がスローされます。 コメントと末尾のコンマを許可することができます。
- 既定の最大深度は 64 です。
ASP.NET Core アプリで System.Text.Json を間接的に使用する場合、一部の既定の動作が異なります。 詳細については、「JsonSerializerOptions の Web の規定値」を参照してください。
カスタム コンバーターを実装して、組み込みコンバーターではサポートされていない機能を提供できます。
.NET クラスを使用せずに逆シリアル化する
逆シリアル化する JSON があり、それを逆シリアル化するクラスがない場合は、必要なクラスを手動で作成する以外のオプションがあります。
Utf8JsonReader を直接使用します。
JSON DOM (ドキュメント オブジェクト モデル) に逆シリアル化し、DOM から必要なデータを抽出します。
DOM を使用すると、JSON ペイロードのサブセクションに移動し、単一の値、カスタム型、または配列を逆シリアル化できます。 JsonNode DOM の詳細については、「JSON ペイロードのサブセクションを逆シリアル化する」を参照してください。 JsonDocument DOM の詳細については、「JsonDocument」を参照してください。
Visual Studio 2022 を使用して、必要なクラスを自動的に生成します。
- 逆シリアル化する必要がある JSON をコピーします。
- クラス ファイルを作成し、テンプレート コードを削除します。
- [編集]>[形式を選択して貼り付け]>[JSON をクラスとして貼り付ける] を選択します。
結果は、逆シリアル化ターゲットに使用できるクラスになります。
UTF-8 からの逆シリアル化
UTF-8 から逆シリアル化するには、次の例に示すように、JsonSerializer.Deserialize または ReadOnlySpan<byte>
を受け取る Utf8JsonReader
オーバーロードを呼び出します。 この例では、JSON が jsonUtf8Bytes という名前のバイト配列内にあることを想定しています。
var readOnlySpan = new ReadOnlySpan<byte>(jsonUtf8Bytes);
WeatherForecast deserializedWeatherForecast =
JsonSerializer.Deserialize<WeatherForecast>(readOnlySpan)!;
Dim jsonString = Encoding.UTF8.GetString(jsonUtf8Bytes)
weatherForecast1 = JsonSerializer.Deserialize(Of WeatherForecast)(jsonString)
var utf8Reader = new Utf8JsonReader(jsonUtf8Bytes);
WeatherForecast deserializedWeatherForecast =
JsonSerializer.Deserialize<WeatherForecast>(ref utf8Reader)!;
' This code example doesn't apply to Visual Basic. For more information, go to the following URL:
' https://learn.microsoft.com/dotnet/standard/serialization/system-text-json-how-to#visual-basic-support
GitHub Copilot を使用して JSON を逆シリアル化する
IDE で GitHub Copilot を使用すると、System.Text.Json
により JSON から逆シリアル化したコードを生成できます。 このプロンプトは、要件に合ったプロパティ名と値を含む JSON 文字列を使用してカスタマイズできます。
次のテキストは、Copilot Chat のプロンプトの例を示しています。
Generate code to use System.Text.Json to deserialize a JSON string {"FirstName":"John","LastName":"Doe","Age":30} to an equivalent .NET object.
Map property names & values.
Provide example output.
GitHub Copilot では AI を利用しているため、想定外のことや間違いが起こる可能性があります。 詳細については、Copilot の FAQを参照してください。
Visual Studio での GitHub Copilot
.NET