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 から逆シリアル化するには、次の例に示すように、ReadOnlySpan<byte>
または Utf8JsonReader
を受け取る JsonSerializer.Deserialize オーバーロードを呼び出します。 この例では、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 から逆シリアル化したコードを生成できます。
Visual Studio 2022 バージョン 17.8 以降を使用している場合は、System.Text.Json
を使用して JSON を逆シリアル化したコードの生成に、AI 駆動型の Visual Studio の GitHub Copilot を試すことができます。 次の例のように、Copilot チャット ウィンドウにプロンプトとして質問を送信します。 エディター ウィンドウ自体で インライン チャット を使用してプロンプトを送信することもできます。
Note
GitHub Copilot では AI を利用しているため、想定外のことや間違いが起こる可能性があります。 生成されたコードまたは提案を必ず確認してください。 GitHub Copilot の一般的な用途、製品への影響、人間の監視、プライバシーの詳細については、 GitHub Copilot に関する FAQを参照してください。
次のテキストは、Copilot Chat のプロンプトの例を示しています。
System.Text.Json
を使用して JSON 文字列 {"FirstName":"John","LastName":"Doe","Age":30} を等価の .NET オブジェクトに逆シリアル化したコードを生成してください。 プロパティ名 & 値をマップしてください。 出力例を示します。
このプロンプトは、要件に合ったプロパティ名と値を含む JSON 文字列を使用してカスタマイズできます。
スラッシュ コマンド、ファイル、メソッド、クラスへの参照、スレッドなどのチャット機能を使用して、意図を設定し、スコープ指定されたコンテキストでより適切な回答を得ることができます。 IDE で開いているプロジェクト内の既存のクラスの場合は、GitHub Copilot に /generate code to dserialize JSON to equivalent .NET object in #Filename
とプロンプトを出すことができます。
次の出力は、Copilot Chat の応答の例を示しています。
Here's an example of how you can use `System.Text.Json` to deserialize a JSON string into a .NET object in C#:
using System;
using System.Text.Json;
public class Person
{
public string FirstName { get; set; }
public string LastName { get; set; }
public int Age { get; set; }
}
public class Program
{
public static void Main()
{
string jsonString = "{\"FirstName\":\"John\",\"LastName\":\"Doe\",\"Age\":30}";
Person person = JsonSerializer.Deserialize<Person>(jsonString);
Console.WriteLine($"FirstName: {person.FirstName}");
Console.WriteLine($"LastName: {person.LastName}");
Console.WriteLine($"Age: {person.Age}");
}
}
**Example Output**
FirstName: John
LastName: Doe
Age: 30
This code defines a Person class with properties that match the JSON string. It then uses `JsonSerializer.Deserialize` to convert the JSON string into a `Person` object and prints the properties to the console.
Copilot がコード ブロックを返す場合、応答には、コードをコピーする、コードを新しいファイルに挿入する、またはコード出力をプレビューするオプションが含まれます。
Note
結果は、サンプルの回答に示されているものと異なる場合があります。 AI モデルは非決定論的です。つまり、同じ質問を受けたときに異なる応答を返す場合があります。 これは、時間の経過に伴う学習と適応の進行、言語バリエーション、チャット履歴などのコンテキストの変更などが原因である可能性があります。
詳細については、以下を参照してください:
- GitHub Copilot セキュリティ センター
- Visual Studio の GitHub Copilot
- VS Code の GitHub Copilot
.NET