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

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

参考

  • c# - Is it possible to deserialize json string into dynamic object using System.Text.Json? - Stack Overflow
本文转载于网络 如有侵权请联系删除

相关文章

  • 宕机了,缓存数据没了。。。

    AOF日志 试想一下,如果Redis每执行一条写操作命令,就把该命令以追加的方式写入到一个文件里,然后重启Redis的时候,先去读取这个文件里的命令,并且执行它,这不就相当于恢复了缓存数据了吗?这种保存写操作命令到日志的持久化方式,就是Redis里的AOF(AppendOnlyFile)持久化功能,注意只会记录写操作命令,读操作命令是不会被记录的,因为没意义。在Redis中AOF持久化功能默认是不开启的,需要我们修改redis.conf配置文件中的以下参数:AOF日志文件其实就是普通的文本,我们可以通过cat命令查看里面的内容,不过里面的内容如果不知道一定的规则的话,可能会看不懂。我这里以「setnamexiaolin」命令作为例子,Redis执行了这条命令后,记录在AOF日志里的内容如下图:我这里给大家解释下。「*3」表示当前命令有三个部分,每部分都是以「+数字」开头,后面紧跟着具体的命令、键或值。然后,这里的「数字」表示这部分中的命令、键或值一共有多少字节。例如,「3set」表示这部分有3个字节,也就是「set」命令这个字符串的长度。不知道大家注意到没有,Redis是先执行写操作命

  • 基于互信息正则化策略梯度的隐私约束策略(CS LG)

    随着强化学习技术越来越多地应用于现实世界的决策问题,人们的注意力已转向这些算法如何使用潜在的敏感信息。我们认为培训策略的任务是最大化奖励,同时通过行动将某些敏感状态变量的披露最小化。我们将举例说明此设置如何涵盖隐私中的实际问题,以便进行顺序决策。在策略梯度框架中,我们通过引入基于敏感状态和给定时间步长之间的互信息(MI)的正则化器来解决此问题。我们开发了一种基于模型的随机梯度估计器,用于优化隐私约束策略,还讨论了另一种MI正则化器,它作为我们主要MI正则化器的上限,并且可以在无模型的设置中进行优化。我们将差别隐私强化学习中的先前工作与信息披露的相互信息表述进行了对比。实验结果表明,我们的训练方法产生了隐藏敏感状态的策略。原文题目:Privacy-ConstrainedPoliciesviaMutualInformationRegularizedPolicyGradients原文:Asreinforcementlearningtechniquesareincreasinglyappliedtoreal-worlddecisionproblems,attentionhasturnedtoh

  • 他们为什么选择中科大少年班?官方公布48名新生名单,有人因偶像曹原,有人只是不想经历高三

    边策杨净发自凹非寺 量子位报道|公众号QbitAI中国最受关注的大学和“专业”?中科大少年班,一定是绕不过去的一个。就在新生开学季,中国科学技术大学官方也公布了2020年中科大少年班录取名单。今年共有48名学生被录取,其中女10名、男38名,分别来自13个省市。中科大官方称,本届的招生对象需符合:2004年1月1日及以后出生、高二(含)以下学生。换而言之,光年龄维度来看,入选者大概在16岁左右。当然,“年龄”是中科大少年班的标签,但也是其自1978年创办以来,一直在赞誉和争议的地方。虽然这种培育方式被批评为“揠苗助长”,但不可否认的是,这40多年来已经培养了无数顶级人才。他们在产业界、学术界大放异彩。比如,24岁就发表了4篇Nature的曹原、前微软亚洲研究院院长张亚勤、百度联合创始人马东敏等等。而且从公开信息来看,这届少年班里,并非只是智商卓绝、应试学习能力很强的天才。录取学生分布:浙江人数第一在这份名单里,坐阵主场的安徽不是录取人数最多的省份,反而是浙江以12人位居第一,安徽11人、湖南6人、江苏5人分列二三四。而因为浙江、湖南、江苏、湖北和广东等录取人数众多,按中国地理传统南北方

  • 聊聊nacos-sdk-go的NamingProxy

    序本文主要研究一下nacos-sdk-go的NamingProxyNamingProxynacos-sdk-go-v0.3.2/clients/naming_client/naming_proxy.gotypeNamingProxystruct{ clientConfigconstant.ClientConfig nacosServernacos_server.NacosServer }复制NamingProxy定义了clientConfig、nacosServer属性NewNamingProxynacos-sdk-go-v0.3.2/clients/naming_client/naming_proxy.gofuncNewNamingProxy(clientCfgconstant.ClientConfig,serverCfgs[]constant.ServerConfig,httpAgenthttp_agent.IHttpAgent)(NamingProxy,error){ srvProxy:=NamingProxy{} srvProxy.clientConfig=clientCfg

  • Facebook认罚50亿美元创纪录,剑桥分析事件尘埃落定

    昨日,联邦法院正式批准美国联邦贸易委员会(FTC)和Facebook之间的用户个人隐私问题和解协议,Facebook认罚50亿美元。2019年7月,FTC在对Facebook和剑桥分析公司滥用用户数据事件进行长期调查后,就相关问题达成了和解协议。这场和解可以说是具有里程碑的意义,50亿美元是有史以来对侵犯隐私科技公司的最高罚款,远远超过2012年谷歌的2200万美元,或者其他隐私罚款。同时,对于美国联邦委员会来说这也是有史以来最大的一笔罚款。该和解协议除了罚款还包含其他条款,比如增加隐私措施,并提供季度报告来证明遵守隐私协议。除此以外,Facebook还同意成立一个专门的隐私委员会,以此来加强用户隐私保护。Facebook首席产品隐私官MichelProtti在公司的一篇博客文章中说:“这项和解协议已经给我们的公司带来了根本性的变化,我们在保护人们隐私方面取得了前所未有的进步。最重要的是,它带来了新的责任水平,并确保隐私是Facebook每个人的责任。”协议对Facebook的业务运营增加了新限制,并建立了多种合规渠道,要求Facebook从公司董事会层面向下调整其隐私保护方法,并建立

  • python paramiko

    Win7下Python2.7环境安装paramiko模块Win7下Python2.7环境安装paramiko模块,有需要的朋友可以参考下近段时间用Python写一个小东西,每次修改代码后要手工上传到服务器,觉得很麻烦,虽然有WinSCP,找了一下资料,发现paramiko可以实现自动上传文件的功能,可惜的是,折腾了半天,在Python3.3下没有成功,最后退而求其次安装了2.7才弄好,记录如下:1.下载安装Windows版本的Python2.7,我默认装在C:\Python272.下载PyCrypto2.6forPython2.764bit 地址为http://www.voidspace.org.uk/python/modules.shtml#pycrypto 以管理员权限执行安装程序,一路Next即可3.下载安装ecdsa-0.10.tar.gz,地址https://pypi.python.org/packages/source/e/ecdsa/ecdsa-0.10.tar.gz解压缩 进入安装目录,执行C:\Python27\pythonsetup.pyinstall4.下载par

  • 如何在SAP Cloud Platform ABAP编程环境里创建一个employee

    版权声明:本文为博主原创文章,遵循CC4.0BY-SA版权协议,转载请附上原文出处链接和本声明。本文链接:https://jerry.blog.csdn.net/article/details/102739735用ABAPDevelopmentTool登录SAPCloudPlatformABAP编程环境后,对ABAP项目点击右键,选择属性,从而找到该环境的web访问的url:https://325df18f-0b6b-4d85-a127-ee6ad7437a7c.abap.eu10.hana.ondemand.com登录web界面,实际上是一个FioriUI,点击tileMaintainemployee:新建一个employee:维护email地址:给其维护业务角色:

  • java中的lastIndexOf( )函数是什么意思

    String中的lastIndexOf方法,是获取要搜索的字符、字符串最后次出现的位置。可以看到有四个重载方法分别是:publicintlastIndexOf(intch); publicintlastIndexOf(intch,intfromIndex); publicintlastIndexOf(Stringstr); publicintlastIndexOf(Stringstr,intfromIndex);复制四个方法,其中第一、第二个方法时对char(字符)进行匹配,区别在于第二个方法多了个参数fromIndex,该参数的含义是从String(字符串)中的第几位开始向前进行匹配。同理第三个和第四个方法时对字符串进行匹配,第四个方法可以申明开始向前匹配的位置。示例1如下:publicclassTest{ publicstaticvoidmain(String[]args){ Stringstr="sdasaq"; System.out.println(str.lastIndexOf('a'));//4 System.out.println(

  • 有趣的Python开源库之Hashids

    Hashids是一个非常小巧的跨语言的开源库,它用来把数字编码成一个随机字符串。它不同于md5这种算法这种单向映射,Hashids除了编码还会解码。拿论坛来说,一般帖子在数据库里的id都是顺序递增的,但是你可能不想在url上直接把id暴露出来,以免爬虫直接遍历id爬取你的内容,给你带来损失。那现在你就可以使用Hashids把这个id搞乱,让它失去顺序性,无法直接遍历,这样就可以直接提高了爬虫的门槛。著名的Youtube网站就是这么做的。我们来看看它怎么使用首先安装一下pipinstallhashids我们看到hashids不仅可以编码一个整数,还可以一次编码多个整数。解码的时候不需要对字符串进行分割,可以直接解码成多个整数。这在存储一个帖子的相关帖子时给我们多了一种选择,一般我们使用json打包多个帖子id放在帖子表的一个字段里,现在我们就可以使用hashids把它们编码成一个字符串塞进去了,可以节省一定的存储空间。不过,除此之外我想不到编码多个整数有什么其它的用途了。hashids需要提供一个salt值,相当于编解码的私钥,别人不知道你的私钥,就无法编码出对应的帖子的展现key,也无

  • 神经网络进化能否改变机器学习?

    神经网络进化通过筛选人工神经网络中的神经通路来模拟自然进化。神经进化将进化算法和人工神经网络结合起来,能像类似于地球上大脑进化的方式来训练系统。许多与机器学习相关的概念已经存在了几十年。然而,在过去的几年中,由于计算能力的巨大进步,研究人员才得以探索那些已经停滞不前的算法和方法。在人工智能领域,有一个概念突然引起了人们的注意:神经进化。这种方法通过筛选人工神经网络中的神经通路来模拟自然进化。通过突变,它确定了处理特定任务最有效的途径。在未来几年,神经进化通过允许系统更动态、更智能地进行调整和适应,可能会影响各种领域,如机器人、医学和后勤。虽然这个概念的起源可以追溯到20世纪80年代,但一直到今天,计算能力的发展才使研究人员能够给旧算法注入新的活力。“神经进化将进化算法和人工神经网络结合起来。其结果是得到了一种训练系统的方法,该方法与人类大脑的进化方式非常相似。”Uber人工智能实验室的高级研究科学家KennethStanley解释道。自然(代码)选择神经进化受自然的启发。传统的深度学习使用一种被称为随机梯度下降(SGD)的方法;它通过不断的训练,逐步减少误差,从而改进算法。尽管SGD在

  • Netty之Unpooled_Bytebuf

    前言 计算机存储基本单位是字节(byte),传输基本单位是bit(位),JAVANIO提供了ByteBuffer等七种容器来提升传输时的效率,但是在使用时比较复杂,经常要进行读写切换,主要缺点如下: (1)ByteBuffer长度固定,一旦分配完成,它的容量不能动态扩展和收缩,当需要编码的对象大于ByteBuffer的容量时,会发生索引越界异常; (2)ByteBuffer只有一个标识位置的指针position,读写的时候需要手工调用flip()和rewind()等,使用者必须小心谨慎地处理这些API,否则很容易导致程序处理失败; (3)ByteBuffer的API功能有限,一些高级和实用的特性它不支持,需要使用者自己编程实现。 为了弥补这些不足,Netty提供了自己的ByteBuffer实现——ByteBuf。 ByteBuf介绍 ByteBuf是Netty.Buffer中的类,主要特征如下: 读和写用不同的索引。 读和写可以随意的切换,不需要调用flip()方法。 容量能够被动态扩展,和StringBuilder一样。 用其内置的复合缓冲区可实现透明的零拷贝。 支持方法链。 支

  • Jenkins Pipeline 动态参数传递 Git 分支

    背景 公司其中一个项目采用分支上线模式,每次生产上线都需要修改Jenkins任务中的Git分支版本,改为参数传递Git分支。 实现 我们采用参数传递Git分支,另外也可使用GitParameter插件实现,会列出所有的Git分支。 在Jenkins任务中添加String类型参数:GIT_BRANCH。用于存储Git分支名称。 在Pipeline中配置Git分支参数变量:${GIT_BRANCH}。 就可以将Git分支名称通过GIT_BRANCH参数传递进行构建。 执行后报错: stderr:fatal:Couldn'tfindremoterefrefs/heads/${GIT_BRANCH} 解决办法 取消Pipeline的lightweightcheckout(轻量级检出)选项,就可以正常构建。 https://issues.jenkins.io/plugins/servlet/mobile#issue/JENKINS-28447 作者:蒋李恒 出处:https://www.cnblogs.com/daodaotest/ 如果你想及时得到个人撰写文章的消

  • JAVA实现两种方法反转单列表

    /** *@authorluochengcheng *定义一个单链表 */ classNode{ //变量 privateintrecord; //指向下一个对象 privateNodenextNode; publicNode(intrecord){ super(); this.record=record; } publicintgetRecord(){ returnrecord; } publicvoidsetRecord(intrecord){ this.record=record; } publicNodegetNextNode(){ returnnextNode; } publicvoidsetNextNode(NodenextNode){ this.nextNode=nextNode; } } /** *@authorluochengcheng *两种方式实现单链表的反转(递归、普通) *新手强烈建议旁边拿着纸和笔跟着代码画图(便于理解) */ publicclassReverseSingleList{ /** *递归,在反转当前节点之前先反转后续节点 */ public

  • 多线程输出奇偶数

    #include<pthread.h> #include<iostream> #include<stdlib.h> #include<unistd.h> #include<stdio.h> usingnamespacestd; pthread_cond_tqready=PTHREAD_COND_INITIALIZER; pthread_mutex_tqlock=PTHREAD_MUTEX_INITIALIZER; boolflag=false; inti=0; void*PrintA(void*arg){ while(1){ pthread_mutex_lock(&qlock); pthread_cond_wait(&qready,&qlock); cout<<"A="<<i<<endl; i++; pthread_mutex_unlock(&qlock); flag=false; if(i>=100){ break; } } } void*PrintB

  • Eclipse 安装插件

    Eclipse安装插件 本文介绍Eclipse插件的安装方法。Eclipse插件的安装方法大体有三种:直接复制、使用link文件,以及使用eclipse自带的图形界面的插件安装方法。 AD: 做为当下最流行的开源IDE之一,Eclipse的一大优势就在于其无数优秀的插件。一个好的插件可以大大的提高我们的工作效率,学习如何安装Eclipse插件自然也是必修课了。下面介绍Eclipse插件的安装方法。 Eclipse插件的安装方法大体有以下三种: 第一种:直接复制法 假设你的Eclipse的在(C:\eclipse),解压你下载的eclipse插件或者安装eclipse插件到指定目录AA(c:\AA)文件夹,打开AA文件夹,在AA文件夹里分别包含两个文件夹features和plugins,然后把两个文件夹里的文件分别复制到eclipse下所对应的文件夹下的features和plugins下,一般的把插件文件直接复制到eclipse目录里是最直接也是最愚蠢的一种方法!因为日后想要删除这些插件会非常的困难!强列的不推荐使用!! 注意:直接将插件包解压到plugins文件夹下之后,重启

  • Anaconda下安装tensorflow

      安装anaconda 1.常用命令(tensorflow是对应的环境名) 查看有什么环境:condainfo--envs 激活环境:condaactivatetensorflow 关闭环境:condadeactivatetensorflow 移除环境:condaremove-ntensorflow--all 2.安装anaconda 选择官网下载, 2.1安装简单不赘述,注意两个地方的选择     有的说不勾选第一个,可能会出现“无法定位到动态链接库”的问题,之后手动添加。我直接都勾选安装了,幸运的是没有遇到问题。 2.2安装成功之后查看安装成功与否,进入cmd中 cmd中输入:conda--version,查看是否有conda环境(成功的标志) cmd中输入:python--version,查看安装的python版本 cmd中输入:condainfo,查看是否有虚拟环境 打开AnacondaNavigator,能进入页面,安装成功。 3.搭建tensorflow环境 新创建的虚拟环境不会像<base>环境一样,带着基本包,numpy,

  • 为什么不建议你在 Docker 中跑 MySQL?

    容器的定义:容器是为了解决“在切换运行环境时,如何保证软件能够正常运行”这一问题。 目前,容器和Docker依旧是技术领域最热门的词语,无状态的服务容器化已经是大势所趋,同时也带来了一个热点问题被大家所争论不以:数据库MySQL是否需要容器化?     认真分析大家的各种观点,发现赞同者仅仅是从容器优势的角度来阐述MySQL需要容器化,几乎没有什么业务场景进行验证自己的观点;反过来再看反对者,他们从性能、数据安全等多个因素进行阐述MySQL不需要容器化,也举证了一些不适合的业务场景。下面就来聊下Docker不适合跑MySQL的原因!     1. 数据安全问题 不要将数据储存在容器中,这也是Docker官方容器使用技巧中的一条。容器随时可以停止、或者删除。当容器被rm掉,容器里的数据将会丢失。为了避免数据丢失,用户可以使用数据卷挂载来存储数据。但是容器的Volumes设计是围绕UnionFS镜像层提供持久存储,数据安全缺乏保证。如果容器突然崩溃,数据库未正常关闭,可能会损坏数据。另外,容器里共享数据卷组,对物理机硬件损伤也比较大。

  • cookie记录用户名

    在说如何用cookie记录用户名之前,我们先来说说cookie的工作原理: cookie:存储数据,当用户访问了某个网站(网页)的时候,我们就可以通过cookie来像访问者电脑上存储数据; 1.不同的浏览器存放的cookie位置不一样,也是不能通用的; 2.cookie的存储是以域名形式进行区分的; 3.cookie的数据可以设置名字的; 4.一个域名下存放的cookie的个数是有限制的,不同的浏览器存放的个数不一样; 5.每个cookie存放的内容大小也是有限制的,不同的浏览器存放大小不一样; 6.我们通过document.cookie来获取当前网站下的cookie的时候,得到的字符串形式的值,他包含了当前网站下所有的cookie。他会把所有的cookie通过一个分号+空格的形式串联起来; 7.如果我们想长时间存放一个cookie。需要在设置这个cookie的时候同时给他设置一个过期的时间; 8.cookie默认是临时存储的,当浏览器关闭进程的时候自动销毁; cookie的存储方式: document.cookie='名字=值'; document.cookie='use

  • 定时任务框架Quartz-(一)Quartz入门与Demo搭建

    https://blog.csdn.net/noaman_wgs/article/details/80984873 转载请注明出处 https://www.cnblogs.com/xinruyi 喜欢可以点击关注我

  • 第二次作业

    这个作业属于那个课程 https://edu.cnblogs.com/campus/zswxy/software0102 这个作业要求在哪里 https://viewer.mosoteach.cn/viewer?token=72055ae819e90ec53a488d17b296e0e4&screenx=false&app_id=MTWEB&app_version=5.2.0&location= 我在这个课程的目标是 通过思维导图,规划学习的时间计划 其他文件参考 《软件工程与实践(第四版)》、CSDN博客、博客园 一、寄语:写在前面的话 目标 回顾当初,自己在选择专业的时候也感觉到很迷茫,只是对电脑方面更感兴趣,所以最后选择了软件工程。一晃眼就到了大三,我接下来两年的目标主要是完成软考和四六级考试。我目前对前端比较感兴趣,所以我选择了Web前端作为自己的目标,加深对这方面的学习,对未来就业提供帮助。 榜样 在我们班上有很多值得我学习的榜样,最令我佩服的就是我的室友裴增,他能朝着自己的梦想努力奋斗,专业课程从未落下,平时也积极

  • Java 并发编程:volatile的使用及其原理

    Java并发编程系列: Java并发编程:核心理论  Java并发编程:Synchronized及其实现原理 Java并发编程:Synchronized底层优化(轻量级锁、偏向锁) Java并发编程:线程间的协作(wait/notify/sleep/yield/join) Java并发编程:volatile的使用及其原理  一、volatile的作用   在《Java并发编程:核心理论》一文中,我们已经提到过可见性、有序性及原子性问题,通常情况下我们可以通过Synchronized关键字来解决这些个问题,不过如果对Synchronized原理有了解的话,应该知道Synchronized是一个比较重量级的操作,对系统的性能有比较大的影响,所以,如果有其他解决方案,我们通常都避免使用Synchronized来解决问题。而volatile关键字就是Java中提供的另一种解决可见性和有序性问题的方案。对于原子性,需要强调一点,也是大家容易误解的一点:对volatile变量的单次读/写操作可以保证原子性的,如long和double类型变量,但是并不能保

相关推荐

推荐阅读