本文演示如何使用 System.Text.Json 命名空间向 / 从 JavaScript 对象表示法 (JSON) 进行序列化和反序列化。
本文参考:https://learn.microsoft.com/zh-cn/dotnet/standard/serialization/system-text-json/how-to?pivots=dotnet-6-0
# 命名空间
using System.Text.Json; | |
using System.Text.Json.Serialization; |
# 最简单将.NET 对象编写为 JSON
Console.WriteLine(JsonSerializer.Serialize(item)); |
# 如何将 .NET 对象编写为 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"} |
默认情况下,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"} |
下面的示例使用异步代码创建 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"; | |
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"} |
前面的示例对要序列化的类型使用类型推理。 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"} |
# 序列化示例
以下示例演示了如何序列化包含集合属性和用户定义类型的类:
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" | |
// ] | |
//} |
# 序列化为 UTF-8
序列化为 UTF-8 字节数组比使用基于字符串的方法大约快 5-10%。 出现这种差别的原因是字节(作为 UTF-8)不需要转换为字符串 (UTF-16)。
若要序列化为 UTF-8 字节数组,请调用 JsonSerializer.SerializeToUtf8Bytes 方法:
byte[] jsonUtf8Bytes =JsonSerializer.SerializeToUtf8Bytes(weatherForecast); |
# 如何将 JSON 读取为 .NET 对象(反序列化)
以下示例演示如何对 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 |
若要使用同步代码从文件进行反序列化,请将文件读入字符串中,如下面的示例中所示:
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 |
若要使用异步代码从文件进行反序列化,请调用 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 |
# 从 UTF-8 进行反序列化
若要从 UTF-8 进行反序列化,请调用采用 ReadOnlySpan<byte> 或 Utf8JsonReader 的 JsonSerializer.Deserialize 重载,如下面的示例中所示。 这些示例假设 JSON 处于名为 jsonUtf8Bytes 的字节数组中。
var readOnlySpan = new ReadOnlySpan<byte>(jsonUtf8Bytes); | |
WeatherForecast deserializedWeatherForecast = | |
JsonSerializer.Deserialize<WeatherForecast>(readOnlySpan)!; |
var utf8Reader = new Utf8JsonReader(jsonUtf8Bytes); | |
WeatherForecast deserializedWeatherForecast = | |
JsonSerializer.Deserialize<WeatherForecast>(ref utf8Reader)!; |
# 序列化为格式化 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" | |
//} |