Newtonsoft Json.NET动态决定属性是否序列化

2024-02-21 03:08

本文主要是介绍Newtonsoft Json.NET动态决定属性是否序列化,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

转自:http://www.it165.net/pro/html/201309/7044.html

本人用了,解决了现实的业务问题。


昨天提到Json.NET属性序列化设定,接获读者森哥留言:

请问黑大,
针对不需要序列化的「属性」是否可以透过程序「动态」设定或是过滤?

有预感迟早也会遇到这个靠杯火杯的考验,决定打铁趁热,马上来练习。所幸,Json.NET真的很强大,早就料想到此一需求,提供ContractResolver以实现神乎奇技的高度动态化。

我写了一个范例,展示两种动态决定应序列化属性的情境:

Serialize时传入属性名称数组作为参数,正向表列JSON应包含的属性。
由对象属性值决定属性是否要序列化,例如: 如果是女生就不包含年龄。(这几乎已弹性到极点,虽然实务上不常用到)
程序的做法是宣告两个继承自DefaultContractResolver的类别: LimitPropsContractResolver在建构时传入string[]参数列出要序列化的属性名称,并覆写CreateProperties方法,过滤base.CreateProperties()传回的IList<JsonProperty>,只保留前述string[]有列出的属性;HideAgeContractResolver则覆写CreateProperty()方法,由base.CreateProperty()取得JsonProperty,JsonProperty有个ShouldSerialize属性可以传入Lambda表达式,逐笔处理每个要序列化的对象,在Lambda表达式中可将对象转型为原型别进行判断,若不要序列化就传回false。 www.it165.net

 

view source print ?
01. using System;
02. using System.Collections.Generic;
03. using System.Linq;
04. using System.Reflection;
05. using System.Text;
06. using Newtonsoft.Json;
07. using Newtonsoft.Json.Converters;
08. using Newtonsoft.Json.Serialization;
09.  
10. namespace ConsoleApplication1
11. {
12. class Program
13. {
14. public enum Gender
15. {
16. Male, Female
17. }
18.  
19. public class Person
20. {
21. public string Name { getset; }
22. [JsonConverter(typeof(StringEnumConverter))]
23. public Gender Gender { getset; }
24. public int Age { getset; }
25. public Person(string name, Gender gender, int age)
26. {
27. Name = name; Gender = gender; Age = age;
28. }
29. }
30.  
31. public class HideAgeContractResolver : DefaultContractResolver
32. {
33. //REF: http://james.newtonking.com/projects/json/help/index.html?topic=html/ContractResolver.htm
34. protected override JsonProperty CreateProperty(MemberInfo member,
35. MemberSerialization memberSerialization)
36. {
37. JsonProperty p = base.CreateProperty(member, memberSerialization);
38. if (p.PropertyName == "Age")
39. {
40. //依性别决定是否要序列化
41. p.ShouldSerialize = instance =>
42. {
43. Person person = (Person)instance;
44. return person.Gender == Gender.Male;
45. };
46. }
47. return p;
48. }
49. }
50.  
51. public class LimitPropsContractResolver : DefaultContractResolver
52. {
53. string[] props = null;
54. public LimitPropsContractResolver(string[] props)
55. {
56. //指定要序列化属性的清单
57. this.props = props;
58. }
59. //REF: http://james.newtonking.com/archive/2009/10/23/efficient-json-with-json-net-reducing-serialized-json-size.aspx
60. protected override IList<JsonProperty> CreateProperties(Type type,
61. MemberSerialization memberSerialization)
62. {
63. IList<JsonProperty> list =
64. base.CreateProperties(type, memberSerialization);
65. //只保留清单有列出的属性
66. return list.Where(p => props.Contains(p.PropertyName)).ToList();
67. }
68.  
69. }
70.  
71. static void Main(string[] args)
72. {
73. List<Person> list = new List<Person>();
74. list.Add(new Person("George", Gender.Male, 18));
75. list.Add(new Person("Mary", Gender.Female, 40));
76. //正常输出
77. Console.WriteLine(JsonConvert.SerializeObject(
78. list, Formatting.Indented));
79. var settings = new JsonSerializerSettings();
80. //加上ContractResolver,正向表列哪些属性要序列化
81. settings.ContractResolver =
82. new LimitPropsContractResolver("Name,Age".Split(','));
83. Console.WriteLine(JsonConvert.SerializeObject(
84. list, Formatting.Indented, settings));
85. //加上ContractResolver,依对象的属性值动态决定要不要序列化
86. settings.ContractResolver = new HideAgeContractResolver();
87. Console.WriteLine(JsonConvert.SerializeObject(
88. list, Formatting.Indented, settings));
89. Console.ReadLine();
90.  
91. }
92. }
93. }

