NewtonSoft.JSON官方手册中文版【连载4】

即将推出本人原译的NewtonSoft.JSON官方手册中文版完整文档(.chm格式),敬请期待!

序列化教程

 

Json.NET序列化器可以序列化各种各样的.NET对象。此教程着眼于它如何工作,先讲高层次,后深入细节。

  • 摘要
  • 复合类型
  • 基元类型
  • 类型序列化的分解

摘要

在高层次,Json.NET序列化器将把基元.NET值转换为基元JSON值,将把.NET数组和集合转换为JSON数组,将把其它的一切转换为JSON对象。

在反序列化一个值时,如果Json.NET遭遇了不正确的JSON,它将抛出一个错误。例如,如果序列化器遭遇了一个JSON属性,带有一个值的数组,而且匹配.NET属性的类型不是一个集合,则将抛出一个错误,反之亦然。

复合类型

.NETJSON
IList, IEnumerable, IList<T>, ArrayArray (集合上的属性不能被序列化)
IDictionary, IDictionary<TKey, TValue>Object (只有字典名、值,不会序列化字典上的属性)
Object (more detail below)Object

基元类型

.NETJSON
StringString
Byte
SByte
UInt16
Int16
UInt32
Int32
UInt64
Int64
Integer
Float
Double
Decimal
Float
EnumInteger (can be the enum value name with StringEnumConverter)
DateTimeString (Serializing Dates in JSON)
Byte[]String (base 64 encoded)
TypeString (type name)
GuidString
TypeConverter (convertible to String)String

类型序列化的分解

此节内容包含了下面的小节:

  • Objects
  • IEnumerable, Lists, and Arrays
  • Dictionaries and Hashtables
  • Untyped Objects
  • Dynamic
  • ISerializable
  • LINQ to JSON
  • JsonConverter

Objects

不属于下面列出的任何其他类别的.NET类型(即不是列表、字典、动态、实现ISerializable等)将被序列化为JSON对象。你还可以通过把JsonObjectAttribute放到类型上来强迫一个类型被序列化为JSON。

默认情况下,一个类型的属性会在opt-out模式下被序列化。这意味着,所有带有getter的公共字段和属性都会自动序列化为JSON,而不应该序列化的字段和属性则会通过在其上放置JsonIgnoreAttribute来进行选择。若要序列化私有成员,可以在私有字段和属性上放置JsonPropertyAttribute。

也可以使用opt-in模式来序列化类型。只有具有JsonPropertyAttribute或DataMemberAttribute的属性或字段将被序列化。对象的Opt-in模式是通过在类型上放置JsonObjectAttribute或DataContractAttribute来指定的。

最后,可以使用字段模式来序列化炻工。所有的字段,无论是公开的还是私有的,都被序列化,所有属性都被忽略。这可以通过利用JsonObjectAttribute在类型上设置MemberSerialization.Fields来指定,或者使用.NET SerializableAttribute并在DefaultContractResolver上把IgnoreSerializableAttribute设置为false来指定。

IEnumerable, Lists, and Arrays

.NET列表(类型继承自IEnumerable)以及.NET数组会被转换为JSON数组。因为JSON数组只支持值的范围,而不支持属性,所有声明在.NET集合上的任何额外的属性和字段都不会被序列化。在某些情形中,类型实例化了IEnumerable,但是不想要JSON数组,则可以在类型上放置JsonObjectAttribute,以迫使它被序列化为一个JSON对象。

JsonArrayAttribute上面有选项,用来自定义应用到集合项上的JsonConverter、类型名称处理和引用处理。

请注意,如果在序列化器上已经针对JSON数组启用了TypeNameHandling或PreserveReferencesHandling,则JSON数组将被包装入一个容纳对象。此对象将具有类型名称、引用属性以及一个$value属性,它具有集合的数据。

在序列化时,如果某个成员被类型化为接口 IList<T>,则它将被反序列化为List<T>。

你可以在此处进一步了解序列化集合:序列化集合

字典和哈希表

