2
// Copyright (c) 2007 James Newton-King
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
13
// The above copyright notice and this permission notice shall be
14
// included in all copies or substantial portions of the Software.
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.
27
using System.Collections.Generic;
28
using System.Globalization;
30
using System.Runtime.Serialization.Formatters;
31
using Newtonsoft.Json.Converters;
32
using Newtonsoft.Json.Serialization;
33
using Newtonsoft.Json.Utilities;
34
using System.Runtime.Serialization;
35
using ErrorEventArgs=Newtonsoft.Json.Serialization.ErrorEventArgs;
37
namespace Newtonsoft.Json
40
/// Serializes and deserializes objects into and from the JSON format.
41
/// The <see cref="JsonSerializer"/> enables you to control how objects are encoded into JSON.
43
public class JsonSerializer
46
private TypeNameHandling _typeNameHandling;
47
private FormatterAssemblyStyle _typeNameAssemblyFormat;
48
private PreserveReferencesHandling _preserveReferencesHandling;
49
private ReferenceLoopHandling _referenceLoopHandling;
50
private MissingMemberHandling _missingMemberHandling;
51
private ObjectCreationHandling _objectCreationHandling;
52
private NullValueHandling _nullValueHandling;
53
private DefaultValueHandling _defaultValueHandling;
54
private ConstructorHandling _constructorHandling;
55
private JsonConverterCollection _converters;
56
private IContractResolver _contractResolver;
57
private IReferenceResolver _referenceResolver;
58
private ITraceWriter _traceWriter;
59
private SerializationBinder _binder;
60
private StreamingContext _context;
61
private Formatting? _formatting;
62
private DateFormatHandling? _dateFormatHandling;
63
private DateTimeZoneHandling? _dateTimeZoneHandling;
64
private DateParseHandling? _dateParseHandling;
65
private CultureInfo _culture;
66
private int? _maxDepth;
67
private bool _maxDepthSet;
68
private bool? _checkAdditionalContent;
71
/// Occurs when the <see cref="JsonSerializer"/> errors during serialization and deserialization.
73
public virtual event EventHandler<ErrorEventArgs> Error;
76
/// Gets or sets the <see cref="IReferenceResolver"/> used by the serializer when resolving references.
78
public virtual IReferenceResolver ReferenceResolver
82
if (_referenceResolver == null)
83
_referenceResolver = new DefaultReferenceResolver();
85
return _referenceResolver;
90
throw new ArgumentNullException("value", "Reference resolver cannot be null.");
92
_referenceResolver = value;
97
/// Gets or sets the <see cref="SerializationBinder"/> used by the serializer when resolving type names.
99
public virtual SerializationBinder Binder
108
throw new ArgumentNullException("value", "Serialization binder cannot be null.");
115
/// Gets or sets the <see cref="ITraceWriter"/> used by the serializer when writing trace messages.
117
/// <value>The trace writer.</value>
118
public virtual ITraceWriter TraceWriter
126
_traceWriter = value;
131
/// Gets or sets how type name writing and reading is handled by the serializer.
133
public virtual TypeNameHandling TypeNameHandling
135
get { return _typeNameHandling; }
138
if (value < TypeNameHandling.None || value > TypeNameHandling.Auto)
139
throw new ArgumentOutOfRangeException("value");
141
_typeNameHandling = value;
146
/// Gets or sets how a type name assembly is written and resolved by the serializer.
148
/// <value>The type name assembly format.</value>
149
public virtual FormatterAssemblyStyle TypeNameAssemblyFormat
151
get { return _typeNameAssemblyFormat; }
154
if (value < FormatterAssemblyStyle.Simple || value > FormatterAssemblyStyle.Full)
155
throw new ArgumentOutOfRangeException("value");
157
_typeNameAssemblyFormat = value;
162
/// Gets or sets how object references are preserved by the serializer.
164
public virtual PreserveReferencesHandling PreserveReferencesHandling
166
get { return _preserveReferencesHandling; }
169
if (value < PreserveReferencesHandling.None || value > PreserveReferencesHandling.All)
170
throw new ArgumentOutOfRangeException("value");
172
_preserveReferencesHandling = value;
177
/// Get or set how reference loops (e.g. a class referencing itself) is handled.
179
public virtual ReferenceLoopHandling ReferenceLoopHandling
181
get { return _referenceLoopHandling; }
184
if (value < ReferenceLoopHandling.Error || value > ReferenceLoopHandling.Serialize)
185
throw new ArgumentOutOfRangeException("value");
187
_referenceLoopHandling = value;
192
/// Get or set how missing members (e.g. JSON contains a property that isn't a member on the object) are handled during deserialization.
194
public virtual MissingMemberHandling MissingMemberHandling
196
get { return _missingMemberHandling; }
199
if (value < MissingMemberHandling.Ignore || value > MissingMemberHandling.Error)
200
throw new ArgumentOutOfRangeException("value");
202
_missingMemberHandling = value;
207
/// Get or set how null values are handled during serialization and deserialization.
209
public virtual NullValueHandling NullValueHandling
211
get { return _nullValueHandling; }
214
if (value < NullValueHandling.Include || value > NullValueHandling.Ignore)
215
throw new ArgumentOutOfRangeException("value");
217
_nullValueHandling = value;
222
/// Get or set how null default are handled during serialization and deserialization.
224
public virtual DefaultValueHandling DefaultValueHandling
226
get { return _defaultValueHandling; }
229
if (value < DefaultValueHandling.Include || value > DefaultValueHandling.IgnoreAndPopulate)
230
throw new ArgumentOutOfRangeException("value");
232
_defaultValueHandling = value;
237
/// Gets or sets how objects are created during deserialization.
239
/// <value>The object creation handling.</value>
240
public virtual ObjectCreationHandling ObjectCreationHandling
242
get { return _objectCreationHandling; }
245
if (value < ObjectCreationHandling.Auto || value > ObjectCreationHandling.Replace)
246
throw new ArgumentOutOfRangeException("value");
248
_objectCreationHandling = value;
253
/// Gets or sets how constructors are used during deserialization.
255
/// <value>The constructor handling.</value>
256
public virtual ConstructorHandling ConstructorHandling
258
get { return _constructorHandling; }
261
if (value < ConstructorHandling.Default || value > ConstructorHandling.AllowNonPublicDefaultConstructor)
262
throw new ArgumentOutOfRangeException("value");
264
_constructorHandling = value;
269
/// Gets a collection <see cref="JsonConverter"/> that will be used during serialization.
271
/// <value>Collection <see cref="JsonConverter"/> that will be used during serialization.</value>
272
public virtual JsonConverterCollection Converters
276
if (_converters == null)
277
_converters = new JsonConverterCollection();
284
/// Gets or sets the contract resolver used by the serializer when
285
/// serializing .NET objects to JSON and vice versa.
287
public virtual IContractResolver ContractResolver
291
if (_contractResolver == null)
292
_contractResolver = DefaultContractResolver.Instance;
294
return _contractResolver;
296
set { _contractResolver = value; }
300
/// Gets or sets the <see cref="StreamingContext"/> used by the serializer when invoking serialization callback methods.
302
/// <value>The context.</value>
303
public virtual StreamingContext Context
305
get { return _context; }
306
set { _context = value; }
310
/// Indicates how JSON text output is formatted.
312
public virtual Formatting Formatting
314
get { return _formatting ?? JsonSerializerSettings.DefaultFormatting; }
315
set { _formatting = value; }
319
/// Get or set how dates are written to JSON text.
321
public virtual DateFormatHandling DateFormatHandling
323
get { return _dateFormatHandling ?? JsonSerializerSettings.DefaultDateFormatHandling; }
324
set { _dateFormatHandling = value; }
328
/// Get or set how <see cref="DateTime"/> time zones are handling during serialization and deserialization.
330
public virtual DateTimeZoneHandling DateTimeZoneHandling
332
get { return _dateTimeZoneHandling ?? JsonSerializerSettings.DefaultDateTimeZoneHandling; }
333
set { _dateTimeZoneHandling = value; }
337
/// Get or set how date formatted strings, e.g. "\/Date(1198908717056)\/" and "2012-03-21T05:40Z", are parsed when reading JSON.
339
public virtual DateParseHandling DateParseHandling
341
get { return _dateParseHandling ?? JsonSerializerSettings.DefaultDateParseHandling; }
342
set { _dateParseHandling = value; }
346
/// Gets or sets the culture used when reading JSON. Defaults to <see cref="CultureInfo.InvariantCulture"/>.
348
public virtual CultureInfo Culture
350
get { return _culture ?? JsonSerializerSettings.DefaultCulture; }
351
set { _culture = value; }
355
/// Gets or sets the maximum depth allowed when reading JSON. Reading past this depth will throw a <see cref="JsonReaderException"/>.
357
public virtual int? MaxDepth
359
get { return _maxDepth; }
363
throw new ArgumentException("Value must be positive.", "value");
371
/// Gets a value indicating whether there will be a check for additional JSON content after deserializing an object.
374
/// <c>true</c> if there will be a check for additional JSON content after deserializing an object; otherwise, <c>false</c>.
376
public virtual bool CheckAdditionalContent
378
get { return _checkAdditionalContent ?? JsonSerializerSettings.DefaultCheckAdditionalContent; }
379
set { _checkAdditionalContent = value; }
382
internal bool IsCheckAdditionalContentSet()
384
return (_checkAdditionalContent != null);
390
/// Initializes a new instance of the <see cref="JsonSerializer"/> class.
392
public JsonSerializer()
394
_referenceLoopHandling = JsonSerializerSettings.DefaultReferenceLoopHandling;
395
_missingMemberHandling = JsonSerializerSettings.DefaultMissingMemberHandling;
396
_nullValueHandling = JsonSerializerSettings.DefaultNullValueHandling;
397
_defaultValueHandling = JsonSerializerSettings.DefaultDefaultValueHandling;
398
_objectCreationHandling = JsonSerializerSettings.DefaultObjectCreationHandling;
399
_preserveReferencesHandling = JsonSerializerSettings.DefaultPreserveReferencesHandling;
400
_constructorHandling = JsonSerializerSettings.DefaultConstructorHandling;
401
_typeNameHandling = JsonSerializerSettings.DefaultTypeNameHandling;
402
_context = JsonSerializerSettings.DefaultContext;
403
_binder = DefaultSerializationBinder.Instance;
407
/// Creates a new <see cref="JsonSerializer"/> instance using the specified <see cref="JsonSerializerSettings"/>.
409
/// <param name="settings">The settings to be applied to the <see cref="JsonSerializer"/>.</param>
410
/// <returns>A new <see cref="JsonSerializer"/> instance using the specified <see cref="JsonSerializerSettings"/>.</returns>
411
public static JsonSerializer Create(JsonSerializerSettings settings)
413
JsonSerializer jsonSerializer = new JsonSerializer();
415
if (settings != null)
417
if (!CollectionUtils.IsNullOrEmpty(settings.Converters))
418
jsonSerializer.Converters.AddRange(settings.Converters);
420
// serializer specific
421
jsonSerializer.TypeNameHandling = settings.TypeNameHandling;
422
jsonSerializer.TypeNameAssemblyFormat = settings.TypeNameAssemblyFormat;
423
jsonSerializer.PreserveReferencesHandling = settings.PreserveReferencesHandling;
424
jsonSerializer.ReferenceLoopHandling = settings.ReferenceLoopHandling;
425
jsonSerializer.MissingMemberHandling = settings.MissingMemberHandling;
426
jsonSerializer.ObjectCreationHandling = settings.ObjectCreationHandling;
427
jsonSerializer.NullValueHandling = settings.NullValueHandling;
428
jsonSerializer.DefaultValueHandling = settings.DefaultValueHandling;
429
jsonSerializer.ConstructorHandling = settings.ConstructorHandling;
430
jsonSerializer.Context = settings.Context;
431
jsonSerializer._checkAdditionalContent = settings._checkAdditionalContent;
433
// reader/writer specific
434
// unset values won't override reader/writer set values
435
jsonSerializer._formatting = settings._formatting;
436
jsonSerializer._dateFormatHandling = settings._dateFormatHandling;
437
jsonSerializer._dateTimeZoneHandling = settings._dateTimeZoneHandling;
438
jsonSerializer._dateParseHandling = settings._dateParseHandling;
439
jsonSerializer._culture = settings._culture;
440
jsonSerializer._maxDepth = settings._maxDepth;
441
jsonSerializer._maxDepthSet = settings._maxDepthSet;
443
if (settings.Error != null)
444
jsonSerializer.Error += settings.Error;
446
if (settings.ContractResolver != null)
447
jsonSerializer.ContractResolver = settings.ContractResolver;
448
if (settings.ReferenceResolver != null)
449
jsonSerializer.ReferenceResolver = settings.ReferenceResolver;
450
if (settings.TraceWriter != null)
451
jsonSerializer.TraceWriter = settings.TraceWriter;
452
if (settings.Binder != null)
453
jsonSerializer.Binder = settings.Binder;
456
return jsonSerializer;
460
/// Populates the JSON values onto the target object.
462
/// <param name="reader">The <see cref="TextReader"/> that contains the JSON structure to reader values from.</param>
463
/// <param name="target">The target object to populate values onto.</param>
464
public void Populate(TextReader reader, object target)
466
Populate(new JsonTextReader(reader), target);
470
/// Populates the JSON values onto the target object.
472
/// <param name="reader">The <see cref="JsonReader"/> that contains the JSON structure to reader values from.</param>
473
/// <param name="target">The target object to populate values onto.</param>
474
public void Populate(JsonReader reader, object target)
476
PopulateInternal(reader, target);
479
internal virtual void PopulateInternal(JsonReader reader, object target)
481
ValidationUtils.ArgumentNotNull(reader, "reader");
482
ValidationUtils.ArgumentNotNull(target, "target");
484
JsonSerializerInternalReader serializerReader = new JsonSerializerInternalReader(this);
485
serializerReader.Populate(reader, target);
489
/// Deserializes the Json structure contained by the specified <see cref="JsonReader"/>.
491
/// <param name="reader">The <see cref="JsonReader"/> that contains the JSON structure to deserialize.</param>
492
/// <returns>The <see cref="Object"/> being deserialized.</returns>
493
public object Deserialize(JsonReader reader)
495
return Deserialize(reader, null);
499
/// Deserializes the Json structure contained by the specified <see cref="StringReader"/>
500
/// into an instance of the specified type.
502
/// <param name="reader">The <see cref="TextReader"/> containing the object.</param>
503
/// <param name="objectType">The <see cref="Type"/> of object being deserialized.</param>
504
/// <returns>The instance of <paramref name="objectType"/> being deserialized.</returns>
505
public object Deserialize(TextReader reader, Type objectType)
507
return Deserialize(new JsonTextReader(reader), objectType);
511
/// Deserializes the Json structure contained by the specified <see cref="JsonReader"/>
512
/// into an instance of the specified type.
514
/// <param name="reader">The <see cref="JsonReader"/> containing the object.</param>
515
/// <typeparam name="T">The type of the object to deserialize.</typeparam>
516
/// <returns>The instance of <typeparamref name="T"/> being deserialized.</returns>
517
public T Deserialize<T>(JsonReader reader)
519
return (T)Deserialize(reader, typeof(T));
523
/// Deserializes the Json structure contained by the specified <see cref="JsonReader"/>
524
/// into an instance of the specified type.
526
/// <param name="reader">The <see cref="JsonReader"/> containing the object.</param>
527
/// <param name="objectType">The <see cref="Type"/> of object being deserialized.</param>
528
/// <returns>The instance of <paramref name="objectType"/> being deserialized.</returns>
529
public object Deserialize(JsonReader reader, Type objectType)
531
return DeserializeInternal(reader, objectType);
534
internal virtual object DeserializeInternal(JsonReader reader, Type objectType)
536
ValidationUtils.ArgumentNotNull(reader, "reader");
538
// set serialization options onto reader
539
CultureInfo previousCulture = null;
540
if (_culture != null && reader.Culture != _culture)
542
previousCulture = reader.Culture;
543
reader.Culture = _culture;
545
DateTimeZoneHandling? previousDateTimeZoneHandling = null;
546
if (_dateTimeZoneHandling != null && reader.DateTimeZoneHandling != _dateTimeZoneHandling)
548
previousDateTimeZoneHandling = reader.DateTimeZoneHandling;
549
reader.DateTimeZoneHandling = _dateTimeZoneHandling.Value;
551
DateParseHandling? previousDateParseHandling = null;
552
if (_dateParseHandling != null && reader.DateParseHandling != _dateParseHandling)
554
previousDateParseHandling = reader.DateParseHandling;
555
reader.DateParseHandling = _dateParseHandling.Value;
557
int? previousMaxDepth = null;
558
if (_maxDepthSet && reader.MaxDepth != _maxDepth)
560
previousMaxDepth = reader.MaxDepth;
561
reader.MaxDepth = _maxDepth;
564
JsonSerializerInternalReader serializerReader = new JsonSerializerInternalReader(this);
565
object value = serializerReader.Deserialize(reader, objectType, CheckAdditionalContent);
567
// reset reader back to previous options
568
if (previousCulture != null)
569
reader.Culture = previousCulture;
570
if (previousDateTimeZoneHandling != null)
571
reader.DateTimeZoneHandling = previousDateTimeZoneHandling.Value;
572
if (previousDateParseHandling != null)
573
reader.DateParseHandling = previousDateParseHandling.Value;
575
reader.MaxDepth = previousMaxDepth;
581
/// Serializes the specified <see cref="Object"/> and writes the Json structure
582
/// to a <c>Stream</c> using the specified <see cref="TextWriter"/>.
584
/// <param name="textWriter">The <see cref="TextWriter"/> used to write the Json structure.</param>
585
/// <param name="value">The <see cref="Object"/> to serialize.</param>
586
public void Serialize(TextWriter textWriter, object value)
588
Serialize(new JsonTextWriter(textWriter), value);
592
/// Serializes the specified <see cref="Object"/> and writes the Json structure
593
/// to a <c>Stream</c> using the specified <see cref="JsonWriter"/>.
595
/// <param name="jsonWriter">The <see cref="JsonWriter"/> used to write the Json structure.</param>
596
/// <param name="value">The <see cref="Object"/> to serialize.</param>
597
public void Serialize(JsonWriter jsonWriter, object value)
599
SerializeInternal(jsonWriter, value);
602
internal virtual void SerializeInternal(JsonWriter jsonWriter, object value)
604
ValidationUtils.ArgumentNotNull(jsonWriter, "jsonWriter");
606
// set serialization options onto writer
607
Formatting? previousFormatting = null;
608
if (_formatting != null && jsonWriter.Formatting != _formatting)
610
previousFormatting = jsonWriter.Formatting;
611
jsonWriter.Formatting = _formatting.Value;
613
DateFormatHandling? previousDateFormatHandling = null;
614
if (_dateFormatHandling != null && jsonWriter.DateFormatHandling != _dateFormatHandling)
616
previousDateFormatHandling = jsonWriter.DateFormatHandling;
617
jsonWriter.DateFormatHandling = _dateFormatHandling.Value;
619
DateTimeZoneHandling? previousDateTimeZoneHandling = null;
620
if (_dateTimeZoneHandling != null && jsonWriter.DateTimeZoneHandling != _dateTimeZoneHandling)
622
previousDateTimeZoneHandling = jsonWriter.DateTimeZoneHandling;
623
jsonWriter.DateTimeZoneHandling = _dateTimeZoneHandling.Value;
626
JsonSerializerInternalWriter serializerWriter = new JsonSerializerInternalWriter(this);
627
serializerWriter.Serialize(jsonWriter, value);
629
// reset writer back to previous options
630
if (previousFormatting != null)
631
jsonWriter.Formatting = previousFormatting.Value;
632
if (previousDateFormatHandling != null)
633
jsonWriter.DateFormatHandling = previousDateFormatHandling.Value;
634
if (previousDateTimeZoneHandling != null)
635
jsonWriter.DateTimeZoneHandling = previousDateTimeZoneHandling.Value;
638
internal JsonConverter GetMatchingConverter(Type type)
640
return GetMatchingConverter(_converters, type);
643
internal static JsonConverter GetMatchingConverter(IList<JsonConverter> converters, Type objectType)
646
ValidationUtils.ArgumentNotNull(objectType, "objectType");
649
if (converters != null)
651
for (int i = 0; i < converters.Count; i++)
653
JsonConverter converter = converters[i];
655
if (converter.CanConvert(objectType))
663
internal void OnError(ErrorEventArgs e)
665
EventHandler<ErrorEventArgs> error = Error;
b'\\ No newline at end of file'