.NET オブジェクトを JSON として書き込む方法 (シリアル化)
この記事では、System.Text.Json 名前空間を使用して JavaScript Object Notation (JSON) にシリアル化する方法について示します。 Newtonsoft.Json
から既存のコードを移植する場合は、Newtonsoft.Json
に関する記事を参照してください。
JSON を文字列またはファイルに書き込むには、JsonSerializer.Serialize メソッドを呼び出します。
次の例では、JSON を文字列として作成します。
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.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.Text.Json;
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";
await using FileStream createStream = File.Create(fileName);
await JsonSerializer.SerializeAsync(createStream, weatherForecast);
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.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)
シリアル化の動作
- 既定では、すべてのパブリック プロパティがシリアル化されます。 無視するプロパティを指定することができます。 プライベート メンバーを含めることもできます。
- 既定のエンコーダーでは、ASCII 以外の文字、ASCII 範囲内の HTML に影響する文字、および RFC 8259 JSON 仕様に従ってエスケープする必要のある文字がエスケープされます。
- 既定では、JSON は縮小されます。 JSON を整形することができます。
- 既定では、JSON 名の大文字と小文字の区別は .NET 名と一致します。 JSON 名の大文字と小文字の区別をカスタマイズすることができます。
- 既定では、循環参照が検出され、例外がスローされます。 参照を保持し、循環参照を処理することができます。
- 既定では、フィールドは無視されます。 フィールドを含めることができます。
ASP.NET Core アプリで System.Text.Json を間接的に使用する場合、一部の既定の動作が異なります。 詳細については、「JsonSerializerOptions の Web の規定値」を参照してください。
サポートされる型には次のようなものがあります。
数値型、文字列、ブール値など、JavaScript プリミティブにマップされる .NET プリミティブ。
ユーザー定義の単純な従来の CLR オブジェクト (POCO)。
1 次元配列とジャグ配列 (
T[][]
)。次の名前空間のコレクションとディクショナリ:
- System.Collections
- System.Collections.Generic
- System.Collections.Immutable
- System.Collections.Concurrent
- System.Collections.Specialized
- System.Collections.ObjectModel
詳細については、System.Text.Json でサポートされているコレクション型に関する記事を参照してください。
カスタム コンバーターを実装して、追加の型を処理したり、組み込みコンバーターではサポートされていない機能を提供したりすることができます。
コレクションのプロパティとユーザー定義型が含まれるクラスをシリアル化する方法の例を次に示します。
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 オーバーロードも使用できます。
書式設定された JSON へのシリアル化
JSON 出力を整形するには、JsonSerializerOptions.WriteIndented を true
に設定します。
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 インスタンスの再利用に関する説明を参照してください。
.NET