.NET 内で JSON のシリアル化と逆シリアル化 (マーシャリングとマーシャリングの解除) を行う方法

この記事では、System.Text.Json 名前空間を使用して JavaScript Object Notation (JSON) のシリアル化と逆シリアル化を行う方法について示します。 Newtonsoft.Json から既存のコードを移植する場合は、System.Text.Json に移行する方法に関する記事を参照してください。

コード サンプル

この記事のコード サンプルは次のとおりです。

  • ASP.NET Core などのフレームワーク経由ではなく、ライブラリを直接使用します。

  • JsonSerializer クラスとカスタム型を使用して、シリアル化と逆シリアル化を行います。

    JsonSerializer を使用せずに JSON データを読み書きする方法の詳細については、JSON DOM、Utf8JsonReader、Utf8JsonWriter を使用する方法に関する記事を参照してください。

  • WriteIndented オプションを使用し、必要に応じて JSON を人間が読みやすい形式に設定します。

    運用環境で使用する場合は、通常、この設定の既定値である false をそのまま使用します。不要な空白を追加すると、パフォーマンスや帯域幅の使用率が低下するおそれがあるためです。

  • 次のクラスとそのバリアントを参照してください。

    public class WeatherForecast
    {
        public DateTimeOffset Date { get; set; }
        public int TemperatureCelsius { get; set; }
        public string Summary { get; set; }
    }
    
    Public Class WeatherForecast
        Public Property [Date] As DateTimeOffset
        Public Property TemperatureCelsius As Integer
        Public Property Summary As String
    End Class
    

Visual Basic のサポート

System.Text.Json の一部で、Visual Basic でサポートされていない ref 構造体が使用されています。 Visual Basic で System.Text.Json ref 構造 API を使用しようとすると、BC40000 コンパイラ エラーが発生します。 このエラー メッセージは、問題が古い API であることを示していますが、実際の問題は、コンパイラでの ref 構造体のサポートの欠如です。 System.Text.Json の次の部分は、Visual Basic では使用できません。

  • Utf8JsonReader クラスです。 JsonConverter<T>.Read メソッドは Utf8JsonReader パラメーターを受け取るため、この制限は、Visual Basic を使用してカスタム コンバーターを記述することはできないことを意味します。 これを回避するには、C# ライブラリ アセンブリにカスタム コンバーターを実装し、VB プロジェクトからそのアセンブリを参照します。 これは、Visual Basic で行うのが、コンバーターをシリアライザーに登録するだけであることを前提としています。 Visual Basic コードからコンバーターの Read メソッドを呼び出すことはできません。
  • ReadOnlySpan<T> 型を含む他の API のオーバーロード。 ほとんどのメソッドには、ReadOnlySpan の代わりに String を使用するオーバーロードが含まれています。

これらの制限が適用されるのは、"データを通過させる" だけの場合でも、言語サポートなしでは ref 構造体を安全に使用できないからです。 このエラーを無効にすると、メモリを破損するおそれのある Visual Basic コードが生成されるため、実行しないでください。

名前空間

System.Text.Json 名前空間には、すべてのエントリ ポイントと主要な型が含まれています。 System.Text.Json.Serialization 名前空間には、シリアル化と逆シリアル化に固有の高度なシナリオとカスタマイズのための属性と API が含まれています。 この記事に示されているコード例では、次のいずれかまたは両方の名前空間に using ディレクティブが必要です。

using System.Text.Json;
using System.Text.Json.Serialization;
Imports System.Text.Json
Imports System.Text.Json.Serialization

重要

System.Runtime.Serialization 名前空間の属性は、System.Text.Json ではサポートされていません。

.NET オブジェクトを JSON として書き込む方法 (シリアル化)

JSON を文字列またはファイルに書き込むには、JsonSerializer.Serialize メソッドを呼び出します。

次の例では、JSON を文字列として作成します。

using System;
using System.Text.Json;

namespace SerializeBasic
{
    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()
        {
            var weatherForecast = new WeatherForecast
            {
                Date = DateTime.Parse("2019-08-01"),
                TemperatureCelsius = 25,
                Summary = "Hot"
            };

            string jsonString = JsonSerializer.Serialize(weatherForecast);

            Console.WriteLine(jsonString);
        }
    }
}
// output:
//{"Date":"2019-08-01T00:00:00-07:00","TemperatureCelsius":25,"Summary":"Hot"}
Dim jsonString As String

既定では、JSON 出力は縮小されます (空白、インデント、および改行文字が削除されます)。

次の例では、同期コードを使用して JSON ファイルを作成します。

using System;
using System.IO;
using System.Text.Json;

