本文主要是介绍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
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 { get; set; } 22. [JsonConverter(typeof(StringEnumConverter))] 23. public Gender Gender { get; set; } 24. public int Age { get; set; } 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则包含。
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动态决定属性是否序列化的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!