本文主要是介绍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动态决定属性是否序列化的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!