Json.NET
Code Coverage Statistics for Source File

Newtonsoft.Json\JsonSerializer.cs

Symbol Coverage: 88.34% (144 of 163)

Branch Coverage: 74.34% (84 of 113)

Cyclomatic Complexity Avg: 1.78 Max:7

Code Lines: 149


L V Source
1
#region License
2
// Copyright (c) 2007 James Newton-King
3
//
4
// Permission is hereby granted, free of charge, to any person
5
// obtaining a copy of this software and associated documentation
6
// files (the "Software"), to deal in the Software without
7
// restriction, including without limitation the rights to use,
8
// copy, modify, merge, publish, distribute, sublicense, and/or sell
9
// copies of the Software, and to permit persons to whom the
10
// Software is furnished to do so, subject to the following
11
// conditions:
12
//
13
// The above copyright notice and this permission notice shall be
14
// included in all copies or substantial portions of the Software.
15
//
16
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
18
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
20
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
21
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
23
// OTHER DEALINGS IN THE SOFTWARE.
24
#endregion
25

  
26
using System;
27
using System.Collections.Generic;
28
using System.IO;
29
using System.Runtime.Serialization.Formatters;
30
using Newtonsoft.Json.Converters;
31
using Newtonsoft.Json.Serialization;
32
using Newtonsoft.Json.Utilities;
33
using System.Runtime.Serialization;
34
using ErrorEventArgs=Newtonsoft.Json.Serialization.ErrorEventArgs;
35

  
36
namespace Newtonsoft.Json
37
{
38
  /// <summary>
39
  /// Serializes and deserializes objects into and from the JSON format.
40
  /// The <see cref="JsonSerializer"/> enables you to control how objects are encoded into JSON.
41
  /// </summary>
42
  public class JsonSerializer
43
  {
44
    #region Properties
45
    private TypeNameHandling _typeNameHandling;
46
    private FormatterAssemblyStyle _typeNameAssemblyFormat;
47
    private PreserveReferencesHandling _preserveReferencesHandling;
48
    private ReferenceLoopHandling _referenceLoopHandling;
49
    private MissingMemberHandling _missingMemberHandling;
50
    private ObjectCreationHandling _objectCreationHandling;
51
    private NullValueHandling _nullValueHandling;
52
    private DefaultValueHandling _defaultValueHandling;
53
    private ConstructorHandling _constructorHandling;
54
    private JsonConverterCollection _converters;
55
    private IContractResolver _contractResolver;
56
    private IReferenceResolver _referenceResolver;
57
    private SerializationBinder _binder;
58
    private StreamingContext _context;
59

  
60
    /// <summary>
61
    /// Occurs when the <see cref="JsonSerializer"/> errors during serialization and deserialization.
62
    /// </summary>
63
    public virtual event EventHandler<ErrorEventArgs> Error;
64

  
65
    /// <summary>
66
    /// Gets or sets the <see cref="IReferenceResolver"/> used by the serializer when resolving references.
67
    /// </summary>
68
    public virtual IReferenceResolver ReferenceResolver
69
    {
70
      get
71
      {
72
 128
        if (_referenceResolver == null)
73
 28
          _referenceResolver = new DefaultReferenceResolver();
74

  
75
 128
        return _referenceResolver;
76
 128
      }
77
      set
78
      {
79
 0
        if (value == null)
80
 0
          throw new ArgumentNullException("value", "Reference resolver cannot be null.");
81

  
82
 0
        _referenceResolver = value;
83
 0
      }
84
    }
85

  
86
    /// <summary>
87
    /// Gets or sets the <see cref="SerializationBinder"/> used by the serializer when resolving type names.
88
    /// </summary>
89
    public virtual SerializationBinder Binder
90
    {
91
      get
92
      {
93
 13
        return _binder;
94
 13
      }
95
      set
96
      {
97
 0
        if (value == null)
98
 0
          throw new ArgumentNullException("value", "Serialization binder cannot be null.");
99

  
100
 0
        _binder = value;
101
 0
      }
102
    }
103

  
104
    /// <summary>
105
    /// Gets or sets how type name writing and reading is handled by the serializer.
106
    /// </summary>
107
    public virtual TypeNameHandling TypeNameHandling
108
    {
109
 173595
      get { return _typeNameHandling; }
110
      set
111
      {
112
 172
        if (value < TypeNameHandling.None || value > TypeNameHandling.All)
113
 0
          throw new ArgumentOutOfRangeException("value");
114

  
115
 172
        _typeNameHandling = value;
116
 172
      }
117
    }
118

  
119
    /// <summary>
120
    /// Gets or sets how a type name assembly is written and resolved by the serializer.
121
    /// </summary>
122
    /// <value>The type name assembly format.</value>
123
    public virtual FormatterAssemblyStyle TypeNameAssemblyFormat
124
    {
125
 11
      get { return _typeNameAssemblyFormat; }
126
      set
127
      {
128
 172
        if (value < FormatterAssemblyStyle.Simple || value > FormatterAssemblyStyle.Full)
129
 0
          throw new ArgumentOutOfRangeException("value");
130

  
131
 172
        _typeNameAssemblyFormat = value;
132
 172
      }
133
    }
134

  
135
    /// <summary>
136
    /// Gets or sets how object references are preserved by the serializer.
137
    /// </summary>
138
    public virtual PreserveReferencesHandling PreserveReferencesHandling
139
    {
140
 331290
      get { return _preserveReferencesHandling; }
141
      set
142
      {
143
 172
        if (value < PreserveReferencesHandling.None || value > PreserveReferencesHandling.All)
144
 0
          throw new ArgumentOutOfRangeException("value");
145

  
146
 172
        _preserveReferencesHandling = value;
147
 172
      }
148
    }
149

  
150
    /// <summary>
151
    /// Get or set how reference loops (e.g. a class referencing itself) is handled.
152
    /// </summary>
153
    public virtual ReferenceLoopHandling ReferenceLoopHandling
154
    {
155
 6
      get { return _referenceLoopHandling; }
156
      set
157
      {
158
 10175
        if (value < ReferenceLoopHandling.Error || value > ReferenceLoopHandling.Serialize)
159
 0
          throw new ArgumentOutOfRangeException("value");
160

  
161
 10175
        _referenceLoopHandling = value;
162
 10175
      }
163
    }
164

  
165
    /// <summary>
166
    /// Get or set how missing members (e.g. JSON contains a property that isn't a member on the object) are handled during deserialization.
167
    /// </summary>
168
    public virtual MissingMemberHandling MissingMemberHandling
169
    {
170
 39
      get { return _missingMemberHandling; }
171
      set
172
      {
173
 10176
        if (value < MissingMemberHandling.Ignore || value > MissingMemberHandling.Error)
174
 0
          throw new ArgumentOutOfRangeException("value");
175

  
176
 10176
        _missingMemberHandling = value;
177
 10176
      }
178
    }
179

  
180
    /// <summary>
181
    /// Get or set how null values are handled during serialization and deserialization.
182
    /// </summary>
183
    public virtual NullValueHandling NullValueHandling
184
    {
185
 629414
      get { return _nullValueHandling; }
186
      set
187
      {
188
 174
        if (value < NullValueHandling.Include || value > NullValueHandling.Ignore)
189
 0
          throw new ArgumentOutOfRangeException("value");
190

  
191
 174
        _nullValueHandling = value;
192
 174
      }
193
    }
194

  
195
    /// <summary>
196
    /// Get or set how null default are handled during serialization and deserialization.
197
    /// </summary>
198
    public virtual DefaultValueHandling DefaultValueHandling
199
    {
200
 629399
      get { return _defaultValueHandling; }
201
      set
202
      {
203
 172
        if (value < DefaultValueHandling.Include || value > DefaultValueHandling.Ignore)
204
 0
          throw new ArgumentOutOfRangeException("value");
205

  
206
 172
        _defaultValueHandling = value;
207
 172
      }
208
    }
209

  
210
    /// <summary>
211
    /// Gets or sets how objects are created during deserialization.
212
    /// </summary>
213
    /// <value>The object creation handling.</value>
214
    public virtual ObjectCreationHandling ObjectCreationHandling
215
    {
216
 160615
      get { return _objectCreationHandling; }
217
      set
218
      {
219
 10175
        if (value < ObjectCreationHandling.Auto || value > ObjectCreationHandling.Replace)
220
 0
          throw new ArgumentOutOfRangeException("value");
221

  
222
 10175
        _objectCreationHandling = value;
223
 10175
      }
224
    }
225

  
226
    /// <summary>
227
    /// Gets or sets how constructors are used during deserialization.
228
    /// </summary>
229
    /// <value>The constructor handling.</value>
230
    public virtual ConstructorHandling ConstructorHandling
231
    {
232
 4
      get { return _constructorHandling; }
233
      set
234
      {
235
 172
        if (value < ConstructorHandling.Default || value > ConstructorHandling.AllowNonPublicDefaultConstructor)
236
 0
          throw new ArgumentOutOfRangeException("value");
237

  
238
 172
        _constructorHandling = value;
239
 172
      }
240
    }
241

  
242
    /// <summary>
243
    /// Gets a collection <see cref="JsonConverter"/> that will be used during serialization.
244
    /// </summary>
245
    /// <value>Collection <see cref="JsonConverter"/> that will be used during serialization.</value>
246
    public virtual JsonConverterCollection Converters
247
    {
248
      get
249
      {
250
 146
        if (_converters == null)
251
 134
          _converters = new JsonConverterCollection();
252

  
253
 146
        return _converters;
254
 146
      }
255
    }
256

  
257
    /// <summary>
258
    /// Gets or sets the contract resolver used by the serializer when
259
    /// serializing .NET objects to JSON and vice versa.
260
    /// </summary>
261
    public virtual IContractResolver ContractResolver
262
    {
263
      get
264
      {
265
 793762
        if (_contractResolver == null)
266
 26277
          _contractResolver = DefaultContractResolver.Instance;
267

  
268
 793762
        return _contractResolver;
269
 793762
      }
270
 9
      set { _contractResolver = value; }
271
    }
272

  
273
    /// <summary>
274
    /// Gets or sets the <see cref="StreamingContext"/> used by the serializer when invoking serialization callback methods.
275
    /// </summary>
276
    /// <value>The context.</value>
277
    public virtual StreamingContext Context
278
    {
279
 487941
      get { return _context; }
280
 172
      set { _context = value; }
281
    }
282
    #endregion
283

  
284
    /// <summary>
285
    /// Initializes a new instance of the <see cref="JsonSerializer"/> class.
286
    /// </summary>
287
 26470
    public JsonSerializer()
288
    {
289
 26470
      _referenceLoopHandling = JsonSerializerSettings.DefaultReferenceLoopHandling;
290
 26470
      _missingMemberHandling = JsonSerializerSettings.DefaultMissingMemberHandling;
291
 26470
      _nullValueHandling = JsonSerializerSettings.DefaultNullValueHandling;
292
 26470
      _defaultValueHandling = JsonSerializerSettings.DefaultDefaultValueHandling;
293
 26470
      _objectCreationHandling = JsonSerializerSettings.DefaultObjectCreationHandling;
294
 26470
      _preserveReferencesHandling = JsonSerializerSettings.DefaultPreserveReferencesHandling;
295
 26470
      _constructorHandling = JsonSerializerSettings.DefaultConstructorHandling;
296
 26470
      _typeNameHandling = JsonSerializerSettings.DefaultTypeNameHandling;
297
 26470
      _context = JsonSerializerSettings.DefaultContext;
298

  
299
 26470
      _binder = DefaultSerializationBinder.Instance;
300
 26470
    }
301

  
302
    /// <summary>
303
    /// Creates a new <see cref="JsonSerializer"/> instance using the specified <see cref="JsonSerializerSettings"/>.
304
    /// </summary>
305
    /// <param name="settings">The settings to be applied to the <see cref="JsonSerializer"/>.</param>
306
    /// <returns>A new <see cref="JsonSerializer"/> instance using the specified <see cref="JsonSerializerSettings"/>.</returns>
307
    public static JsonSerializer Create(JsonSerializerSettings settings)
308
    {
309
 5841
      JsonSerializer jsonSerializer = new JsonSerializer();
310

  
311
 5841
      if (settings != null)
312
      {
313
 172
        if (!CollectionUtils.IsNullOrEmpty(settings.Converters))
314
 120
          jsonSerializer.Converters.AddRange(settings.Converters);
315

  
316
 172
        jsonSerializer.TypeNameHandling = settings.TypeNameHandling;
317
 172
        jsonSerializer.TypeNameAssemblyFormat = settings.TypeNameAssemblyFormat;
318
 172
        jsonSerializer.PreserveReferencesHandling = settings.PreserveReferencesHandling;
319
 172
        jsonSerializer.ReferenceLoopHandling = settings.ReferenceLoopHandling;
320
 172
        jsonSerializer.MissingMemberHandling = settings.MissingMemberHandling;
321
 172
        jsonSerializer.ObjectCreationHandling = settings.ObjectCreationHandling;
322
 172
        jsonSerializer.NullValueHandling = settings.NullValueHandling;
323
 172
        jsonSerializer.DefaultValueHandling = settings.DefaultValueHandling;
324
 172
        jsonSerializer.ConstructorHandling = settings.ConstructorHandling;
325
 172
        jsonSerializer.Context = settings.Context;
326

  
327
 172
        if (settings.Error != null)
328
 2
          jsonSerializer.Error += settings.Error;
329

  
330
 172
        if (settings.ContractResolver != null)
331
 7
          jsonSerializer.ContractResolver = settings.ContractResolver;
332
 172
        if (settings.ReferenceResolver != null)
333
 0
          jsonSerializer.ReferenceResolver = settings.ReferenceResolver;
334
 172
        if (settings.Binder != null)
335
 0
          jsonSerializer.Binder = settings.Binder;
336
      }
337

  
338
 5841
      return jsonSerializer;
339
 5841
    }
340

  
341
    /// <summary>
342
    /// Populates the JSON values onto the target object.
343
    /// </summary>
344
    /// <param name="reader">The <see cref="TextReader"/> that contains the JSON structure to reader values from.</param>
345
    /// <param name="target">The target object to populate values onto.</param>
346
    public void Populate(TextReader reader, object target)
347
    {
348
 2
      Populate(new JsonTextReader(reader), target);
349
 2
    }
350

  
351
    /// <summary>
352
    /// Populates the JSON values onto the target object.
353
    /// </summary>
354
    /// <param name="reader">The <see cref="JsonReader"/> that contains the JSON structure to reader values from.</param>
355
    /// <param name="target">The target object to populate values onto.</param>
356
    public void Populate(JsonReader reader, object target)
357
    {
358
 15
      PopulateInternal(reader, target);
359
 12
    }
360

  
361
    internal virtual void PopulateInternal(JsonReader reader, object target)
362
    {
363
 9
      ValidationUtils.ArgumentNotNull(reader, "reader");
364
 9
      ValidationUtils.ArgumentNotNull(target, "target");
365

  
366
 9
      JsonSerializerInternalReader serializerReader = new JsonSerializerInternalReader(this);
367
 9
      serializerReader.Populate(reader, target);
368
 6
    }
369

  
370
    /// <summary>
371
    /// Deserializes the Json structure contained by the specified <see cref="JsonReader"/>.
372
    /// </summary>
373
    /// <param name="reader">The <see cref="JsonReader"/> that contains the JSON structure to deserialize.</param>
374
    /// <returns>The <see cref="Object"/> being deserialized.</returns>
375
    public object Deserialize(JsonReader reader)
376
    {
377
 1
      return Deserialize(reader, null);
378
 1
    }
379

  
380
    /// <summary>
381
    /// Deserializes the Json structure contained by the specified <see cref="StringReader"/>
382
    /// into an instance of the specified type.
383
    /// </summary>
384
    /// <param name="reader">The <see cref="TextReader"/> containing the object.</param>
385
    /// <param name="objectType">The <see cref="Type"/> of object being deserialized.</param>
386
    /// <returns>The instance of <paramref name="objectType"/> being deserialized.</returns>
387
    public object Deserialize(TextReader reader, Type objectType)
388
    {
389
 5004
      return Deserialize(new JsonTextReader(reader), objectType);
390
 5003
    }
391

  
392
    /// <summary>
393
    /// Deserializes the Json structure contained by the specified <see cref="JsonReader"/>
394
    /// into an instance of the specified type.
395
    /// </summary>
396
    /// <param name="reader">The <see cref="JsonReader"/> containing the object.</param>
397
    /// <typeparam name="T">The type of the object to deserialize.</typeparam>
398
    /// <returns>The instance of <typeparamref name="T"/> being deserialized.</returns>
399
    public T Deserialize<T>(JsonReader reader)
400
    {
401
 6
      return (T)Deserialize(reader, typeof(T));
402
 6
    }
403

  
404
    /// <summary>
405
    /// Deserializes the Json structure contained by the specified <see cref="JsonReader"/>
406
    /// into an instance of the specified type.
407
    /// </summary>
408
    /// <param name="reader">The <see cref="JsonReader"/> containing the object.</param>
409
    /// <param name="objectType">The <see cref="Type"/> of object being deserialized.</param>
410
    /// <returns>The instance of <paramref name="objectType"/> being deserialized.</returns>
411
    public object Deserialize(JsonReader reader, Type objectType)
412
    {
413
 10245
      return DeserializeInternal(reader, objectType);
414
 10216
    }
415

  
416
    internal virtual object DeserializeInternal(JsonReader reader, Type objectType)
417
    {
418
 10225
      ValidationUtils.ArgumentNotNull(reader, "reader");
419

  
420
 10225
      JsonSerializerInternalReader serializerReader = new JsonSerializerInternalReader(this);
421
 10225
      return serializerReader.Deserialize(reader, objectType);
422
 10196
    }
423

  
424
    /// <summary>
425
    /// Serializes the specified <see cref="Object"/> and writes the Json structure
426
    /// to a <c>Stream</c> using the specified <see cref="TextWriter"/>. 
427
    /// </summary>
428
    /// <param name="textWriter">The <see cref="TextWriter"/> used to write the Json structure.</param>
429
    /// <param name="value">The <see cref="Object"/> to serialize.</param>
430
    public void Serialize(TextWriter textWriter, object value)
431
    {
432
 3
      Serialize(new JsonTextWriter(textWriter), value);
433
 3
    }
434

  
435
    /// <summary>
436
    /// Serializes the specified <see cref="Object"/> and writes the Json structure
437
    /// to a <c>Stream</c> using the specified <see cref="JsonWriter"/>. 
438
    /// </summary>
439
    /// <param name="jsonWriter">The <see cref="JsonWriter"/> used to write the Json structure.</param>
440
    /// <param name="value">The <see cref="Object"/> to serialize.</param>
441
    public void Serialize(JsonWriter jsonWriter, object value)
442
    {
443
 16113
      SerializeInternal(jsonWriter, value);
444
 16107
    }
445

  
446
    internal virtual void SerializeInternal(JsonWriter jsonWriter, object value)
447
    {
448
 16074
      ValidationUtils.ArgumentNotNull(jsonWriter, "jsonWriter");
449

  
450
 16074
      JsonSerializerInternalWriter serializerWriter = new JsonSerializerInternalWriter(this);
451
 16074
      serializerWriter.Serialize(jsonWriter, value);
452
 16068
    }
453

  
454
    internal JsonConverter GetMatchingConverter(Type type)
455
    {
456
 793688
      return GetMatchingConverter(_converters, type);
457
 793688
    }
458

  
459
    internal static JsonConverter GetMatchingConverter(IList<JsonConverter> converters, Type objectType)
460
    {
461
 794221
      ValidationUtils.ArgumentNotNull(objectType, "objectType");
462

  
463
 794221
      if (converters != null)
464
      {
465
 916
        for (int i = 0; i < converters.Count; i++)
466
        {
467
 2503
          JsonConverter converter = converters[i];
468

  
469
 2503
          if (converter.CanConvert(objectType))
470
 207
            return converter;
471
        }
472
      }
473

  
474
 794014
      return null;
475
 794221
    }
476

  
477
    internal void OnError(ErrorEventArgs e)
478
    {
479
 21
      EventHandler<ErrorEventArgs> error = Error;
480
 21
      if (error != null)
481
 5
        error(this, e);
482
 21
    }
483
  }
484
}