您的位置:首页 > Web前端 > JavaScript

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

2015-02-04 16:31 555 查看
转自: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
sourceprint?

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则包含。



view
sourceprint?

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的景仰如淊淊江水,绵绵不绝~

如果奥斯卡有最佳组件奖,我提名它!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