namespace SerializeToFile
{
    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()
        {
            var weatherForecast = new WeatherForecast
            {
                Date = DateTime.Parse("2019-08-01"),
                TemperatureCelsius = 25,
                Summary = "Hot"
            };

            string fileName = "WeatherForecast.json"; 
            string jsonString = JsonSerializer.Serialize(weatherForecast);
            File.WriteAllText(fileName, jsonString);

            Console.WriteLine(File.ReadAllText(fileName));
        }
    }
}
// output:
//{"Date":"2019-08-01T00:00:00-07:00","TemperatureCelsius":25,"Summary":"Hot"}
jsonString = JsonSerializer.Serialize(weatherForecast1)
File.WriteAllText(fileName, jsonString)

次の例では、非同期コードを使用して JSON ファイルを作成します。

using System;
using System.IO;
using System.Text.Json;
using System.Threading.Tasks;

namespace SerializeToFileAsync
{
    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()
        {
            var weatherForecast = new WeatherForecast
            {
                Date = DateTime.Parse("2019-08-01"),
                TemperatureCelsius = 25,
                Summary = "Hot"
            };

            string fileName = "WeatherForecast.json";
            using FileStream createStream = File.Create(fileName);
            await JsonSerializer.SerializeAsync(createStream, weatherForecast);
            await createStream.DisposeAsync();

            Console.WriteLine(File.ReadAllText(fileName));
        }
    }
}
// output:
//{"Date":"2019-08-01T00:00:00-07:00","TemperatureCelsius":25,"Summary":"Hot"}
Dim createStream As FileStream = File.Create(fileName)
Await JsonSerializer.SerializeAsync(createStream, weatherForecast1)

前の例では、シリアル化する型に型の推定を使用しています。 Serialize() のオーバーロードでは、ジェネリック型パラメーターを受け取ります。

using System;
using System.Text.Json;

namespace SerializeWithGenericParameter
{
    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()
        {
            var weatherForecast = new WeatherForecast
            {
                Date = DateTime.Parse("2019-08-01"),
                TemperatureCelsius = 25,
                Summary = "Hot"
            };

            string jsonString = JsonSerializer.Serialize<WeatherForecast>(weatherForecast);

            Console.WriteLine(jsonString);
        }
    }
}
// output:
//{"Date":"2019-08-01T00:00:00-07:00","TemperatureCelsius":25,"Summary":"Hot"}
jsonString = JsonSerializer.Serialize(Of WeatherForecastWithPOCOs)(weatherForecast)

シリアル化の例

コレクションのプロパティとユーザー定義型が含まれるクラスをシリアル化する方法の例を次に示します。

using System;
using System.Collections.Generic;
using System.Text.Json;

namespace SerializeExtra
{
    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()
        {
            var weatherForecast = new WeatherForecast
            {
                Date = DateTime.Parse("2019-08-01"),
                TemperatureCelsius = 25,
                Summary = "Hot",
                SummaryField = "Hot",
                DatesAvailable = new List<DateTimeOffset>() 
                    { DateTime.Parse("2019-08-01"), DateTime.Parse("2019-08-02") },
                TemperatureRanges = new Dictionary<string, HighLowTemps>
                    {
                        ["Cold"] = new HighLowTemps { High = 20, Low = -10 },
                        ["Hot"] = new HighLowTemps { High = 60 , Low = 20 }
                    },
                SummaryWords = new[] { "Cool", "Windy", "Humid" }
            };

            var options = new JsonSerializerOptions { WriteIndented = true };
            string jsonString = JsonSerializer.Serialize(weatherForecast, options);

            Console.WriteLine(jsonString);
        }
    }
}
// output:
//{
//  "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"
//  ]
//}
Public Class WeatherForecastWithPOCOs
    Public Property [Date] As DateTimeOffset
    Public Property TemperatureCelsius As Integer
    Public Property Summary As String
    Public SummaryField As String
    Public Property DatesAvailable As IList(Of DateTimeOffset)
    Public Property TemperatureRanges As Dictionary(Of String, HighLowTemps)
    Public Property SummaryWords As String()
End Class

Public Class HighLowTemps
    Public Property High As Integer
    Public Property Low As Integer
End Class

' serialization output formatted (pretty-printed with whitespace and indentation):
' {
'   "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"
'   ]
' }

UTF-8 にシリアル化する

UTF-8 バイト配列へのシリアル化は、文字列ベースのメソッドを使用するより約 5 から 10% 高速です。 違いは、バイト (UTF-8) を文字列 (UTF-16) に変換する必要がないことから生じます。

UTF-8 バイト配列にシリアル化するには、JsonSerializer.SerializeToUtf8Bytes メソッドを呼び出します。

byte[] jsonUtf8Bytes =JsonSerializer.SerializeToUtf8Bytes(weatherForecast);
Dim jsonUtf8Bytes As Byte()
Dim options As JsonSerializerOptions = New JsonSerializerOptions With {
    .WriteIndented = True
}
jsonUtf8Bytes = JsonSerializer.SerializeToUtf8Bytes(weatherForecast1, options)

Utf8JsonWriter を受け取る Serialize オーバーロードも使用できます。

シリアル化の動作

ASP.NET Core アプリで System.Text.Json を間接的に使用する場合、一部の既定の動作が異なります。 詳細については、「JsonSerializerOptions の Web の規定値」を参照してください。

サポートされる型には次のようなものがあります。

詳細については、System.Text.Json でサポートされているコレクション型に関する記事を参照してください。

カスタム コンバーターを実装して、追加の型を処理したり、組み込みコンバーターではサポートされていない機能を提供したりすることができます。

JSON を .NET オブジェクトとして読み取る方法 (逆シリアル化)

文字列またはファイルから逆シリアル化するには、JsonSerializer.Deserialize メソッドを呼び出します。

次の例では、JSON 文字列を逆シリアル化する方法を示します。

using System;
using System.Collections.Generic;
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;
using System.IO;
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;
using System.IO;
using System.Text.Json;
using System.Threading.Tasks;

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 があり、それを逆シリアル化するクラスがない場合は、必要なクラスを手動で作成する以外のオプションがあります。

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://docs.microsoft.com/dotnet/standard/serialization/system-text-json-how-to#visual-basic-support

逆シリアル化の動作

JSON を逆シリアル化する場合、次の動作が適用されます。

  • 既定では、プロパティ名の照合では大文字と小文字が区別されます。 大文字と小文字を区別しないことを指定できます。
  • JSON に読み取り専用プロパティの値が含まれている場合、その値は無視され、例外はスローされません。
  • 非パブリック コンストラクターはシリアライザーにより無視されます。
  • パブリック set アクセサーを持たない、変更できないオブジェクトまたはプロパティへの逆シリアル化がサポートされています。 「不変の型とレコード」を参照してください。
  • 既定では、列挙型は数値としてサポートされています。 列挙型名を文字列としてシリアル化することができます。
  • 既定では、フィールドは無視されます。 フィールドを含めることができます。
  • 既定では、JSON にコメントまたは末尾のコンマがあると例外がスローされます。 コメントと末尾のコンマを許可することができます。
  • 既定の最大深度は 64 です。

ASP.NET Core アプリで System.Text.Json を間接的に使用する場合、一部の既定の動作が異なります。 詳細については、「JsonSerializerOptions の Web の規定値」を参照してください。

  • 既定では、プロパティ名の照合では大文字と小文字が区別されます。 大文字と小文字を区別しないことを指定できます。 ASP.NET Core アプリの場合、既定では大文字と小文字を区別しないことが指定されます。
  • JSON に読み取り専用プロパティの値が含まれている場合、その値は無視され、例外はスローされません。
  • 逆シリアル化には、パラメーターなしのコンストラクター (public、internal、private のいずれか) が使用されます。
  • パブリック set アクセサーを持たない、変更できないオブジェクトまたはプロパティへの逆シリアル化は、サポートされていません。
  • 既定では、列挙型は数値としてサポートされています。 列挙型名を文字列としてシリアル化することができます。
  • フィールドはサポートされません。
  • 既定では、JSON にコメントまたは末尾のコンマがあると例外がスローされます。 コメントと末尾のコンマを許可することができます。
  • 既定の最大深度は 64 です。

ASP.NET Core アプリで System.Text.Json を間接的に使用する場合、一部の既定の動作が異なります。 詳細については、「JsonSerializerOptions の Web の規定値」を参照してください。

カスタム コンバーターを実装して、組み込みコンバーターではサポートされていない機能を提供できます。

書式設定された JSON へのシリアル化

JSON 出力を整形するには、JsonSerializerOptions.WriteIndentedtrue に設定します。

using System;
using System.Text.Json;

namespace SerializeWriteIndented
{
    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()
        {
            var weatherForecast = new WeatherForecast
            {
                Date = DateTime.Parse("2019-08-01"),
                TemperatureCelsius = 25,
                Summary = "Hot"
            };

            var options = new JsonSerializerOptions { WriteIndented = true };
            string jsonString = JsonSerializer.Serialize(weatherForecast, options);

            Console.WriteLine(jsonString);
        }
    }
}
// output:
//{
//  "Date": "2019-08-01T00:00:00-07:00",
//  "TemperatureCelsius": 25,
//  "Summary": "Hot"
//}
Dim options As JsonSerializerOptions = New JsonSerializerOptions With {
    .WriteIndented = True
}
jsonString = JsonSerializer.Serialize(weatherForecast, options)

