.NET 6中System.Text.Json的七个特性
作者:Oleg?Kyrylchuk 发布时间:2024-05-02 17:20:02
标签:.NET6,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的七个特 * 的支持!
来源:https://mp.weixin.qq.com/s/ggEeqm_e4i7d4w-_44mPgA
0
投稿
猜你喜欢
- 在上篇文章给大家介绍了Bootstrap的基础知识,接下来通过本文给大家介绍我们可以在http://getbootstrap.com下载bo
- 一、简介Flask是一个轻量级的基于Python的web框架。本文适合有一定HTML、Python、网络基础的同学阅读。这份文档中的代码使用
- HTML 5基本思维概念形成于2003年,之后W3C对页面超文本应用技术工作小组(WHATWG)开发的HTML草图颇感兴趣,这个小组的开发人
- sign签名是用于提供给外部(第三方)调用的接口,调用方需要提供正确的appkey钥匙才能调用,确保了接口的安全性。签名参数sign生成方法
- 执行时间方法1import datetimestarttime = datetime.datetime.now()#long running
- 本文介绍MySQL与Redis缓存的同步的两种方案方案1:通过MySQL自动同步刷新Redis,MySQL触发器+UDF函数实现方案2:解析
- 存储过程的优缺点: 存储过程优点: 1.由于应用程序随着时间推移会不断更改,增删功能,T-SQL过程代码会变得更复杂,StoredProce
- 一,封装封装是面向对象编程思想的重要特征之一。(一)什么是封装封装是一个抽象对象的过程,它容纳了对象的属性和行为实现细节,并以此对外提供公共
- 新闻系统、blog系统等都可能用到将动态页面生成静态页面的技巧来提高页面的访问速度,从而减轻服务器的压力,本文为大家搜集整理了ASP编程中常
- 前言:协程(coroutine)是 Go 语言最大的特色之一,goroutine 的实现其实是通过协程。协程的概念协程一词最早出现在 196
- 1. 普通装饰器 import logging1. foo = use_loggine(foo) def use_loggine(func)
- 1、说明关键词传递以“形参变量名=实参”的形式参与实参关联,根据形参的名称进行参数传递,使实参和形参的顺序不一致。不用担心定义函数时参数的顺
- 由于Access数据库是一种文件型数据库,所以无法跨服务器进行访问。下面我们来介绍一下如何利用SQL Server 的链接服务器,把地理上分
- 帮网友小改了一下主题. 任务比较简单, 只是为一个三栏主题添加对 Widget 的支持而已,就先从这次简单的案例开始说吧.单侧边栏funct
- 目前已经有很多生成html的新闻系统,但是都是用的模板,本函数实现把asp页面产生的html代码保存成为一个html文件,这样就没有必要改动
- 我们最常用的 DBD::mysql 模块,我发现是难住很多人的地方.因为安装老是失败,下面我介绍一下解决方法,比如我使用 cpanm 安装,
- 字符画是一种由字母、标点或其他字符组成的图画,它产生于互联网时代,在聊天软件中使用较多,本文我们看一下如何将自己喜欢的图片转成字符画。静态图
- 今天在设计一个标签(采用的是Select 选择器中的标签那一个)时,从后台返回了数据,但是在输入值时,没有对回显的值进行过滤匹配,通过查看官
- 前言常见的通知方式有:邮件,电话,短信,微信。短信和电话:通常是收费的,较少使用;邮件:适合带文件类型的通知,较正式,存档使用;微信:适合告
- 前言要在pandas.DataFrame中的任何位置检索或更改数据,可以使用at,iat,loc,iloc。位置的指定方法at,loc:行标