Subversion Repository Public Repository

ChrisCompleteCodeTrunk

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
<?xml version="1.0" encoding="utf-8"?>
<topic id="SerializationGuide" revisionNumber="1">
  <developerConceptualDocument xmlns="http://ddue.schemas.microsoft.com/authoring/2003/5" xmlns:xlink="http://www.w3.org/1999/xlink">
    <!--
    <summary>
      <para>Optional summary abstract</para>
    </summary>
    -->
    <introduction>
      <para>The Json.NET serializer can serialize a wide variety of .NET objects. This guide looks at how it works, first at a high level and then in more detail.</para>
    </introduction>
    <!-- Add one or more top-level section elements.  These are collapsible.
         If using <autoOutline />, add an address attribute to identify it
         and specify a title so that it can be jumped to with a hyperlink. -->
    <section>
      <title>Summary</title>
      <content>
        <!-- Uncomment this to create a sub-section outline
        <autoOutline /> -->
        <para>At a high level, the Json.NET serializer will convert primitive .NET values into primitive JSON values,
        will convert .NET arrays and collections to JSON arrays, and will convert everything else to JSON objects.</para>
        <para>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.</para>
      </content>
    </section>
    <section>
      <title>Complex Types</title>
<content>
<table>
  <tableHeader>
    <row>
      <entry><para>.NET</para></entry>
      <entry><para>JSON</para></entry>
    </row>
  </tableHeader>
  <row>
    <entry><para><legacyBold>IList, IEnumerable, IList&lt;T&gt;, Array</legacyBold></para></entry>
    <entry><para>Array (properties on the collection will not be serialized)</para></entry>
  </row>
  <row>
    <entry><para><legacyBold>IDictionary, IDictionary&lt;TKey, TValue&gt;</legacyBold></para></entry>
    <entry><para>Object (dictionary name/values only, properties on the dictionary will not be serialized)</para></entry>
  </row>
  <row>
    <entry><para><legacyBold>Object (more detail below)</legacyBold></para></entry>
    <entry><para>Object</para></entry>
  </row>
</table>
</content>
    </section>
    <section>
      <title>Primitive Types</title>
<content>
<table>
  <tableHeader>
    <row>
      <entry><para>.NET</para></entry>
      <entry><para>JSON</para></entry>
    </row>
  </tableHeader>
  <row>
    <entry><para><legacyBold>String</legacyBold></para></entry>
    <entry><para>String</para></entry>
  </row>
  <row>
    <entry><para><legacyBold>Byte</legacyBold></para>
<para><legacyBold>SByte</legacyBold></para>
<para><legacyBold>UInt16</legacyBold></para>
<para><legacyBold>Int16</legacyBold></para>
<para><legacyBold>UInt32</legacyBold></para>
<para><legacyBold>Int32</legacyBold></para>
<para><legacyBold>UInt64</legacyBold></para>
<para><legacyBold>Int64</legacyBold></para></entry>
    <entry><para>Integer</para></entry>
  </row>
  <row>
    <entry>
    <para><legacyBold>Float</legacyBold></para>
    <para><legacyBold>Double</legacyBold></para>
    <para><legacyBold>Decimal</legacyBold></para>
    </entry>
    <entry><para>Float</para></entry>
  </row>
  <row>
    <entry>
    <para><legacyBold>Enum</legacyBold></para>
    </entry>
    <entry><para>Integer (can be the enum value name with <codeEntityReference>T:Newtonsoft.Json.Converters.StringEnumConverter</codeEntityReference>)</para></entry>
  </row>
  <row>
    <entry>
    <para><legacyBold>DateTime</legacyBold></para>
    </entry>
    <entry><para>String (<link xlink:href="DatesInJSON" />)</para></entry>
  </row>
  <row>
    <entry>
    <para><legacyBold>Byte[]</legacyBold></para>
    </entry>
    <entry><para>String (base 64 encoded)</para></entry>
  </row>
  <row>
    <entry>
    <para><legacyBold>Type</legacyBold></para>
    </entry>
    <entry><para>String (type name)</para></entry>
  </row>
  <row>
    <entry>
    <para><legacyBold>Guid</legacyBold></para>
    </entry>
    <entry><para>String</para></entry>
  </row>
  <row>
    <entry>
    <para><legacyBold><codeEntityReference>T:System.ComponentModel.TypeConverter</codeEntityReference> (convertible to String)</legacyBold></para>
    </entry>
    <entry><para>String</para></entry>
  </row>
