1.
JSON
格式化
2.
忽略指定成员
3.
忽略默认值成员
4.
忽略空值
(null)
成员
5.
驼峰命名序列化成员
6.
日期类型格式化
7.
解决序列化对象循环引用
8.
使用
JsonConverter
自定义成员转换
9.
使用
DefaultContractResolver
(契约分解器)指定序列化成员
10.
使用
JsonSerializer
对象序列化与反序列化
Ø
首先,准备数据
Goods
[] goods =
new
Goods
[]
{
new
Goods
()
{
GoodsId = 1,
GoodsName =
"
联想
ThinkPad
无线鼠标
"
,
//Price = 125.00m,
//IsQuota = true,
Attributes =
new
Goods
.
Attribute
[]
{
new
Goods
.
Attribute
() { Name =
"
品牌
"
, Value =
"Lenovo/
联想
"
},
new
Goods
.
Attribute
() { Name =
"
颜色
"
, Value =
"
黑色
"
}
},
Status =
Status
.Online
}
};
1.
JSON
格式化(可以采用以下
2
种方式)
1)
简单格式化(推荐)
string
jsonStr1_1_1 =
JsonConvert
.SerializeObject(goods, Newtonsoft.Json.
Formatting
.Indented);
结果:
[
{
"GoodsName": "
联想
ThinkPad
无线鼠标
",
"IsQuota": true,
"Status": "Online"
}
]
2)
使用
Newtonsoft.Json.JsonTextWriter
格式化
JsonSerializer
serializer1 =
new
JsonSerializer
();
using
(
StringWriter
textWriter =
new
StringWriter
())
{
using
(
JsonTextWriter
jsonWriter =
new
JsonTextWriter
(textWriter))
{
jsonWriter.Formatting = Newtonsoft.Json.
Formatting
.Indented;
//
默认为
Formatting.None
jsonWriter.Indentation = 4;
//
缩进字符数,默认为
2
jsonWriter.IndentChar =
' '
;
//
缩进字符,默认为
' '
serializer1.Serialize(jsonWriter, goods);
}
string
jsonStr1_2_1 = textWriter.ToString();
}
结果:
[
{
"GoodsName": "
联想
ThinkPad
无线鼠标
",
"IsQuota": true,
"Status": "Online"
}
]
2.
忽略指定成员
忽略指定序列化成员使用
JsonIgnore
特性,例如(修改
Goods
):
///
<summary>
///
商品名称
///
</summary>
[
JsonIgnore
]
public
string
GoodsName {
get
;
set
; }
1)
序列化
string
jsonStr2_1 =
JsonConvert
.SerializeObject(goods);
结果:
[{"IsQuota":true,"Status":"Online"}]
2)
反序列化
string
jsonStr2_2 =
"[{\"GoodsName\": \"
联想
ThinkPad
无线鼠标
\",\"IsQuota\":true,\"Status\":\"Online\"}]"
;
Goods
[] jsonObj2_1 =
JsonConvert
.DeserializeObject<
Goods
[]>(jsonStr2_2);
结果:
3.
忽略默认值成员(忽略
GoodsId
和
Price
这两个默认值)
可以采用两种方式实现:
1.
使用
JsonSerializerSettings
对象;
2
.
成员标记
JsonProperty
特性并指定
DefaultValueHandling
属性。
下面演示第一种实现方式:
1)
加入
DefaultValue
特性(修改
goods
)
///
<summary>
///
价格
///
</summary>
[System.ComponentModel.
DefaultValue
(125.00)]
public
decimal
Price {
get
;
set
; }
2)
创建
JsonSerializerSettings
对象
goods[0].GoodsId = 0;
//int
类型的本身默认值(
0
)
goods[0].Price = 125;
//
加了
System.ComponentModel.DefaultValue
特性的默认值(
125
)
var
settings1 =
new
JsonSerializerSettings
();
settings1.DefaultValueHandling =
DefaultValueHandling
.Ignore;
//
默认为
Include
3)
序列化
string
jsonStr3_1 =
JsonConvert
.SerializeObject(goods, settings1);
结果:
[{"GoodsName":"
联想
ThinkPad
无线鼠标
","IsQuota":true,"Status":"Online"}]
4)
反序列化
string
jsonStr3_2 =
"[{\"GoodsId\":0,\"GoodsName\":\"
联想
ThinkPad
无线鼠标
\",\"Price\":125,\"IsQuota\":true,\"Status\":\"Online\"}]"
;
Goods
[] jsonObj3_1 =
JsonConvert
.DeserializeObject<
Goods
[]>(jsonStr3_2, settings1);
结果:
4.
忽略空值
(null)
成员
可以采用两种方式实现:
1.
使用
JsonSerializerSettings
对象;
2
.
成员标记
JsonProperty
特性并指定
NullValueHandling
属性。
下面演示第一种实现方式:
goods[0].GoodsName =
null
;
var
settings2 =
new
JsonSerializerSettings
();
settings2.NullValueHandling =
NullValueHandling
.Ignore;
//
默认为
Include
1)
序列化
string
jsonStr4_1 =
JsonConvert
.SerializeObject(goods, settings2);
结果:
[{"GoodsId":0,"Price":125.0,"IsQuota":true,"Status":"Online"}]
5.
驼峰命名序列化成员
var
settings3 =
new
JsonSerializerSettings
();
settings3.ContractResolver =
new
CamelCasePropertyNamesContractResolver
();
1)
序列化
string
jsonStr5_1 =
JsonConvert
.SerializeObject(goods, settings3);
结果:
[{"goodsId":0,"price":125.0,"isQuota":true,"status":"Online"}]
6.
日期类型格式化
日期类型默认情况下,会序列化为一个带有
“T”
字符的日期字符串,比如:
2018-04-24T17:58:26.0096087+08:00
,
可以采用两种方式对日期类型格式化,例如(修改
Goods
):
///
<summary>
///
创建时间
///
</summary>
public
DateTime
CreateTime {
get
;
set
;}
goods[0].CreateTime =
DateTime
.Now;
//2018/4/24 17:58:26
1)
默认序列化
string
jsonStr6_1 =
JsonConvert
.SerializeObject(goods);
结果:
[{"GoodsId":0,"Price":125.0,"IsQuota":true,"Status":"Online",
"CreateTime":"2018-04-24T17:58:26.0096087+08:00"
}]
2)
使用
JsonSerializerSettings
对象格式化
var
settings4 =
new
JsonSerializerSettings
();
settings4.DateFormatString =
"yyy-MM-dd"
;
//
默认为:
yyyy'-'MM'-'dd'T'HH':'mm':'ss.FFFFFFFK
string
jsonStr6_2 =
JsonConvert
.SerializeObject(goods, settings4);
结果:
[{"GoodsId":0,"Price":125.0,"IsQuota":true,"Status":"Online",
"CreateTime":"2018-04-24"
}]
3)
使用
IsoDateTimeConverter
对象格式化
var
dateTimeConverter1 =
new
IsoDateTimeConverter
();
dateTimeConverter1.DateTimeFormat =
"yyy-MM-dd HH:mm:ss fff"
;
//
默认为
""
string
jsonStr6_3 =
JsonConvert
.SerializeObject(goods, dateTimeConverter1);
结果:
[{"GoodsId":0,"Price":125.0,"IsQuota":true,"Status":"Online",
"CreateTime":"2018-04-24 17:58:26 009"
}]
4)
也可以在日期类型成员指定
JsonConverter
特性,例如:
///
<summary>
///
创建时间
///
</summary>
[
JsonConverter
(
typeof
(Newtonsoft.Json.Converters.
IsoDateTimeConverter
))]
public
DateTime
CreateTime {
get
;
set
;}
7.
解决序列化对象循环引用
处理循环引用使用
JsonSerializerSettings
对象,并设置
ReferenceLoopHandling
属性,该属性是一个枚举类型,解释如下:
Error
|
默认值,发生循环引用时将抛出序列化异常:
Newtonsoft.Json.JsonSerializationException
|
Ignore
|
忽略循环引用的成员
|
Serialize
|
继续序列化,不管是否存在循环引用,指定该值将抛出溢出异常:
System.StackOverflowException
(感觉这个值没什么用?)
|
下面模拟循环引用场景(修改
Goods
):
///
<summary>
///
订单明细
///
</summary>
public
OrdersDetail
OrdersDetail {
get
;
set
; }
///
<summary>
///
订单明细
///
</summary>
public
class
OrdersDetail
{
///
<summary>
///
商品集合
///
</summary>
public
Goods
[] Goods {
get
;
set
; }
}
OrdersDetail
od =
new
OrdersDetail
() { Goods = goods };
goods[0].OrdersDetail = od;
1)
序列化
string
jsonStr7_1 =
JsonConvert
.SerializeObject(goods);
//
将抛出
JsonSerializationException
异常
2)
忽略循环引用
var
settings5 =
new
JsonSerializerSettings
();
settings5.ReferenceLoopHandling =
ReferenceLoopHandling
.Ignore;
string
jsonStr7_2 =
JsonConvert
.SerializeObject(goods, settings5);
结果:
[{"GoodsId":0,"Price":125.0,"IsQuota":true,"Status":"Online","CreateTime":"2018-04-25T09:57:52.8628936+08:00",
"OrdersDetail":{}
}]
8.
使用
JsonConverter
自定义成员转换
自定义成员转换使用
JsonConverter
类,该类是一个抽象类,实现
WriteJson
()
、
ReadJson
()
方法完成自定义序列化和反序列化。下面以
IsQuota
属性为例,自定义
B
o
olean
类型的序列化和反序列化操作。
1)
首先定义个
BoolConvert
类,继承于
Newtonsoft.Json.
JsonConverter
类
///
<summary>
///
自定义
Boolean
类型转换。
///
</summary>
public
class
BoolConvert
:
JsonConverter
{
private
static
readonly
string
[] _values = {
"
是
"
,
"
否
"
};
public
override
bool
CanConvert(
Type
objectType)
{
return
true
;
}
//
序列化时被调用
public
override
void
WriteJson(
JsonWriter
writer,
object
value,
JsonSerializer
serializer)
{
if
(value ==
null
)
writer.WriteNull();
//
输出:
null
else
if
((
bool
)value)
writer.WriteValue(_values[0]);
//
输出:是
else
writer.WriteValue(_values[1]);
//
输出:否
}
//
反序列化时被调用
public
override
object
ReadJson(
JsonReader
reader,
Type
objectType,
object
existingValue,
JsonSerializer
serializer)
{
//
反序列化成员是否为
null
值
if
(reader.TokenType ==
JsonToken
.Null)
{
if
(!IsNullableType(objectType))
throw
new
Exception
(
"
序列化成员不能为
null
值
"
);
return
null
;
}
else
if
(reader.TokenType ==
JsonToken
.String)
//
为字符型,应该是“是
|
否”
{
string
val = reader.Value.ToString();
if
(val == _values[0])
return
true
;
else
if
(val == _values[1])
return
false
;
}
else
if
(reader.TokenType ==
JsonToken
.Integer)
//
为
int
型,应该是:
0|1
{
return
Convert
.ToInt32(reader.Value) != 0;
//
非零即真
}
throw
new
Exception
(
"
反序列化不支持的
boolean
类型
"
);
}
//
判断是否为可空类型
private
bool
IsNullableType(
Type
type)
{
if
(type ==
null
)
throw
new
ArgumentNullException
(
"type"
);
return
type.BaseType.FullName ==
"System.ValueType"
&& type.GetGenericTypeDefinition() ==
typeof
(
Nullable
<>);
}
}
2)
修改
G
oods
类,添加
JsonConverter
特性。
///
<summary>
///
是否限购
///
</summary>
[
JsonConverter
(
typeof
(
BoolConvert
))]
public
bool
IsQuota {
get
;
set
; }
3)
序列化
goods[0].IsQuota =
true
;
string
jsonStr8_1 =
JsonConvert
.SerializeObject(goods);
结果:
[{"GoodsId":1,"Price":0.0,
"IsQuota":"
是
"
,"Status":"Online","CreateTime":"0001-01-01T00:00:00","OrdersDetail":null}]
4)
反序列化(字符型)
string
jsonStr8_2 =
"[{\"IsQuota\":\"
是
\"}]"
;
Goods
[] jsonObj8_1 =
JsonConvert
.DeserializeObject<
Goods
[]>(jsonStr8_2);
结果:
5)
反序列化(
int
型)
string
jsonStr8_3 =
"[{\"IsQuota\":1}]"
;
Goods
[] jsonObj8_2 =
JsonConvert
.DeserializeObject<
Goods
[]>(jsonStr8_3);
结果:
9.
使用
DefaultContractResolver
(契约分解器)指定序列化成员
我们可以从
DefaultContractResolver
类派生一个自定义成员分解器类,重写
CreateProperties
()
方法完成对每个序列化成员的操作,首先新建一
个
“
成员契约解析器
”类,例如:
///
<summary>
///
成员契约解析器。
///
</summary>
public
class
MemberContractResolver
:
DefaultContractResolver
{
public
string
[] Props {
get
;
set
; }
public
bool
IsRetain {
get
;
set
; }
///
<summary>
///
构造方法。
///
</summary>
///
<param name="props">
指定的成员名称数组。
</param>
///
<param name="isRetain">
是否保留指定成员,
true:
保留;
false:
不保留。
</param>
public
MemberContractResolver(
string
[] props,
bool
isRetain)
{
this
.Props = props;
this
.IsRetain = isRetain;
}
//
创建
JsonProperty
集合
protected
override
IList
<
JsonProperty
> CreateProperties(
Type
type,
MemberSerialization
memberSerialization)
{
List
<
JsonProperty
> list =
base
.CreateProperties(type, memberSerialization)
as
List
<
JsonProperty
>;
//
顺便设置下日期格式化
IsoDateTimeConverter
dtConverter =
new
IsoDateTimeConverter
() { DateTimeFormat =
"yyyy-dd-MM HH:mm:dd"
};
list.ForEach(o =>
{
if
(o.PropertyType ==
typeof
(
DateTime
))
o.Converter = dtConverter;
});
//
输出包含或不包含的指定的成员
if
(
this
.IsRetain)
return
list.Where(o => Props.Contains(o.PropertyName)).ToList();
else
return
list.Where(o => !Props.Contains(o.PropertyName)).ToList();
}
}
1)
序列化包含指定成员
JsonSerializerSettings
serializer6 =
new
JsonSerializerSettings
();
serializer6.ContractResolver =
new
MemberContractResolver
(
new
string
[] {
"GoodsName"
},
true
);
string
jsonStr9_1 =
JsonConvert
.SerializeObject(goods, serializer6);
结果:
[{"GoodsName":null}]
2)
序列化不包含指定成员
JsonSerializerSettings
serializer7 =
new
JsonSerializerSettings
();
serializer7.ContractResolver =
new
MemberContractResolver
(
new
string
[] {
"GoodsName"
},
false
);
string
jsonStr9_2 =
JsonConvert
.SerializeObject(goods, serializer7);
结果:
[{"GoodsId":0,"Price":125.0,"IsQuota":false,"Status":"Online","CreateTime":"2018-25-04 15:35:25","OrdersDetail":null}]
10.
使用
JsonSerializer
对象序列化与反序列化
序列化与反序列化除了使用
JsonConvert
这个静态类的
SerializeObject
()
、
DeserializeObject
()
方法,还可以使用
JsonSerializer
对象的
Serialize
()
、
Deserialize
()
方法,不过这两个方法用起来比较麻烦,所有不建议使用,知道下就好了。
序列化与反序列化:
JsonSerializer
serializer2 =
new
JsonSerializer
();
using
(
StringWriter
textWriter =
new
StringWriter
())
{
using
(
JsonTextWriter
jsonWriter =
new
JsonTextWriter
(textWriter))
{
//
这里可以使用
JsonTextWriter
对象进行序列化相关设置
serializer2.Serialize(jsonWriter, goods);
}
string
jsonStr10_1 = textWriter.ToString();
using
(
TextReader
textReader =
new
StringReader
(jsonStr10_1))
{
using
(
JsonTextReader
jsonTextReader =
new
JsonTextReader
(textReader))
{
//
这里可以使用
JsonTextReader
对象进行反序列化相关设置
object
obj = serializer2.Deserialize(jsonTextReader);
}
}
}
序列化:
[{"GoodsId":0,"GoodsName":null,"Price":125.0,"IsQuota":false,"Status":"Online","CreateTime":"2018-04-25T22:10:09.4901712+08:00","OrdersDetail":null}]
反序列化: