.NET 6 中的七个 System.Text.Json 特性
Posted dotNET跨平台
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了.NET 6 中的七个 System.Text.Json 特性相关的知识,希望对你有一定的参考价值。
忽略循环引用
在 .NET 5 中,如果存在循环依赖, 那么序列化的时候会抛出异常, 而在 .NET 6 中, 你可以选择忽略它。
Category dotnet = new()
Name = ".NET 6",
;
Category systemTextJson = new()
Name = "System.Text.Json",
Parent = dotnet
;
dotnet.Children.Add(systemTextJson);
JsonSerializerOptions options = new()
ReferenceHandler = ReferenceHandler.IgnoreCycles,
WriteIndented = true
;
string dotnetJson = JsonSerializer.Serialize(dotnet, options);
Console.WriteLine($"dotnetJson");
public class Category
public string Name get; set;
public Category Parent get; set;
public List<Category> Children get; set; = new();
// 输出:
//
// "Name": ".NET 6",
// "Parent": null,
// "Children": [
//
// "Name": "System.Text.Json",
// "Parent": null,
// "Children": []
//
// ]
//
序列化和反序列化通知
在 .NET 6 中,System.Text.Json 公开序列化和反序列化的通知。
有四个新接口可以根据您的需要进行实现:
•IJsonOnDeserialized•IJsonOnDeserializing•IJsonOnSerialized•IJsonOnSerializing
Product invalidProduct = new() Name = "Name", Test = "Test" ;
JsonSerializer.Serialize(invalidProduct);
// The InvalidOperationException is thrown
string invalidJson = "";
JsonSerializer.Deserialize<Product>(invalidJson);
// The InvalidOperationException is thrown
class Product : IJsonOnDeserialized, IJsonOnSerializing, IJsonOnSerialized
public string Name get; set;
public string Test get; set;
public void OnSerialized()
throw new NotImplementedException();
void IJsonOnDeserialized.OnDeserialized() => Validate(); // Call after deserialization
void IJsonOnSerializing.OnSerializing() => Validate(); // Call before serialization
private void Validate()
if (Name is null)
throw new InvalidOperationException("The 'Name' property cannot be 'null'.");
序列化支持属性排序
在 .NET 6 中, 添加了 JsonPropertyOrderAttribute
特性,允许控制属性的序列化顺序,以前,序列化顺序是由反射顺序决定的。
Product product = new()
Id = 1,
Name = "Surface Pro 7",
Price = 550,
Category = "Laptops"
;
JsonSerializerOptions options = new() WriteIndented = true ;
string json = JsonSerializer.Serialize(product, options);
Console.WriteLine(json);
class Product : A
[JsonPropertyOrder(2)]
public string Category get; set;
[JsonPropertyOrder(1)]
public decimal Price get; set;
public string Name get; set;
[JsonPropertyOrder(-1)]
public int Id get; set;
class A
public int Test get; set;
// 输出:
//
// "Id": 1,
// "Name": "Surface Pro 7",
// "Price": 550,
// "Category": "Laptops"
//
使用 Utf8JsonWriter 编写 JSON
.NET 6 增加了 System.Text.Json.Utf8JsonWriter
,你可以方便的用它编写原始Json。
JsonWriterOptions writerOptions = new() Indented = true, ;
using MemoryStream stream = new();
using Utf8JsonWriter writer = new(stream, writerOptions);
writer.WriteStartObject();
writer.WriteStartArray("customJsonFormatting");
foreach (double result in new double[] 10.2, 10 )
writer.WriteStartObject();
writer.WritePropertyName("value");
writer.WriteRawValue(FormatNumberValue(result), skipInputValidation: true);
writer.WriteEndObject();
writer.WriteEndArray();
writer.WriteEndObject();
writer.Flush();
string json = Encoding.UTF8.GetString(stream.ToArray());
Console.WriteLine(json);
static string FormatNumberValue(double numberValue)
return numberValue == Convert.ToInt32(numberValue)
? numberValue.ToString() + ".0"
: numberValue.ToString();
// 输出:
//
// "customJsonFormatting": [
//
// "value": 10.2
// ,
//
// "value": 10.0
//
// ]
//
IAsyncEnumerable 支持
在 .NET 6 中, System.Text.Json 支持 IAsyncEnumerable
。
static async IAsyncEnumerable<int> GetNumbersAsync(int n)
for (int i = 0; i < n; i++)
await Task.Delay(1000);
yield return i;
// Serialization using IAsyncEnumerable
JsonSerializerOptions options = new() WriteIndented = true ;
using Stream 输出Stream = Console.OpenStandard输出();
var data = new Data = GetNumbersAsync(5) ;
await JsonSerializer.SerializeAsync(输出Stream, data, options);
// 输出:
//
// "Data": [
// 0,
// 1,
// 2,
// 3,
// 4
// ]
//
// Deserialization using IAsyncEnumerable
using MemoryStream memoryStream = new(Encoding.UTF8.GetBytes("[0,1,2,3,4]"));
// Wraps the UTF-8 encoded text into an IAsyncEnumerable<T> that can be used to deserialize root-level JSON arrays in a streaming manner.
await foreach (int item in JsonSerializer.DeserializeAsyncEnumerable<int>(memoryStream))
Console.WriteLine(item);
// 输出:
// 0
// 1
// 2
// 3
// 4
IAsyncEnumerable 的序列化的动图。
序列化支持流
在 .NET 6 中, 序列化和反序列化支持流。
string json = "\\"Value\\":\\"Deserialized from stream\\"";
byte[] bytes = Encoding.UTF8.GetBytes(json);
// Deserialize from stream
using MemoryStream ms = new MemoryStream(bytes);
Example desializedExample = JsonSerializer.Deserialize<Example>(ms);
Console.WriteLine(desializedExample.Value);
// 输出: Deserialized from stream
// ==================================================================
// Serialize to stream
JsonSerializerOptions options = new() WriteIndented = true ;
using Stream 输出Stream = Console.OpenStandard输出();
Example exampleToSerialize = new() Value = "Serialized from stream" ;
JsonSerializer.Serialize<Example>(输出Stream, exampleToSerialize, options);
// 输出:
//
// "Value": "Serialized from stream"
//
class Example
public string Value get; set;
像 DOM 一样使用 JSON
.NET 6 添加了下面的新类型, 支持像操作 DOM 一样访问 Json 元素。
•JsonArray•JsonNode•JsonObject•JsonValue
// Parse a JSON object
JsonNode jNode = JsonNode.Parse("\\"Value\\":\\"Text\\",\\"Array\\":[1,5,13,17,2]");
string value = (string)jNode["Value"];
Console.WriteLine(value); // Text
// or
value = jNode["Value"].GetValue<string>();
Console.WriteLine(value); // Text
int arrayItem = jNode["Array"][1].GetValue<int>();
Console.WriteLine(arrayItem); // 5
// or
arrayItem = jNode["Array"][1].GetValue<int>();
Console.WriteLine(arrayItem); // 5
// Create a new JsonObject
var jObject = new JsonObject
["Value"] = "Text",
["Array"] = new JsonArray(1, 5, 13, 17, 2)
;
Console.WriteLine(jObject["Value"].GetValue<string>()); // Text
Console.WriteLine(jObject["Array"][1].GetValue<int>()); // 5
// Converts the current instance to string in JSON format
string json = jObject.ToJsonString();
Console.WriteLine(json); // "Value":"Text","Array":[1,5,13,17,2]
全文完...
以上是关于.NET 6 中的七个 System.Text.Json 特性的主要内容,如果未能解决你的问题,请参考以下文章