.NET字典(继承自IDictionary的类型)被转换为JSON对象。请注意,在序列化时,只有字典名称、值会被写到JSON对象中,在反序列化时,JSON对象上的属性将被添加到字典的名称值上。在序列化时,.NET字典上的额外的成员会被忽略。

当序列化一个字典时,字典的键被转换为字符串,用作JSON对象属性名称。可以自定义写作键的字符串,既可以通过针对键类型重写ToString(),也可以通过TypeConverter来实现。TypeConverter也支持在反序列化一个字典时,把自定义的字符串转换回去。

JsonDictionaryAttribute上面有选项,用来自定义应用到集合项上的JsonConverter,类型名称处理以及引用处理。

在反序列化时,如果一个成员被类型化为接口IDictionary<TKey, TValue>,则它将被反序列化为Dictionary<TKey, TValue>。

你可以在此处进一步了解序列化集合:序列化集合

未类型化的对象

在类上的.NET属性,如果没有指定类型(亦即,它们只是对象)也会如常序列化。当未类型化的属性被反序列化时,序列化器没有办法知道要创建哪种类型(除非启用了类型名称处理,而且JSON包含了类型名称)。

对于那些未类型化的属性,Json.NET序列化器将JSON读入LINQ to JSON对象,并把它们设置为属性。将针对JSON对象创建JObject;将针对JSON数组创建JArray,针针对基元JSON值创建JValue。

动态

.NET中有两种不同的动态用法(在.NET 4中引入)。第一种是.NET属性,带有动态的类型。动态属性行为像属性,被声明为对象:可以给它分配一些值,但是区别是可以在动态的属性上调用属性和方法,无需强制转换。在Json.NET中,动态属性被序列化、反序列化,与非类型化的对象完全一致:因为动态不是实际的类型,Json.NET会回退到将Json反序列化为LINQ to Json对象。

在.NET中动态的第二种用法是由实现 IDynamicMetaObjectProvider的类型来实现的。此接口让实现器创建动态对象,截断在一个对象上调用的属性和方法,并使用它们。ExpandoObject是动态对象的好例子。

动态对象会被序列化为JSON对象。针对DynamicMetaObject.GetDynamicMemberNames()返回的所有成员编写属性。动态对象的常规属性默认不会被序列化,但是可以被包含,只要在它上面放JsonPropertyAttribute。

在反序列化动态对象时,序列化器首先尝试在名称匹配的常规.NET成员上设置JSON属性值。如果找不到带有那个名称的.NET成员,则序列化器将在动态对象上调用SetMember。因为动态对象上的动态成员不存在类型信息,所以分配给他们的值将是LINQ to JSON对象。

ISerializable

实现ISerializable的类型,以及带有SerializableAttribute标记的类型会被序列化为JSON对象。在序列化时,只用到了返回自ISerializable.GetObjectData的值;类型上的成员会被忽略。在反序列化时,调用了带有SerializationInfo和StreamingContext的构造器,传递JSON对象的值。

在一些不需要这种行为的情形中,可在.NET类型上面放置JsonObjectAttribute,实现Iserializable强制它被序列化为一个常规JSON对象。

LINQ to JSON

当Json.NET序列化器遭遇到了LINQ to JSON类型时,LINQ to JSON类型(例如,JObject和JArray)会自动序列化和反序列化为和它们等价的JSON。

JsonConverter

JsonConvert完全重写了可被JsonConverter转换的值(亦即,对于那种类型,CanConvert返回true)的序列化。检查JsonSerializer是否可以转换值的测试优先于所有其他测试。

可以在很多地方定义并指定JsonConverters:在某个成员的某个特性上、在一个类的特性上,或者添加到JsonSerializer的转换器集合上。使用哪种JsonConvert的优先顺序,首先一个成员的特定上定义的JsonConverter,然后是一个类上定义的JsonConverter,最后是传给JsonSerializer的任何转换器。

 Note:
因为JsonConverter创建了一个新值,所以转换器不能与只读属性配合作用,因为没办法给这样的属性赋新值。请将属性更改为具有公共setter,或在属性上放置JsonPropertyAttribute或DataMemberAttribute。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值