首页 > 其他分享 >System.Text.Json匿名对象反序列化

System.Text.Json匿名对象反序列化

时间:2023-05-23 21:14:09浏览次数:39  
标签:Text dynamic System Json meta 序列化 public

以前就是一直使用 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

当然可以通过自定义序列化的方式操作(见参考),但是这个办法与我们的不写额外代码的初衷相冲突,因此不考虑了。

参考

标签:Text,dynamic,System,Json,meta,序列化,public
From: https://www.cnblogs.com/podolski/p/17426371.html

相关文章

  • 【836】Cannot import tensorflow_text
    Ref:Cannotimporttensorflow_textSometimesyouneedtoreinstallandupdatetensorflowtheninstalltensorflow_text.(Becauseyouneedyourtensorflow.__version__andtensorflow_text.__version__tohavethesameversion)Makesuretensorflowandtensor......
  • UE Build System:Target and Module
    Module是构成Unreal的基本元素,每一个Module封装和实现了一组功能,并且可以供其他的Module使用,整个UnrealEngine就是靠各个Module组合驱动的,连我们创建的游戏项目本身,都是一个单独的Module。那么UE又是怎么创建和构建这这些Module的呢?这是写这篇文章的主要目的,研......
  • 上下文管理者(ServletContext)
    作用1.获取全局初始化参数2.资源共享(servlet通信)能让上下文呢的Servlet相互关联起来3.获取资源文件生命周期创建服务器启动的时候会为每个项目创建一个servletContext上下文对象,servleContext是项目的一个引用销毁在服务器关闭或者移除项目的时候servletContext销毁获取方......
  • MVC4 部署 could not load file or assembly system.web.http.webhost.....出错
    1.确保项目是.net4.0版本 2.如下图标出的部分,确保这个dll引用是项目本地,找到项目下的“引用”,找到对应的引用右键属性,将“复制本地”改为True,这里我们可以在项目下新建一个存入dll的文件夹,将这些dll放在这个文件夹里面,路径引用改为复制本地为True后就自动引用这个文件夹的路......
  • golang context 应用
    packagemainimport( "context" "fmt" "time")funcmain(){ //创建初始上下文 ctx:=context.Background() //派生可取消的上下文 cancelCtx,cancel:=context.WithCancel(ctx) //启动一个Goroutine执行任务 godoTask(cancelCtx) //等待一段时......
  • SystemVerilog for Design Edition 2 Chapter 5
    SystemVerilogforDesignEdition2Chapter5SystemVerilogaddsseveralenhancementstoVerilogforrepresentinglargeamountsofdata.TheVerilogarrayconstructisextendedbothinhowdatacanberepresentedandforoperationsonarrays.Structureand......
  • drf——反序列化校验源码(了解)、断言、drf之请求和响应、视图之两个视图基类
    1.模块与包#模块与包 模块:一个py文件被别的py文件导入使用,这个py文件称之为模块,运行的这个py文件称之为脚本文件包:一个文件夹下有__init__.py#模块与包的导入问题'''1.导入模块有相对导入和绝对导入,绝对导入的路径是从环境变量开始的2.导入任何模块,如果......
  • Thrift 消息序列化分析过程
    序列化浮点型数据流程 bitwise_cast<unsigned__int64,double>(doublefrom)行74 C++ apache::thrift::protocol::TBinaryProtocolT<apache::thrift::transport::TTransport>::writeDouble(constdoubledub)行171 C++ apache::thrift::protocol::TVirtualProtocol<......
  • ServletContext接口详解
    1. ServletContext是什么?  14 *  ServletContext是接口,是Servlet规范中的一员。2. ServletContext是谁实现的?14 *  Tomcat服务器(WEB服务器)实现了ServletContext接口。 *  public class org.apache.catalina.core.ApplicationContextFacade implements ServletCont......
  • 关于Excel表格中对多个General或者Number数值格式的单元转换为Text文本时-值包含E+的
    对于单元格的值为默认的General或者Number数字时,我们可以直接选中,单元格,或者某个范围,可以直接将上面的格式处选择为Text这样就完成了一次格式转换,如下默认是General普通格式,我们直接就将其转换成Text文本格式不过只有当我们将鼠标双击一下单元格式,才会看到左上角看到熟悉的Text......