您好、欢迎来到现金彩票网!
当前位置:盛通彩票app下载 > 根编译程序 >

态编译NewtonsoftJson封装实现JSON转换器原理及JSON操作技巧

发布时间:2019-07-22 14:29 来源:未知 编辑:admin

  看文章标题就知道,本文的主题就是关于JSON,JSON转换器(JsonConverter)具有将C#定义的类源代码直接转换成对应的JSON字符串,以及将JSON字符串转换成对应的C#定义的类源代码,而JSON操作技巧则说明如何通过JPath来快速的定位JSON的属性节点从而达到灵活读写JSON目的。

  现在都流行微服务,前后端分离,而微服务之间、前后端之间数据交互更多的是基于REST FUL风格的API,API的请求与响应一般常用格式都是JSON。当编写了一些API后,为了能够清楚的描述API的请求及响应数据格式(即:JSON格式),以便提供给API服务的消费者(其它微服务、前端)开发人员进行对接开发,通常是编写API说明文档,说明文档中一般包含入参JSON格式说明以及响应的JSON格式说明示例,但如果API涉及数目较多,全由开发人员人工编写,那效率就非常低下,而且不一定准确。于是就有了Swagger,在API项目中集成swagger组件,就会由swagger根据API的ACTION方法定义及注解生成标准的在线API说明文档,具体用法请参见网上相关文章说明。当然除了swagger还有其它类似的集成式的生成在线API说明文档,大家有兴趣的话可以去网上找找资源。虽说swagger组件确实解放了开发人员的双手,无需人工编写就自动生成在线API文档,但我认为还是有一些不足,或者说是不太方便的地方:一是必需集成到API项目中,与API项目本身有耦合与依赖,无法单独作为API帮助文档项目,在有些情况下可能并不想依赖swagger,不想时刻把swagger生成API文档暴露出来;二是目前都是生成的在线API文档,如果API在某些网络环境下不可访问(比如:受限),那在线的API文档基本等同于没用,虽说swagger也可以通过复杂的配置或改造支持导出离线的API文档,但总归是有一定的学习成本。那有没有什么替代方案能解决swagger类似的在线API文档的不足,又避免人工低效编写的状况呢?可能有,我(梦在旅途)没了解过,但我为了解决上述问题,基于.NET动态编译&Newtonsoft.Json封装实现了一个JSON转换器(JsonConverter),采用人工编写+JSON自动生成的方式来实现灵活、快速、离线编写API说明文档。

  class类源代码转换成Json字符串:先将项目中定义的class类源代码复制粘贴到Class Code文本框区域【注意:若有继承或属性本身又是另一个类,则相关的class类定义源代码均应一同复制,using合并,namespace允许多个,目的是确保可以动态编译通过】,然后点击上方的【Parse】按钮,以便执行动态编译并解析出Class Code文本框区域中所包含的class Type,最后选择需要生成JSON的class Type,点击中间的【To Json】按钮,即可将选择的class Type 序列化生成JSON字符串并展示在右边的Json String文本框中;

  有了这个功能以后,API写好后,只需要把ACTION方法的入参class源代码复制过来然后进行class to JSON转换即可快速生成入参JSON,不论是自己测试还是写文档都很方便。建议使用markdown语法来编写API文档。

  Json字符串转换成class类定义源代码:先将正确的JSON字符串复制粘贴到Json String文本框中,然后直接点击中间的【To Class】按钮,弹出输入要生成的class名对话框,输入后点击确定就执行转换逻辑,最终将转换成功的class定义源代码展示在左边的Class Code文本框区域中;

  示例效果如下图示:(支持复杂属性,能够递归生成JSON所需的子类,类似如下的Address,注意暂不支持数组嵌套数组这种非常规的格式,即:[ [1,2,3],[4,5,6] ])

  动态编译是:Parse,序列化是:ToJsonString,需要关注的点是:动态编译时,需要引用相关的.NET运行时DLL,而这些DLL必需在工具的根目录下,否则可能导致引用找不到DLL导致编译失败,故项目中引用了常见的几个DLL,并设置了复制到输出目录中,如果后续有用到其它特殊的类型同样参照该方法先把DLL包含到项目中,并设置复制到输出目录中,然后在动态编译代码中使用cp.ReferencedAssemblies.Add(XXXX.dll);进行添加。核心代码如下:

  Json to Class code 先使用JObject.Parse将json字符串转换为通用的JSON类型实例,然后直接通过获取所有JSON属性集合并遍历这些属性,通过判断属性节点的类型,若是子JSON类型【即:JObject】则创建对象属性字符串 同时递归查找子对象,若是数组类型【即:JArray】则创建List集合属性字符串,同时进一步判断数组的元素类型,若是子JSON类型【即:JObject】则仍是递归查找子对象,最终拼接成所有类及其子类的class定义源代码字符串。核心代码如下:

  把JSON字符串转换为class类源代码,除了我这个工具外,网上也有一些在线的转换网页可以使用,另外我再分享一个小技巧,即:直接利用VS的编辑-》【选择性粘贴】,然后选择粘贴成JSON类或XML即可,菜单位置:

  一般操作JSON,大多要么是把class类的实例数据序列化成JSON字符串,以便进行网络传输,要么是把JSON字符串反序列化成class类的数据实例,以便可以在程序获取这些数据。然而其实还有一些不常用的场景,也是与JSON有关,详见如下说明。

  场景一:如果已有JSON字符串,现在需要获得指定属性节点的数据,且指定的属性名不确定,由外部传入或逻辑计算出来的【即:不能直接在代码中写死要获取的属性逻辑】,那么这时该如何快速的按需获取任意JSON节点的数据呢?

  常规解决方案:先反序列化成某个class的实例对象(或JObject实例对象),然后通过反射获取属性,并通过递归及比对属性名找出最终的属性,最后返回该属性的值。

  场景二:如果已有某个class实例对象数据,现在需要动态更改指定属性节点的数据【即动态给某个属性赋值】,该如何操作呢?

  常规解决方案:通过反射获取属性,并通过递归及比对属性名找出最终的属性,最后通过反射给该属性设置值。

  场景三:如果已有JSON字符串,现在需要动态添加新属性节点,该属性节点可以是任意嵌套子对象的属性节点中,该如何操作呢?

  常规解决方案:先反序列化成JObject实例对象,然后递归查找目标位置,最后在指定的位置创建新的属性节点。

  三种场景归纳一下其实就是需要对JSON的某个属性节点数据可以快速动态的增、改、删、查操作,然而常规则解决方案基本上都是需要靠递归+反射+比对,运行性能可想而知,而我今天分享的JSON操作技巧就是解决上述问题的。

  重点来了,我们可以通过JPath表达式来快速定位查找JSON的属性节点,就像XML利用XPath一样查找DOM节点。

  JPath表达式是什么呢? 详见:,Xpath与JSONPath对比用法如下图示(图片来源于文中):

  代码中如何使用JPath表达式呢?使用JObject.SelectTokens 或 SelectToken方法即可,我们可以使用SelectTokens(jpath)表达式直接快速定位指定的属性节点,然后就可以获得该属性节点的值,若需要该属性设置值,则可以通过该节点找到对应的所属属性信息进行设置值即可,而动态根据指定位置【一般是某个属性节点】添加一个新的属性节点,则可以直接使用JToken的AddBeforeSelf、AddAfterSelf在指定属性节点的前面或后面创建同级新属性节点,是不是非常简单。原理已说明,最后贴出已封装好的实现代码:

  控制台输出的结果如下:可以观察JSON1(原JSON),JSON2(改变了JSON值),JSON3(增加了JSON属性节点)

http://dora6.net/genbianyichengxu/799.html
锟斤拷锟斤拷锟斤拷QQ微锟斤拷锟斤拷锟斤拷锟斤拷锟斤拷锟斤拷微锟斤拷
关于我们|联系我们|版权声明|网站地图|
Copyright © 2002-2019 现金彩票 版权所有