</table>
</content>
    </section>

    <section>
      <title>Breakdown of Type Serialization</title>
      <content>
        <autoOutline />
		</content>
		<sections>
    <section address="Objects">
      <title>Objects</title>
      <content>
        <!-- Uncomment this to create a sub-section outline
        <autoOutline /> -->
        <para>.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. You can also force a type to be serialized as a JSON object by placing the
        JsonObjectAttribute on the type.</para>
        <para>By default a type's properties are serialized in opt-out mode. What that means is that all public fields and properties with
        getters are automatically serialized to JSON, and fields and properties that shouldn't be serialized are opted-out by placing
        JsonIgnoreAttribute on them. To serialize private members, the JsonPropertyAttribute can be placed on private fields and
        properties.</para>
        <para>Types can also be serialized using opt-in mode. Only properties and fields that have a JsonPropertyAttribute
        or DataMemberAttribute on them will be serialized. Opt-in mode for an object is specified by placing the JsonObjectAttribute
        or DataContractAttribute on the type.</para>
        <para>Finally, types can be serialized using a fields mode. All fields, both public and private, are serialized
        and properties are ignored. This can be specified by setting MemberSerialization.Fields on a type with the JsonObjectAttribute
        or by using the .NET <codeEntityReference>T:System.SerializableAttribute</codeEntityReference>
        and setting IgnoreSerializableAttribute on DefaultContractResolver to false.</para>
      </content>
    </section>   

    <section address="Lists">
      <title>IEnumerable, Lists, and Arrays</title>
      <content>
        <!-- Uncomment this to create a sub-section outline
        <autoOutline /> -->
        <para> .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.</para>
        <para>JsonArrayAttribute has options on it to customize the JsonConverter, type name handling, and reference handling
        that are applied to collection items.</para>
        <para>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.</para>
        <para>When deserializing, if a member is typed as the interface IList&lt;T&gt;, then it will be deserialized as a
        List&lt;T&gt;.</para>
        <para>You can read more about serializing collections here: <link xlink:href="SerializingCollections" /></para>
      </content>
    </section>   

    <section address="Dictionarys">
      <title>Dictionaries and Hashtables</title>
      <content>
        <!-- Uncomment this to create a sub-section outline
        <autoOutline /> -->
        <para>.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.</para>
        <para>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
        <codeEntityReference>M:System.Object.ToString</codeEntityReference> for the key type or by implementing a
        <codeEntityReference>T:System.ComponentModel.TypeConverter</codeEntityReference>. A TypeConverter will also
        support converting a custom string back again when deserializing a dictionary.</para>
        <para>JsonDictionaryAttribute has options on it to customize the JsonConverter, type name handling, and reference
        handling that are applied to collection items.</para>
        <para>When deserializing, if a member is typed as the interface IDictionary&lt;TKey, TValue&gt; then it will be
        deserialized as a Dictionary&lt;TKey, TValue&gt;.</para>
        <para>You can read more about serializing collections here: <link xlink:href="SerializingCollections" /></para>
      </content>
    </section>

    <section address="Untyped_Objects">
      <title>Untyped Objects</title>
      <content>
        <!-- Uncomment this to create a sub-section outline
        <autoOutline /> -->
        <para>.NET properties on a class that don't specify a type (i.e. they are just <codeInline>object</codeInline>) 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).</para>
        <para>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.</para>
      </content>
    </section>

    <section address="Dynamic">
      <title>Dynamic</title>
      <content>
        <!-- Uncomment this to create a sub-section outline
        <autoOutline /> -->
        <para>There are two different usages of <codeInline>dynamic</codeInline> (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.</para>
        <para>The second usage of dynamic in .NET are by the types that implement
        <codeEntityReference>T:System.Dynamic.IDynamicMetaObjectProvider</codeEntityReference>. This interface lets
        the implementer create dynamic objects that intercept the property and method calls on an object and use them.
        <codeEntityReference>T:System.Dynamic.ExpandoObject</codeEntityReference>
        is a good example of a dynamic object.</para>
        <para>Dynamic objects are serialized as JSON objects. A property is written for every member name returned by
        <codeEntityReference qualifyHint="true">M:System.Dynamic.DynamicMetaObject.GetDynamicMemberNames</codeEntityReference>.
        A dynamic object's normal properties aren't serialized by default but can be included by placing the
        JsonPropertyAttribute on them.
        </para>
        <para>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.</para>
      </content>
    </section>

    <section address="ISerializable">
      <title>ISerializable</title>
      <content>
        <!-- Uncomment this to create a sub-section outline
        <autoOutline /> -->
        <para>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.</para>
        <para>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.</para>
      </content>
    </section>

    <section address="LINQ">
      <title>LINQ to JSON</title>
      <content>
        <!-- Uncomment this to create a sub-section outline
        <autoOutline /> -->
        <para>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.</para>
      </content>
    </section>   

    <section address="JsonConverter">
      <title>JsonConverter</title>
      <content>
        <!-- Uncomment this to create a sub-section outline
        <autoOutline /> -->
        <para>Serialization of values that are convertible by a <codeEntityReference>T:Newtonsoft.Json.JsonConverter</codeEntityReference>
        (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.</para>
        <para>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.</para>
        
<alert class="note">
  <para>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.</para>
</alert>

      </content>
    </section>
    
      </sections>
    </section>
    <relatedTopics>
      <link xlink:href="SerializationSettings" />
      <link xlink:href="SerializationAttributes" />
      <link xlink:href="DatesInJSON" />

      <codeEntityReference>T:Newtonsoft.Json.JsonSerializer</codeEntityReference>
      <codeEntityReference>T:Newtonsoft.Json.JsonSerializerSettings</codeEntityReference>
    </relatedTopics>
  </developerConceptualDocument>
</topic>

Commits for ChrisCompleteCodeTrunk/M3Workflow/Libraries/Json90r1/Source/Doc/SerializationGuide.aml

Diff revisions: vs.
Revision Author Commited Message
1 BBDSCHRIS picture BBDSCHRIS Wed 22 Aug, 2018 20:08:03 +0000