System.Text.Json匿名对象反序列化
以前就是一直使用 Newtonsoft.Json 用起来还是挺舒服的。由于 JSON 的应用越来越广,现在. NET Core 都内置了 System.Text.Json 可以直接对 JSON 进行操作,不过两个东西的体验依然有点区别。
有时候我们会遇到的从第三方传递过来的 json string 对象,对其进行解析并不需要所有的字段,只需要一个目标的字段时,可以考虑使用匿名对象/动态对象对其反序列化。
之前的
Newtonsoft.Json好像直接使用 dynamic,运用 JObject 进行处理,现在的不是那么容易。下文代码基于. NET 6,为了代码整洁,实际配置了 PropertyNameCaseInsensitive = true,但是下面代码中并没有体现。
数据
我们定义了如下的类型,并从 OData 获得了 str 字符串型数据。
public readonly static string str = """
{"@odata.context":"http://localhost:9000/api/v1/$metadata#DataDto","value":[{"id":"0b734ed7-2955-4af4-a902-35dc17871094","timestamp":1684839865920},{"id":"7e285d08-cdb3-4209-8335-0ff9b20d39ef","timestamp":1684836312421}]}
""";
public class DataDto
{
public string? Id { get; set; }
public long Timestamp { get; set; }
}
由于有元数据,我们无法直接将上面的字符串反序列化为 DataDto 的列表对象。
自定义类
最简单的方式,是对应此类对象,设计一个只用于反序列化的新类。
public class ODataEnumerableResultWrapper<T>
where T : class
{
public IEnumerable<T> Value { get; set; }
}
var meta = JsonSerializer.Deserialize<ODataEnumerableResultWrapper<DataDto>>(str);
var target = meta.Value;
匿名方式
可以使用 JsonNode 来直接反序列化,并使用类似键值对的形式访问。
public static void Main() {
JsonNode? meta = JsonSerializer.Deserialize<JsonNode>(str);
//如果直接是简单的对象,而不是数组,可以使用GetValue<T>这种形式。
var count = meta?["value"]?.Deserialize<IEnumerable<DataDto>>().Count();
Console.WriteLine(count);
}
}
注意,这样的操作和你反序列化为 JsonDocument/JsonElement 并没有什么本质的区别。
动态方式
由于设计区别,直接使用 dynamic 进行反序列化,得到的对象并不具有一般 dynamic 的性质(实际上是 System.Text.Json.JsonElement 对象)。因此,我们无法通过的 dynamic 访问成员的形式进行操作。
dynamic meta = JsonSerializer.Deserialize<dynamic>(str);
Console.WriteLine(meta.GetType());
//OUTPUT: System.Text.Json.JsonElement
有 文章 说可以使用 ExpandoOject 实现,但是实际上无法对子级对象进行类似的访问,因为获取的子级对象,实际上是 JsonElement。
dynamic meta = JsonSerializer.Deserialize<System.Dynamic.ExpandoObject>(str);
Console.WriteLine(meta.GetType());
//System.Dynamic.ExpandoObject
Console.WriteLine(meta.value);
//[{"id":"0b734ed7-2955-4af4-a902-35dc17871094","timestamp":1684839865920},{"id":"7e285d08-cdb3-4209-8335-0ff9b20d39ef","timestamp":1684836312421}]
Console.WriteLine(meta.value.GetType());
//System.Text.Json.JsonElement
当然可以通过自定义序列化的方式操作(见参考),但是这个办法与我们的不写额外代码的初衷相冲突,因此不考虑了。
参考
System.Text.Json匿名对象反序列化的更多相关文章
- MessagePack 和System.Text.Json 序列号 反序列化对比
本博客将测试MessagePack 和System.Text.Json 序列号 反序列化性能 项目文件: Program.cs代码: using BenchmarkDotNet.Running; us ...
- [译]试用新的System.Text.Json API
译注 可能有的小伙伴已经知道了,在.NET Core 3.0中微软加入了对JSON的内置支持. 一直以来.NET开发者们已经习惯使用Json.NET这个强大的库来处理JSON. 那么.NET为什么要增 ...
- 使用System.Text.Json处理Json文档以及部分坑
System.Text.Json处理Json文档需要用到JsonDocument,JsonElement,JsonProperty. JsonDocument就是一个表示Json文档的东西,JsonE ...
- c# System.Text.Json 精讲
本文内容来自我写的开源电子书<WoW C#>,现在正在编写中,可以去WOW-Csharp/学习路径总结.md at master · sogeisetsu/WOW-Csharp (gith ...
- 【译】System.Text.Json 的下一步是什么
.NET 5.0 最近发布了,并带来了许多新特性和性能改进.System.Text.Json 也不例外.我们改进了性能和可靠性,并使熟悉 Newtonsoft.Json 的人更容易采用它.在这篇文章中 ...
- .NET性能系列文章二:Newtonsoft.Json vs. System.Text.Json
微软终于追上了? 图片来自 Glenn Carstens-Peters Unsplash 欢迎来到.NET性能系列的另一章.这个系列的特点是对.NET世界中许多不同的主题进行研究.基准和比较.正如标题 ...
- 使用 System.Text.Json 时,如何处理 Dictionary 中 Key 为自定义类型的问题
在使用 System.Text.Json 进行 JSON 序列化和反序列化操作时,我们会遇到一个问题:如何处理字典中的 Key 为自定义类型的问题. 背景说明 例如,我们有如下代码: // 定义一 ...
- 从 Newtonsoft.Json 迁移到 System.Text.Json
一.写在前面 System.Text.Json 是 .NET Core 3 及以上版本内置的 Json 序列化组件,刚推出的时候经常看到踩各种坑的吐槽,现在经过几个版本的迭代优化,提升了易用性,修复了 ...
- 在.Net Core 3.0中尝试新的System.Text.Json API
.NET Core 3.0提供了一个名为System.Text.Json的全新命名空间,它支持reader/writer,文档对象模型(DOM)和序列化程序.在此博客文章中,我将介绍它如何工作以及如何 ...
- .NET Core 内置的 System.Text.Json 使用注意
System.Text.Json 是 .NET Core 3.0 新引入的高性能 json 解析.序列化.反序列化类库,武功高强,但毕竟初入江湖,炉火还没纯青,使用时需要注意,以下是我们在实现使用中遇 ...
随机推荐
- golang的类型转换
今天我们来说说一个大家每天都在做但很少深入思考的操作--类型转换. 本文索引 一行奇怪的代码 go的类型转换 数值类型之间互相转换 unsafe相关的转换 字符串到byte和rune切片的转换 sli ...
- USB协议详解第7讲(补充-USB帧和微帧剖析)
1.概念 (1)USB2.0帧和微帧属于物理层时间基准的概念,低速和全速下每个帧时长为1ms,高速下每个帧又分为8个微帧,即每个微帧时长为125us. (2)USB主机和设备控制器同步后,每个微帧起始 ...
- redis 配置文件 - 启动redis 使用文件配置启动
# Redis configuration file example. # # Note that in order to read the configuration file, Redis mus ...
- 3. 用过Konva吗,用过他的api吗
基础:使用konva,首先需要创建舞台也就是stage,然后创建一个Layer图层,将图层放到舞台上,将图形等内容放到图层上 ; 第一步:创建一个Stage舞台 , 就是创建一个 stage 实例 ...
- .NET程序获取当前IP经纬度,并通过经纬度实现天气查询功能
创建一个.net 8的webapi项目备用 编辑一个实体类,该实体类用于存储获取ip地址的经纬度数据使用 继续编辑三个类,用来存储对应经纬度的具体天气数据包: 改造默认的天气控制器,里 ...
- 中国移动基于 Kubernetes 的物联网边缘计算应用实践
作者:何毓川,中移物联网,云计算开发高级工程师 EdgeBox简介 中移物联网是中国移动集团在物联网方向的专业研发子公司,在各个垂直行业都有非常丰富和完成的解决方案. 本文通过中移物联网的物联网边缘计 ...
- 云原生爱好者周刊 | 使用 WASM 来写博客是什么感觉?
开源项目推荐 zzhack zzhack 是一个静态博客框架,是一个纯正的 WASM 应用,它由 Rust & Yew 来作为技术栈进行搭建,UI 设计比较美观,大家也可以直接使用该项目的设计 ...
- 12C RAC 故障分析 - ORA-17503: ksfdopn:2 Failed to open file +DATA/EIC1/PASSWORD/pwdeic1.256.957086685
一.故障描述 Oracle 12C PDBS(PDB NAME = WRYPC) 在note1节点上是MOUNTED状态,在note2节点上是READ WRITE状态.note1节点上启动该PDB长时 ...
- vite 设置网络代理
参考文档:vite 官网.node-http-proxy 完整示例: export default defineConfig({ server: { proxy: { // 字符串简写写法 '/foo ...
- Android添加OpenCV支持
首先下载OpenCV的SDK 推荐在官网下载. 官网地址:https://opencv.org/releases/ 也可以在OpenCV的GitHub上现在 GitHUb链接:https://gith ...