同じオプションで JsonSerializerOptions を繰り返し使用する場合、使用のたびに新しい JsonSerializerOptions インスタンスを作成しないでください。 すべての呼び出しで同じインスタンスを再利用します。 詳細については、JsonSerializerOptions インスタンスの再利用に関する説明を参照してください。

フィールドを含める

次の例で示されているように、シリアル化または逆シリアル化のときにフィールドを含めるには、JsonSerializerOptions.IncludeFields グローバル設定または [JsonInclude] 属性を使用します。

using System;
using System.Text.Json;
using System.Text.Json.Serialization;

namespace Fields
{
    public class Forecast
    {
        public DateTime Date;
        public int TemperatureC;
        public string Summary;
    }

    public class Forecast2
    {
        [JsonInclude]
        public DateTime Date;
        [JsonInclude]
        public int TemperatureC;
        [JsonInclude]
        public string Summary;
    }

    public class Program
    {
        public static void Main()
        {
            var json =
                @"{""Date"":""2020-09-06T11:31:01.923395"",""TemperatureC"":-1,""Summary"":""Cold""} ";
            Console.WriteLine($"Input JSON: {json}");

            var options = new JsonSerializerOptions
            {
                IncludeFields = true,
            };
            var forecast = JsonSerializer.Deserialize<Forecast>(json, options);

            Console.WriteLine($"forecast.Date: {forecast.Date}");
            Console.WriteLine($"forecast.TemperatureC: {forecast.TemperatureC}");
            Console.WriteLine($"forecast.Summary: {forecast.Summary}");

            var roundTrippedJson =
                JsonSerializer.Serialize<Forecast>(forecast, options);

            Console.WriteLine($"Output JSON: {roundTrippedJson}");

            var forecast2 = JsonSerializer.Deserialize<Forecast2>(json);

            Console.WriteLine($"forecast2.Date: {forecast2.Date}");
            Console.WriteLine($"forecast2.TemperatureC: {forecast2.TemperatureC}");
            Console.WriteLine($"forecast2.Summary: {forecast2.Summary}");

            roundTrippedJson = JsonSerializer.Serialize<Forecast2>(forecast2);
            
            Console.WriteLine($"Output JSON: {roundTrippedJson}");
        }
    }
}

// Produces output like the following example:
//
//Input JSON: { "Date":"2020-09-06T11:31:01.923395","TemperatureC":-1,"Summary":"Cold"}
//forecast.Date: 9/6/2020 11:31:01 AM
//forecast.TemperatureC: -1
//forecast.Summary: Cold
//Output JSON: { "Date":"2020-09-06T11:31:01.923395","TemperatureC":-1,"Summary":"Cold"}
//forecast2.Date: 9/6/2020 11:31:01 AM
//forecast2.TemperatureC: -1
//forecast2.Summary: Cold
//Output JSON: { "Date":"2020-09-06T11:31:01.923395","TemperatureC":-1,"Summary":"Cold"}
Imports System.Text.Json
Imports System.Text.Json.Serialization

Namespace Fields

    Public Class Forecast
        Public [Date] As Date
        Public TemperatureC As Integer
        Public Summary As String
    End Class

    Public Class Forecast2

        <JsonInclude>
        Public [Date] As Date

        <JsonInclude>
        Public TemperatureC As Integer

        <JsonInclude>
        Public Summary As String

    End Class

    Public NotInheritable Class Program

        Public Shared Sub Main()
            Dim json As String = "{""Date"":""2020-09-06T11:31:01.923395"",""TemperatureC"":-1,""Summary"":""Cold""}"
            Console.WriteLine($"Input JSON: {json}")

            Dim options As New JsonSerializerOptions With {
                .IncludeFields = True
            }
            Dim forecast1 As Forecast = JsonSerializer.Deserialize(Of Forecast)(json, options)

            Console.WriteLine($"forecast.Date: {forecast1.[Date]}")
            Console.WriteLine($"forecast.TemperatureC: {forecast1.TemperatureC}")
            Console.WriteLine($"forecast.Summary: {forecast1.Summary}")

            Dim roundTrippedJson As String = JsonSerializer.Serialize(forecast1, options)

            Console.WriteLine($"Output JSON: {roundTrippedJson}")

            Dim forecast21 As Forecast2 = JsonSerializer.Deserialize(Of Forecast2)(json)

            Console.WriteLine($"forecast2.Date: {forecast21.[Date]}")
            Console.WriteLine($"forecast2.TemperatureC: {forecast21.TemperatureC}")
            Console.WriteLine($"forecast2.Summary: {forecast21.Summary}")

            roundTrippedJson = JsonSerializer.Serialize(forecast21)

            Console.WriteLine($"Output JSON: {roundTrippedJson}")
        End Sub

    End Class

