a575963da9
Former-commit-id: da6be194a6b1221998fc28233f2503bd61dd9d14
138 lines
9.7 KiB
HTML
138 lines
9.7 KiB
HTML
<html>
|
|
|
|
<head>
|
|
<title>Serialization and Preserving Object References</title>
|
|
<link href="styles.css" rel="stylesheet" type="text/css" />
|
|
<link href="custom.css" rel="stylesheet" type="text/css" />
|
|
</head>
|
|
|
|
<body>
|
|
|
|
<div id="control">
|
|
<span class="productTitle">Json.NET - Quick Starts & API Documentation</span><br />
|
|
<span class="topicTitle">Serialization and Preserving Object References</span></div>
|
|
|
|
<div id="content">
|
|
<span style="color: DarkGray"> </span>
|
|
|
|
<p>By default Json.NET will serialize all objects it encounters by value. If a list
|
|
contains two Person references, and both references point to the same object
|
|
then the JsonSerializer will write out all the names and values for each
|
|
reference.</p>
|
|
|
|
<div class="overflowpanel"> <div class="code">
|
|
|
|
<div style="font-family: Courier New; font-size: 10pt; color: black;">
|
|
<pre style="margin: 0px;"><span style="color: #2b91af;">Person</span> p = <span style="color: blue;">new</span> <span style="color: #2b91af;">Person</span></pre>
|
|
<pre style="margin: 0px;"> {</pre>
|
|
<pre style="margin: 0px;"> BirthDate = <span style="color: blue;">new</span> <span style="color: #2b91af;">DateTime</span>(1980, 12, 23, 0, 0, 0, <span style="color: #2b91af;">DateTimeKind</span>.Utc),</pre>
|
|
<pre style="margin: 0px;"> LastModified = <span style="color: blue;">new</span> <span style="color: #2b91af;">DateTime</span>(2009, 2, 20, 12, 59, 21, <span style="color: #2b91af;">DateTimeKind</span>.Utc),</pre>
|
|
<pre style="margin: 0px;"> Name = <span style="color: #a31515;">"James"</span></pre>
|
|
<pre style="margin: 0px;"> };</pre>
|
|
<pre style="margin: 0px;"> </pre>
|
|
<pre style="margin: 0px;"><span style="color: #2b91af;">List</span><<span style="color: #2b91af;">Person</span>> people = <span style="color: blue;">new</span> <span style="color: #2b91af;">List</span><<span style="color: #2b91af;">Person</span>>();</pre>
|
|
<pre style="margin: 0px;">people.Add(p);</pre>
|
|
<pre style="margin: 0px;">people.Add(p);</pre>
|
|
<pre style="margin: 0px;"> </pre>
|
|
<pre style="margin: 0px;"><span style="color: blue;">string</span> json = <span style="color: #2b91af;">JsonConvert</span>.SerializeObject(people, <span style="color: #2b91af;">Formatting</span>.Indented);</pre>
|
|
<pre style="margin: 0px;"><span style="color: green;">//[</span></pre>
|
|
<pre style="margin: 0px;"><span style="color: green;">// {</span></pre>
|
|
<pre style="margin: 0px;"><span style="color: green;">// "Name": "James",</span></pre>
|
|
<pre style="margin: 0px;"><span style="color: green;">// "BirthDate": "\/Date(346377600000)\/",</span></pre>
|
|
<pre style="margin: 0px;"><span style="color: green;">// "LastModified": "\/Date(1235134761000)\/"</span></pre>
|
|
<pre style="margin: 0px;"><span style="color: green;">// },</span></pre>
|
|
<pre style="margin: 0px;"><span style="color: green;">// {</span></pre>
|
|
<pre style="margin: 0px;"><span style="color: green;">// "Name": "James",</span></pre>
|
|
<pre style="margin: 0px;"><span style="color: green;">// "BirthDate": "\/Date(346377600000)\/",</span></pre>
|
|
<pre style="margin: 0px;"><span style="color: green;">// "LastModified": "\/Date(1235134761000)\/"</span></pre>
|
|
<pre style="margin: 0px;"><span style="color: green;">// }</span></pre>
|
|
<pre style="margin: 0px;"><span style="color: green;">//]</span></pre>
|
|
</div>
|
|
</div></div>
|
|
<p>In most cases this is the desired result but in certain scenarios writing the second item in the list as a reference to the first is a better solution.
|
|
If the above JSON was deserialized now then the returned list would contain two
|
|
completely separate Person objects with the same values. Writing references by value will also cause problems on objects where a
|
|
circular reference occurs.</p>
|
|
|
|
<h3>PreserveReferencesHandling</h3>
|
|
<p>Settings PreserveReferencesHandling will track object references when serializing
|
|
and deserializing JSON.</p>
|
|
|
|
<div class="overflowpanel"> <div class="code">
|
|
<div style="font-family: Courier New; font-size: 10pt; color: black;">
|
|
<pre style="margin: 0px;"><span style="color: blue;">string</span> json = <span style="color: #2b91af;">JsonConvert</span>.SerializeObject(people, <span style="color: #2b91af;">Formatting</span>.Indented,</pre>
|
|
<pre style="margin: 0px;"> <span style="color: blue;">new</span> <span style="color: #2b91af;">JsonSerializerSettings</span> { PreserveReferencesHandling = <span style="color: #2b91af;">PreserveReferencesHandling</span>.Objects });</pre>
|
|
<pre style="margin: 0px;"><span style="color: green;">//[</span></pre>
|
|
<pre style="margin: 0px;"><span style="color: green;">// {</span></pre>
|
|
<pre style="margin: 0px;"><span style="color: green;">// "$id": "1",</span></pre>
|
|
<pre style="margin: 0px;"><span style="color: green;">// "Name": "James",</span></pre>
|
|
<pre style="margin: 0px;"><span style="color: green;">// "BirthDate": "\/Date(346377600000)\/",</span></pre>
|
|
<pre style="margin: 0px;"><span style="color: green;">// "LastModified": "\/Date(1235134761000)\/"</span></pre>
|
|
<pre style="margin: 0px;"><span style="color: green;">// },</span></pre>
|
|
<pre style="margin: 0px;"><span style="color: green;">// {</span></pre>
|
|
<pre style="margin: 0px;"><span style="color: green;">// "$ref": "1"</span></pre>
|
|
<pre style="margin: 0px;"><span style="color: green;">// }</span></pre>
|
|
<pre style="margin: 0px;"><span style="color: green;">//]</span></pre>
|
|
<pre style="margin: 0px;"> </pre>
|
|
<pre style="margin: 0px;"><span style="color: #2b91af;">List</span><<span style="color: #2b91af;">Person</span>> deserializedPeople = <span style="color: #2b91af;">JsonConvert</span>.DeserializeObject<<span style="color: #2b91af;">List</span><<span style="color: #2b91af;">Person</span>>>(json,</pre>
|
|
<pre style="margin: 0px;"> <span style="color: blue;">new</span> <span style="color: #2b91af;">JsonSerializerSettings</span> { PreserveReferencesHandling = <span style="color: #2b91af;">PreserveReferencesHandling</span>.Objects });</pre>
|
|
<pre style="margin: 0px;"> </pre>
|
|
<pre style="margin: 0px;"><span style="color: #2b91af;">Console</span>.WriteLine(deserializedPeople.Count);</pre>
|
|
<pre style="margin: 0px;"><span style="color: green;">// 2</span></pre>
|
|
<pre style="margin: 0px;"> </pre>
|
|
<pre style="margin: 0px;"><span style="color: #2b91af;">Person</span> p1 = deserializedPeople[0];</pre>
|
|
<pre style="margin: 0px;"><span style="color: #2b91af;">Person</span> p2 = deserializedPeople[1];</pre>
|
|
<pre style="margin: 0px;"> </pre>
|
|
<pre style="margin: 0px;"><span style="color: #2b91af;">Console</span>.WriteLine(p1.Name);</pre>
|
|
<pre style="margin: 0px;"><span style="color: green;">// James</span></pre>
|
|
<pre style="margin: 0px;"><span style="color: #2b91af;">Console</span>.WriteLine(p2.Name);</pre>
|
|
<pre style="margin: 0px;"><span style="color: green;">// James</span></pre>
|
|
<pre style="margin: 0px;"> </pre>
|
|
<pre style="margin: 0px;"><span style="color: blue;">bool</span> equal = <span style="color: #2b91af;">Object</span>.ReferenceEquals(p1, p2);</pre>
|
|
<pre style="margin: 0px;"><span style="color: green;">// true</span></pre>
|
|
</div>
|
|
</div></div>
|
|
|
|
<p>The first Person in the list is serizlied with the addition of an object Id. The
|
|
second Person in JSON is now only a reference to the first.</p>
|
|
<p>With PreserveReferencesHandling on now only one Person object is created on
|
|
deserialization and the list contains two references to it, mirroring what we
|
|
started with.</p>
|
|
|
|
<h3>IsReference on JsonObjectAttribute, JsonArrayAttribute and JsonPropertyAttribute</h3>
|
|
|
|
|
|
<p>The PreserveReferencesHandling setting on the JsonSerializer will change
|
|
how all objects are serialized and deserialized. For fine grain control over which
|
|
objects and members should be serialized as a reference there is the IsReference property on
|
|
the JsonObjectAttribute, JsonArrayAttribute and JsonPropertyAttribute.</p>
|
|
<p>Setting IsReference on JsonObjectAttribute or JsonArrayAttribute to true will
|
|
mean the JsonSerializer will always serialize the type the attribute is against
|
|
as a reference. Setting IsReference on the JsonPropertyAttribute to true will
|
|
serialize only that property as a reference.</p>
|
|
|
|
<div class="overflowpanel"> <div class="code">
|
|
|
|
<div style="font-family: Courier New; font-size: 10pt; color: black;">
|
|
<pre style="margin: 0px;">[<span style="color: #2b91af;">JsonObject</span>(IsReference = <span style="color: blue;">true</span>)]</pre>
|
|
<pre style="margin: 0px;"><span style="color: blue;">public</span> <span style="color: blue;">class</span> <span style="color: #2b91af;">EmployeeReference</span></pre>
|
|
<pre style="margin: 0px;">{</pre>
|
|
<pre style="margin: 0px;"> <span style="color: blue;">public</span> <span style="color: blue;">string</span> Name { <span style="color: blue;">get</span>; <span style="color: blue;">set</span>; }</pre>
|
|
<pre style="margin: 0px;"> <span style="color: blue;">public</span> <span style="color: #2b91af;">EmployeeReference</span> Manager { <span style="color: blue;">get</span>; <span style="color: blue;">set</span>; }</pre>
|
|
<pre style="margin: 0px;">}</pre>
|
|
</div>
|
|
|
|
</div></div>
|
|
<h3>IReferenceResolver</h3>
|
|
<p>To customize how references are generated and resolved the <a href="./html/T_Newtonsoft_Json_Serialization_IReferenceResolver.htm">IReferenceResolver</a> interface is available to inherit from and use with the JsonSerializer.</p>
|
|
|
|
<div id="footer">
|
|
|
|
|
|
|
|
</div>
|
|
</div>
|
|
|
|
</body>
|
|
|
|
</html> |