程序执行结果如下,共有三段输出,第一段为正常版;第二段套用LimitPropsContractResolver("Name,Age".Split(',')),故JSON中只见Name及Age,Gender被隐藏;第三段套用了HideAgeContractResolver(),如结果所示,Mary的JSON内容不包含年龄,George则包含。

 

view source print ?
01. [
02. {
03. "Name""George",
04. "Gender""Male",
05. "Age": 18
06. },
07. {
08. "Name""Mary",
09. "Gender""Female",
10. "Age": 40
11. }
12. ]
13. [
14. {
15. "Name""George",
16. "Age": 18
17. },
18. {
19. "Name""Mary",
20. "Age": 40
21. }
22. ]
23. [
24. {
25. "Name""George",
26. "Gender""Male",
27. "Age": 18
28. },
29. {
30. "Name""Mary",
31. "Gender""Female"
32. }
33. ]

演练完毕,内心激动澎湃,对Json.NET的景仰如淊淊江水,绵绵不绝~

如果奥斯卡有最佳组件奖,我提名它!


这篇关于Newtonsoft Json.NET动态决定属性是否序列化的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/730391

相关文章

如何自定义Nginx JSON日志格式配置

《如何自定义NginxJSON日志格式配置》Nginx作为最流行的Web服务器之一,其灵活的日志配置能力允许我们根据需求定制日志格式,本文将详细介绍如何配置Nginx以JSON格式记录访问日志,这种... 目录前言为什么选择jsON格式日志?配置步骤详解1. 安装Nginx服务2. 自定义JSON日志格式各

Django序列化中SerializerMethodField的使用详解

《Django序列化中SerializerMethodField的使用详解》:本文主要介绍Django序列化中SerializerMethodField的使用,具有很好的参考价值,希望对大家有所帮... 目录SerializerMethodField的基本概念使用SerializerMethodField的

python dict转换成json格式的实现

《pythondict转换成json格式的实现》本文主要介绍了pythondict转换成json格式的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下... 一开始你变成字典格式data = [ { 'a' : 1, 'b' : 2, 'c编程' : 3,

浅析CSS 中z - index属性的作用及在什么情况下会失效

《浅析CSS中z-index属性的作用及在什么情况下会失效》z-index属性用于控制元素的堆叠顺序,值越大,元素越显示在上层,它需要元素具有定位属性(如relative、absolute、fi... 目录1. z-index 属性的作用2. z-index 失效的情况2.1 元素没有定位属性2.2 元素处

Java实现XML与JSON的互相转换详解

《Java实现XML与JSON的互相转换详解》这篇文章主要为大家详细介绍了如何使用Java实现XML与JSON的互相转换,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录1. XML转jsON1.1 代码目的1.2 代码实现2. JSON转XML3. JSON转XML并输出成指定的

Jackson库进行JSON 序列化时遇到了无限递归(Infinite Recursion)的问题及解决方案

《Jackson库进行JSON序列化时遇到了无限递归(InfiniteRecursion)的问题及解决方案》使用Jackson库进行JSON序列化时遇到了无限递归(InfiniteRecursi... 目录解决方案‌1. 使用 @jsonIgnore 忽略一个方向的引用2. 使用 @JsonManagedR

mybatis-plus 实现查询表名动态修改的示例代码

《mybatis-plus实现查询表名动态修改的示例代码》通过MyBatis-Plus实现表名的动态替换,根据配置或入参选择不同的表,本文主要介绍了mybatis-plus实现查询表名动态修改的示... 目录实现数据库初始化依赖包配置读取类设置 myBATis-plus 插件测试通过 mybatis-plu

SpringBoot接收JSON类型的参数方式

《SpringBoot接收JSON类型的参数方式》:本文主要介绍SpringBoot接收JSON类型的参数方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、jsON二、代码准备三、Apifox操作总结一、JSON在学习前端技术时,我们有讲到过JSON,而在

基于Canvas的Html5多时区动态时钟实战代码

《基于Canvas的Html5多时区动态时钟实战代码》:本文主要介绍了如何使用Canvas在HTML5上实现一个多时区动态时钟的web展示,通过Canvas的API,可以绘制出6个不同城市的时钟,并且这些时钟可以动态转动,每个时钟上都会标注出对应的24小时制时间,详细内容请阅读本文,希望能对你有所帮助...

HTML5 data-*自定义数据属性的示例代码

《HTML5data-*自定义数据属性的示例代码》HTML5的自定义数据属性(data-*)提供了一种标准化的方法在HTML元素上存储额外信息,可以通过JavaScript访问、修改和在CSS中使用... 目录引言基本概念使用自定义数据属性1. 在 html 中定义2. 通过 JavaScript 访问3.