End Namespace

' Produces output like the following example:
'
'Input JSON: { "Date":"2020-09-06T11:31:01.923395","TemperatureC":-1,"Summary":"Cold"}
'forecast.Date: 9/6/2020 11:31:01 AM
'forecast.TemperatureC: -1
'forecast.Summary: Cold
'Output JSON: { "Date":"2020-09-06T11:31:01.923395","TemperatureC":-1,"Summary":"Cold"}
'forecast2.Date: 9/6/2020 11:31:01 AM
'forecast2.TemperatureC: -1
'forecast2.Summary: Cold
'Output JSON: { "Date":"2020-09-06T11:31:01.923395","TemperatureC":-1,"Summary":"Cold"}

読み取り専用フィールドを無視するには、JsonSerializerOptions.IgnoreReadOnlyFields グローバル設定を使用します。

.NET Core 3.1 では、System.Text.Json メソッドはサポートされていません。 この機能は、カスタム コンバーターで提供できます。

HttpClient と HttpContent の拡張メソッド

ネットワークからの JSON ペイロードのシリアル化と逆シリアル化は、一般的な操作です。 HttpClient および HttpContent の拡張メソッドを使用すると、これらの操作を 1 行のコードで実行できます。 これらの拡張メソッドにおいては、JsonSerializerOptions の Web の既定値が使用されます。

次の例では、HttpClientJsonExtensions.GetFromJsonAsyncHttpClientJsonExtensions.PostAsJsonAsync の使用方法を示します。

using System;
using System.Net.Http;
using System.Net.Http.Json;
using System.Threading.Tasks;

namespace HttpClientExtensionMethods
{
    public class User
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public string Username { get; set; }
        public string Email { get; set; }
    }

    public class Program
    {
        public static async Task Main()
        {
            using HttpClient client = new()
            {
                BaseAddress = new Uri("https://jsonplaceholder.typicode.com")
            };

            // Get the user information.
            User user = await client.GetFromJsonAsync<User>("users/1");
            Console.WriteLine($"Id: {user.Id}");
            Console.WriteLine($"Name: {user.Name}");
            Console.WriteLine($"Username: {user.Username}");
            Console.WriteLine($"Email: {user.Email}");

            // Post a new user.
            HttpResponseMessage response = await client.PostAsJsonAsync("users", user);
            Console.WriteLine(
                $"{(response.IsSuccessStatusCode ? "Success" : "Error")} - {response.StatusCode}");
        }
    }
}

// Produces output like the following example but with different names:
//
//Id: 1
//Name: Tyler King
//Username: Tyler
//Email: Tyler @contoso.com
//Success - Created
Imports System.Net.Http
Imports System.Net.Http.Json

Namespace HttpClientExtensionMethods

    Public Class User
        Public Property Id As Integer
        Public Property Name As String
        Public Property Username As String
        Public Property Email As String
    End Class

    Public Class Program

        Public Shared Async Function Main() As Task
            Using client As New HttpClient With {
                .BaseAddress = New Uri("https://jsonplaceholder.typicode.com")
                }

                ' Get the user information.
                Dim user1 As User = Await client.GetFromJsonAsync(Of User)("users/1")
                Console.WriteLine($"Id: {user1.Id}")
                Console.WriteLine($"Name: {user1.Name}")
                Console.WriteLine($"Username: {user1.Username}")
                Console.WriteLine($"Email: {user1.Email}")

                ' Post a new user.
                Dim response As HttpResponseMessage = Await client.PostAsJsonAsync("users", user1)
                Console.WriteLine(
                $"{(If(response.IsSuccessStatusCode, "Success", "Error"))} - {response.StatusCode}")
            End Using
        End Function

    End Class

End Namespace

' Produces output like the following example but with different names:
'
'Id: 1
'Name: Tyler King
'Username: Tyler
'Email: Tyler @contoso.com
'Success - Created

HttpContent には System.Text.Json 用の拡張メソッドもあります。

HttpClient および HttpContent の拡張メソッドは、.NET Core 3.1 の System.Text.Json では使用できません。

関連項目