Newtonsoft.Json Json.Net02.02序列化指引Serialization Guide
Posted liveyourlife
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Newtonsoft.Json Json.Net02.02序列化指引Serialization Guide相关的知识,希望对你有一定的参考价值。
Json.NET serializer可以序列化各种各样.NET对象。这个引到关注于它如何运作,首先以较高的视角来了解它,然后再详细了解它的细节。
概要
总体上说Json.NET serializer是这样转换的:
原始.NET值→原始JSON值
.NET数组、集合→JSON数组
其它→JSON对象
如果遇到不正确的JSON,则会报错。
复杂类型
.NET |
JSON |
---|---|
IList, IEnumerable, IList<T>, Array |
Array (properties on the collection will not be serialized) |
IDictionary, IDictionary<TKey, TValue> |
Object (dictionary name/values only, properties on the dictionary will not be serialized) |
Object (more detail below) |
Object |
基本类型
.NET |
JSON |
---|---|
String |
String |
Byte SByte UInt16 Int16 UInt32 Int32 UInt64 Int64 |
Integer |
Float Double Decimal |
Float |
Enum |
Integer (can be the enum value name with StringEnumConverter) |
DateTime |
String (Serializing Dates in JSON) |
Byte[] |
String (base 64 encoded) |
Type |
String (type name) |
Guid |
String |
TypeConverter (convertible to String) |
String |
序列化类型的分解
Objects:
(i.e. aren‘t lists, dictionaries, dynamic, implement ISerializable, etc.)这些.NET类型外的其它类型序列化时都会成为JSON对象。
可以使用JsonObjectAttribute注解,强制一个.NET类型序列化成JSON对象
默认一个类型的属性是使用opt-out模式进行序列化,会把所有公有字段以及有getter的公有属性自动序列化为JSON,除了有JsonIgnoreAttribute标注的字段和属性。可以使用JsonPropertyAttribute序列化私有成员。
可以设置成opt-in模式进行序列化。此时只有添加了JsonPropertyAttribute注解的字段或属性,才会进行序列化。
最后,还可以使用fields模式进行序列化。此时只有不论是公有还是私有的字段会被序列化,属性会被忽略。可以在一个类型上使用JsonObjectAttribute设置MemberSerialization.Fields或使用.NET SerializableAttribute设置IgnoreSerializableAttribute 或DefaultContractResolver为False.
IEnumerable, Lists, and Arrays:
.NET lists (types that inherit from IEnumerable) and .NET arrays are converted to JSON arrays. Because JSON arrays only support a range of values and not properties, any additional properties and fields declared on .NET collections are not serialized. In situations where a type implements IEnumerable but a JSON array is not wanted, then the JsonObjectAttribute can be placed on the type to force it to be serialized as a JSON object instead.
JsonArrayAttribute has options on it to customize the JsonConverter, type name handling, and reference handling that are applied to collection items.
Note that if TypeNameHandling or PreserveReferencesHandling has been enabled for JSON arrays on the serializer, then JSON arrays are wrapped in a containing object. The object will have the type name/reference properties and a $values property, which will have the collection data.
When deserializing, if a member is typed as the interface IList<T>, then it will be deserialized as a List<T>.
You can read more about serializing collections here: Serializing Collections
Dictionaries and Hashtables
.NET dictionaries (types that inherit from IDictionary) are converted to JSON objects. Note that only the dictionary name/values will be written to the JSON object when serializing, and properties on the JSON object will be added to the dictionary‘s name/values when deserializing. Additional members on the .NET dictionary are ignored during serialization.
When serializing a dictionary, the keys of the dictionary are converted to strings and used as the JSON object property names. The string written for a key can be customized by either overriding ToString() for the key type or by implementing a TypeConverter. A TypeConverter will also support converting a custom string back again when deserializing a dictionary.
JsonDictionaryAttribute has options on it to customize the JsonConverter, type name handling, and reference handling that are applied to collection items.
When deserializing, if a member is typed as the interface IDictionary<TKey, TValue> then it will be deserialized as a Dictionary<TKey, TValue>.
You can read more about serializing collections here: Serializing Collections
Untyped Objects
.NET properties on a class that don‘t specify a type (i.e. they are just object) are serialized as usual. When untyped properties are deserialized, the serializer has no way of knowing what type to create (unless type name handling is enabled and the JSON contains the type names).
For these untyped properties, the Json.NET serializer will read the JSON into LINQ to JSON objects and set them to the property. JObject will be created for JSON objects; JArray will be created for JSON arrays, and JValue will be created for primitive JSON values.
Dynamic
There are two different usages of dynamic (introduced in .NET 4) in .NET. The first are .NET properties with a type of dynamic. Dynamic properties behave like properties declared as object: any value can be assigned to it, but the difference being that properties and methods can be called on a dynamic property without casting. In Json.NET, dynamic properties are serialized and deserialized exactly the same as untyped objects: because dynamic isn‘t an actual type, Json.NET falls back to deserializing the JSON as LINQ to JSON objects.
The second usage of dynamic in .NET are by the types that implement IDynamicMetaObjectProvider. This interface lets the implementer create dynamic objects that intercept the property and method calls on an object and use them. ExpandoObject is a good example of a dynamic object.
Dynamic objects are serialized as JSON objects. A property is written for every member name returned by DynamicMetaObject.GetDynamicMemberNames(). A dynamic object‘s normal properties aren‘t serialized by default but can be included by placing the JsonPropertyAttribute on them.
When deserializing dynamic objects, the serializer first attempts to set JSON property values on a normal .NET member with the matching name. If no .NET member is found with the property name, then the serializer will call SetMember on the dynamic object. Because there is no type information for dynamic members on a dynamic object, the values assigned to them will be LINQ to JSON objects.
ISerializable
Types that implement ISerializable are serialized as JSON objects. When serializing, only the values returned from ISerializable.GetObjectData are used; members on the type are ignored. When deserializing, the constructor with a SerializationInfo and StreamingContext is called, passing the JSON object‘s values.
In situations where this behavior is not wanted, the JsonObjectAttribute can be placed on a .NET type that implements ISerializable to force it to be serialized as a normal JSON object.
LINQ to JSON
LINQ to JSON types (e.g. JObject and JArray) are automatically serialized and deserialized to their equivalent JSON when encountered by the Json.NET serializer.
JsonConverter
Serialization of values that are convertible by a JsonConverter (i.e. CanConvert returns true for its type) is completely overridden by the JsonConverter. The test to see whether a value can be converted by the JsonSerializer takes precedence over all other tests.
JsonConverters can be defined and specified in a number of places: in an attribute on a member, in an attribute on a class, and added to the JsonSerializer‘s converters collection. The priority of which JsonConverter is used is the JsonConverter defined by attribute on a member, then the JsonConverter defined by an attribute on a class, and finally any converters passed to the JsonSerializer.
Note Note
Because a JsonConverter creates a new value, a converter will not work with readonly properties because there is no way to assign the new value to the property. Either change the property to have a public setter or place a JsonPropertyAttribute or DataMemberAttribute on the property.
以上是关于Newtonsoft.Json Json.Net02.02序列化指引Serialization Guide的主要内容,如果未能解决你的问题,请参考以下文章
无法将类型“newtonsoft.json.linq.jtoken”隐式转换为 newt“newtonsoft.json.linq.jvalue”
从 JSON 检索项目时获取“无法将 Newtonsoft.Json.Linq.JObject 转换为 Newtonsoft.Json.Linq.JToken”