JSON

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

字号+ 作者:H5之家 来源:H5之家 2015-11-10 16:00 我要评论( )

昨天提到Json.NET属性序列化设定,接获读者森哥留言:请问黑大,针对不需要序列化的「属性」是否可以透过程序「动态」设定或是过滤?有预感迟早也会遇到这个靠杯火

  • > WEB开发 > ASP.NET > 正文
  • 编程大巴
  • Json.NET动态决定属性是否序列化

    作者:  发布日期:2013-09-05 19:28:19

    Tag标签:Json.NET  序列化  

  • 昨天提到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。

     

    using System; using System.Collections.Generic; using System.Linq; using System.Reflection; using System.Text; using Newtonsoft.Json; using Newtonsoft.Json.Converters; using Newtonsoft.Json.Serialization; namespace ConsoleApplication1 { class Program { public enum Gender { Male, Female } public class Person { public string Name { get; set; } [JsonConverter(typeof(StringEnumConverter))] public Gender Gender { get; set; } public int Age { get; set; } public Person(string name, Gender gender, int age) { Name = name; Gender = gender; Age = age; } } public class HideAgeContractResolver : DefaultContractResolver { //REF: ?topic=html/ContractResolver.htm protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization) { JsonProperty p = base.CreateProperty(member, memberSerialization); if (p.PropertyName == "Age") { //依性别决定是否要序列化 p.ShouldSerialize = instance => { Person person = (Person)instance; return person.Gender == Gender.Male; }; } return p; } } public class LimitPropsContractResolver : DefaultContractResolver { string[] props = null; public LimitPropsContractResolver(string[] props) { //指定要序列化属性的清单 this.props = props; } //REF: protected override IList<JsonProperty> CreateProperties(Type type, MemberSerialization memberSerialization) { IList<JsonProperty> list = base.CreateProperties(type, memberSerialization); //只保留清单有列出的属性 return list.Where(p => props.Contains(p.PropertyName)).ToList(); } } static void Main(string[] args) { List<Person> list = new List<Person>(); list.Add(new Person("George", Gender.Male, 18)); list.Add(new Person("Mary", Gender.Female, 40)); //正常输出 Console.WriteLine(JsonConvert.SerializeObject( list, Formatting.Indented)); var settings = new JsonSerializerSettings(); //加上ContractResolver,正向表列哪些属性要序列化 settings.ContractResolver = new LimitPropsContractResolver("Name,Age".Split(',')); Console.WriteLine(JsonConvert.SerializeObject( list, Formatting.Indented, settings)); //加上ContractResolver,依对象的属性值动态决定要不要序列化 settings.ContractResolver = new HideAgeContractResolver(); Console.WriteLine(JsonConvert.SerializeObject( list, Formatting.Indented, settings)); Console.ReadLine(); } } }

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

     

    [ { "Name": "George", "Gender": "Male", "Age": 18 }, { "Name": "Mary", "Gender": "Female", "Age": 40 } ] [ { "Name": "George", "Age": 18 }, { "Name": "Mary", "Age": 40 } ] [ { "Name": "George", "Gender": "Male", "Age": 18 }, { "Name": "Mary", "Gender": "Female" } ]

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

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

     

  • 延伸阅读:

    返回到首页 返回到编程大巴

  • Win32

  • Win32
  • OpenGL
  • ASP.NET MVC
  • cocos2d-x
  • WCF

  • WCF
  • Linq
  • Android

  • Android
  • QT
  • MFC

  • MFC
  • JQuery
  • 最新文章
  • 专家推荐
  • 热门专题

     

    1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。

    相关文章
    • DataSnap与JSON序列化3

      DataSnap与JSON序列化3

      2016-01-18 18:00

    • JSON对象克隆(JSON对象序列化)(支持function),json序列化

      JSON对象克隆(JSON对象序列化)(支持function),json序列化

      2016-01-14 18:12

    • php 中序列化和json使用介绍

      php 中序列化和json使用介绍

      2015-11-23 15:19

    • PHP中SERIALIZE和JSON序列化与反序列化的区别

      PHP中SERIALIZE和JSON序列化与反序列化的区别

      2015-11-15 12:49

    网友点评
    p