339 lines
12 KiB
HTML
339 lines
12 KiB
HTML
|
<html>
|
||
|
<head>
|
||
|
<title>Serialization Guide</title>
|
||
|
<link href="styles.css" rel="stylesheet" type="text/css" />
|
||
|
<link href="custom.css" rel="stylesheet" type="text/css" />
|
||
|
<style type="text/css">
|
||
|
.style1
|
||
|
{
|
||
|
width: 100%;
|
||
|
}
|
||
|
</style>
|
||
|
</head>
|
||
|
<body>
|
||
|
<div id="control">
|
||
|
<span class="productTitle">Json.NET - Quick Starts & API Documentation</span><br />
|
||
|
<span class="topicTitle">Serialization Guide</span></div>
|
||
|
<div id="content">
|
||
|
<span style="color: DarkGray"></span>
|
||
|
<p>
|
||
|
The Json.NET serializer can serialize a wide variety of .NET objects. This guide
|
||
|
looks at how it works at a high level and in more detail.</p>
|
||
|
<h3>
|
||
|
Summary</h3>
|
||
|
<p>
|
||
|
At a high level, the Json.NET serializer will convert primitive .NET values into
|
||
|
primitive JSON values, .NET arrays and collections to JSON arrays and everything
|
||
|
else to JSON objects.</p>
|
||
|
<p>
|
||
|
Json.NET will throw an error if it encounters incorrect JSON when deserializing
|
||
|
a value. For example if the serializer encounters a JSON property with an array
|
||
|
of values and the type of matching .NET property is not a collection then an error
|
||
|
will be thrown, and vice-versa.
|
||
|
</p>
|
||
|
<h4>
|
||
|
<strong>Complex Types</strong></h4>
|
||
|
<table class="members">
|
||
|
<tbody>
|
||
|
<tr>
|
||
|
<th class="nameColumn">
|
||
|
.NET
|
||
|
</th>
|
||
|
<th class="descriptionColumn">
|
||
|
JSON
|
||
|
</th>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td>
|
||
|
<b>IList, IEnumerable, IList<T>, Array</b>
|
||
|
</td>
|
||
|
<td>
|
||
|
<div class="summary">
|
||
|
Array
|
||
|
</div>
|
||
|
<br>
|
||
|
</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td>
|
||
|
<b>IDictionary, IDictionary<TKey, TValue></b>
|
||
|
</td>
|
||
|
<td>
|
||
|
<div class="summary">
|
||
|
Object
|
||
|
</div>
|
||
|
<br>
|
||
|
</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td>
|
||
|
<b>Object (more detail below)</b>
|
||
|
</td>
|
||
|
<td>
|
||
|
<div class="summary">
|
||
|
Object
|
||
|
</div>
|
||
|
<br>
|
||
|
</td>
|
||
|
</tr>
|
||
|
</tbody>
|
||
|
</table>
|
||
|
<h4>
|
||
|
<strong>Primitive Types</strong></h4>
|
||
|
<table class="members">
|
||
|
<tbody>
|
||
|
<tr>
|
||
|
<th class="nameColumn">
|
||
|
.NET
|
||
|
</th>
|
||
|
<th class="descriptionColumn">
|
||
|
JSON
|
||
|
</th>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td>
|
||
|
<b>String</b>
|
||
|
</td>
|
||
|
<td>
|
||
|
<div class="summary">
|
||
|
String
|
||
|
</div>
|
||
|
<br>
|
||
|
</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td>
|
||
|
<b>Byte<br />
|
||
|
SByte<br />
|
||
|
UInt16<br />
|
||
|
Int16<br />
|
||
|
UInt32<br />
|
||
|
Int32<br />
|
||
|
UInt64<br />
|
||
|
Int64<br />
|
||
|
<br />
|
||
|
</b>
|
||
|
</td>
|
||
|
<td>
|
||
|
<div class="summary">
|
||
|
Integer
|
||
|
</div>
|
||
|
<br>
|
||
|
</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td>
|
||
|
<b>Float<br />
|
||
|
Double<br />
|
||
|
Decimal<br />
|
||
|
<br />
|
||
|
</b>
|
||
|
</td>
|
||
|
<td>
|
||
|
<div class="summary">
|
||
|
Float
|
||
|
</div>
|
||
|
<br>
|
||
|
</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td>
|
||
|
<b>Enum</b>
|
||
|
</td>
|
||
|
<td>
|
||
|
<div class="summary">
|
||
|
Integer (can be string with <a href="html/T_Newtonsoft_Json_Converters_StringEnumConverter.htm">
|
||
|
StringEnumConverter</a>)
|
||
|
</div>
|
||
|
<br>
|
||
|
</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td>
|
||
|
<b>DateTime</b>
|
||
|
</td>
|
||
|
<td>
|
||
|
<div class="summary">
|
||
|
String (<a href="DatesInJSON.html">Serializing Dates in JSON</a>)
|
||
|
</div>
|
||
|
<br>
|
||
|
</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td>
|
||
|
<b>Byte[]</b>
|
||
|
</td>
|
||
|
<td>
|
||
|
<div class="summary">
|
||
|
String (base 64 encoded)
|
||
|
</div>
|
||
|
<br>
|
||
|
</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td>
|
||
|
<b>Type</b>
|
||
|
</td>
|
||
|
<td>
|
||
|
<div class="summary">
|
||
|
String (type name)
|
||
|
</div>
|
||
|
<br>
|
||
|
</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td>
|
||
|
<b>Guid</b>
|
||
|
</td>
|
||
|
<td>
|
||
|
<div class="summary">
|
||
|
String
|
||
|
</div>
|
||
|
<br>
|
||
|
</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td>
|
||
|
<b><a href="http://msdn.microsoft.com/en-us/library/system.componentmodel.typeconverter.aspx"
|
||
|
target="_blank">TypeConverter</a> (convertible to String)</b>
|
||
|
</td>
|
||
|
<td>
|
||
|
<div class="summary">
|
||
|
String
|
||
|
</div>
|
||
|
<br>
|
||
|
</td>
|
||
|
</tr>
|
||
|
</tbody>
|
||
|
</table>
|
||
|
<h3>
|
||
|
Breakdown of Type Serialization</h3>
|
||
|
<h4>
|
||
|
<strong>Objects</strong></h4>
|
||
|
<p>
|
||
|
.NET types that don't fall into any other category listed below (i.e. aren't lists,
|
||
|
dictionaries, dynamic, implement ISerializable, etc) are serialized as JSON objects.</p>
|
||
|
<p>
|
||
|
By default types are serialized in opt-out mode. What that means is all public fields
|
||
|
and properties with getters are automatically serialized to JSON and members that
|
||
|
shouldn't be serialized are opted-out using the JsonIgnoreAttribute. To serialize
|
||
|
private members the JsonPropertyAttribute can be placed on private fields and properties
|
||
|
or the DefaultMembersSearchFlags can be changed on DefaultContractResolver to change
|
||
|
how members are serialized on all types.</p>
|
||
|
<p>
|
||
|
Types can also be serialized using opt-in mode. Only fields that have a JsonPropertyAttribute
|
||
|
or DataMemberAttribute on them will be serialized. Opt-in mode for an object is
|
||
|
specified using the JsonObjectAttribute on the class.
|
||
|
</p>
|
||
|
<h4>
|
||
|
<strong>IEnumerable, Lists and Arrays</strong></h4>
|
||
|
<p>
|
||
|
.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 JSON array is not wanted the JsonObjectAttribute can be placed
|
||
|
on a .NET type that implements IEnumerable to force the type to be serialized as
|
||
|
a JSON object instead.</p>
|
||
|
<p>
|
||
|
Note that if TypeNameHandling or PreserveReferencesHandling has been enabled for
|
||
|
JSON arrays on the serializer then JSON arrays are wrapped it a containing object.
|
||
|
The object will have the type name/reference properties and a $values property which
|
||
|
will have the collection data.</p>
|
||
|
<p>
|
||
|
When deserializing if a member is typed as the interface IList<T> then it
|
||
|
will be deserialized as a List<T>.</p>
|
||
|
<p>
|
||
|
Read more about serializing collections here: <a href="SerializingCollections.html">
|
||
|
Serializing Collections </a>
|
||
|
</p>
|
||
|
<h4>
|
||
|
<strong>Dictionarys and Hashtables</strong></h4>
|
||
|
<p>
|
||
|
.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.</p>
|
||
|
<p>
|
||
|
When deserializing if a member is typed as the interface IDictionary<TKey, TValue>
|
||
|
then it will be deserialized as a Dictionary<TKey, TValue>.</p>
|
||
|
<p>
|
||
|
Read more about serializing collections here: <a href="SerializingCollections.html">
|
||
|
Serializing Collections</a></p>
|
||
|
<h4>
|
||
|
<strong>Untyped Objects</strong></h4>
|
||
|
<p>
|
||
|
.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 to know what type to create (unless type name handling is enabled and
|
||
|
the JSON contains the type names).</p>
|
||
|
<p>
|
||
|
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 for primitive JSON values.
|
||
|
</p>
|
||
|
<h4>
|
||
|
<strong>Dynamic</strong></h4>
|
||
|
<p>
|
||
|
There are two different usages of dynamic (introduced in .NET 4) in .NET. The first
|
||
|
are .NET properties with a type of dynamic. Dynamic proeprties 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.
|
||
|
</p>
|
||
|
<p>
|
||
|
The second usage of dynamic in .NET are classes that implement <a href="http://msdn.microsoft.com/en-us/library/system.dynamic.idynamicmetaobjectprovider.aspx"
|
||
|
target="_blank">IDynamicMetaObjectProvider</a>. This interface lets the implementor
|
||
|
create dynamic objects that intercept the property and method calls on an object
|
||
|
and use them. <a href="http://msdn.microsoft.com/en-us/library/system.dynamic.expandoobject.aspx"
|
||
|
target="_blank">ExpandoObject</a> is a good example of a dynamic object.
|
||
|
</p>
|
||
|
<p>
|
||
|
Dynamic objects are serialized as JSON objects. A property is written for every
|
||
|
member name returned by <a href="http://msdn.microsoft.com/en-us/library/system.dynamic.dynamicmetaobject.getdynamicmembernames.aspx"
|
||
|
target="_blank">DynamicMetaObject.GetDynamicMemberNames</a>.</p>
|
||
|
<p>
|
||
|
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</p>
|
||
|
<h4>
|
||
|
<strong>ISerializable</strong></h4>
|
||
|
<p>
|
||
|
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.</p>
|
||
|
<p>
|
||
|
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.
|
||
|
</p>
|
||
|
<h4>
|
||
|
<strong>LINQ to JSON</strong></h4>
|
||
|
<p>
|
||
|
LINQ to JSON types (e.g. JObject, JArray) are automatically serialized and deserialized
|
||
|
to their equivalent JSON when encountered by the Json.NET serializer.
|
||
|
</p>
|
||
|
<h4>
|
||
|
<strong>JsonConverter</strong></h4>
|
||
|
<p>
|
||
|
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 a JsonSerializer takes precedence over
|
||
|
all other tests.</p>
|
||
|
<p>
|
||
|
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.</p>
|
||
|
<div id="footer">
|
||
|
</div>
|
||
|
</div>
|
||
|
</body>
|
||
|
</html>
|