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;
28
using System.Collections.Generic;
29
using System.ComponentModel;
30
#if !(NET35 || NET20 || WINDOWS_PHONE || PORTABLE)
33
using System.Diagnostics;
34
using System.Globalization;
35
using System.Security;
36
using Newtonsoft.Json.Linq;
37
using Newtonsoft.Json.Utilities;
38
using System.Runtime.Serialization;
40
using Newtonsoft.Json.Utilities.LinqBridge;
45
namespace Newtonsoft.Json.Serialization
47
internal class JsonSerializerInternalWriter : JsonSerializerInternalBase
49
private readonly List<object> _serializeStack = new List<object>();
50
private JsonSerializerProxy _internalSerializer;
52
public JsonSerializerInternalWriter(JsonSerializer serializer)
57
public void Serialize(JsonWriter jsonWriter, object value)
59
if (jsonWriter == null)
60
throw new ArgumentNullException("jsonWriter");
62
SerializeValue(jsonWriter, value, GetContractSafe(value), null, null, null);
65
private JsonSerializerProxy GetInternalSerializer()
67
if (_internalSerializer == null)
68
_internalSerializer = new JsonSerializerProxy(this);
70
return _internalSerializer;
73
private JsonContract GetContractSafe(object value)
78
return Serializer.ContractResolver.ResolveContract(value.GetType());
81
private void SerializePrimitive(JsonWriter writer, object value, JsonPrimitiveContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerProperty)
83
if (contract.UnderlyingType == typeof (byte[]))
85
bool includeTypeDetails = ShouldWriteType(TypeNameHandling.Objects, contract, member, containerContract, containerProperty);
86
if (includeTypeDetails)
88
writer.WriteStartObject();
89
WriteTypeProperty(writer, contract.CreatedType);
90
writer.WritePropertyName(JsonTypeReflector.ValuePropertyName);
91
writer.WriteValue(value);
92
writer.WriteEndObject();
97
writer.WriteValue(value);
100
private void SerializeValue(JsonWriter writer, object value, JsonContract valueContract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerProperty)
108
JsonConverter converter;
109
if ((((converter = (member != null) ? member.Converter : null) != null)
110
|| ((converter = (containerProperty != null) ? containerProperty.ItemConverter : null) != null)
111
|| ((converter = (containerContract != null) ? containerContract.ItemConverter : null) != null)
112
|| ((converter = valueContract.Converter) != null)
113
|| ((converter = Serializer.GetMatchingConverter(valueContract.UnderlyingType)) != null)
114
|| ((converter = valueContract.InternalConverter) != null))
115
&& converter.CanWrite)
117
SerializeConvertable(writer, converter, value, valueContract, containerContract, containerProperty);
121
switch (valueContract.ContractType)
123
case JsonContractType.Object:
124
SerializeObject(writer, value, (JsonObjectContract)valueContract, member, containerContract, containerProperty);
126
case JsonContractType.Array:
127
JsonArrayContract arrayContract = (JsonArrayContract) valueContract;
128
if (!arrayContract.IsMultidimensionalArray)
129
SerializeList(writer, arrayContract.CreateWrapper(value), arrayContract, member, containerContract, containerProperty);
131
SerializeMultidimensionalArray(writer, (Array)value, arrayContract, member, containerContract, containerProperty);
133
case JsonContractType.Primitive:
134
SerializePrimitive(writer, value, (JsonPrimitiveContract)valueContract, member, containerContract, containerProperty);
136
case JsonContractType.String:
137
SerializeString(writer, value, (JsonStringContract)valueContract);
139
case JsonContractType.Dictionary:
140
JsonDictionaryContract dictionaryContract = (JsonDictionaryContract) valueContract;
141
SerializeDictionary(writer, dictionaryContract.CreateWrapper(value), dictionaryContract, member, containerContract, containerProperty);
143
#if !(NET35 || NET20 || WINDOWS_PHONE || PORTABLE)
144
case JsonContractType.Dynamic:
145
SerializeDynamic(writer, (IDynamicMetaObjectProvider)value, (JsonDynamicContract)valueContract, member, containerContract, containerProperty);
148
#if !(SILVERLIGHT || NETFX_CORE || PORTABLE)
149
case JsonContractType.Serializable:
150
SerializeISerializable(writer, (ISerializable)value, (JsonISerializableContract)valueContract, member, containerContract, containerProperty);
153
case JsonContractType.Linq:
154
((JToken) value).WriteTo(writer, (Serializer.Converters != null) ? Serializer.Converters.ToArray() : null);
159
private bool? ResolveIsReference(JsonContract contract, JsonProperty property, JsonContainerContract collectionContract, JsonProperty containerProperty)
161
bool? isReference = null;
163
// value could be coming from a dictionary or array and not have a property
164
if (property != null)
165
isReference = property.IsReference;
167
if (isReference == null && containerProperty != null)
168
isReference = containerProperty.ItemIsReference;
170
if (isReference == null && collectionContract != null)
171
isReference = collectionContract.ItemIsReference;
173
if (isReference == null)
174
isReference = contract.IsReference;
179
private bool ShouldWriteReference(object value, JsonProperty property, JsonContract valueContract, JsonContainerContract collectionContract, JsonProperty containerProperty)
183
if (valueContract.ContractType == JsonContractType.Primitive || valueContract.ContractType == JsonContractType.String)
186
bool? isReference = ResolveIsReference(valueContract, property, collectionContract, containerProperty);
188
if (isReference == null)
190
if (valueContract.ContractType == JsonContractType.Array)
191
isReference = HasFlag(Serializer.PreserveReferencesHandling, PreserveReferencesHandling.Arrays);
193
isReference = HasFlag(Serializer.PreserveReferencesHandling, PreserveReferencesHandling.Objects);
196
if (!isReference.Value)
199
return Serializer.ReferenceResolver.IsReferenced(this, value);
202
private bool ShouldWriteProperty(object memberValue, JsonProperty property)
204
if (property.NullValueHandling.GetValueOrDefault(Serializer.NullValueHandling) == NullValueHandling.Ignore &&
208
if (HasFlag(property.DefaultValueHandling.GetValueOrDefault(Serializer.DefaultValueHandling), DefaultValueHandling.Ignore)
209
&& MiscellaneousUtils.ValueEquals(memberValue, property.GetResolvedDefaultValue()))
215
private bool CheckForCircularReference(JsonWriter writer, object value, JsonProperty property, JsonContract contract, JsonContainerContract containerContract, JsonProperty containerProperty)
217
if (value == null || contract.ContractType == JsonContractType.Primitive || contract.ContractType == JsonContractType.String)
220
ReferenceLoopHandling? referenceLoopHandling = null;
222
if (property != null)
223
referenceLoopHandling = property.ReferenceLoopHandling;
225
if (referenceLoopHandling == null && containerProperty != null)
226
referenceLoopHandling = containerProperty.ItemReferenceLoopHandling;
228
if (referenceLoopHandling == null && containerContract != null)
229
referenceLoopHandling = containerContract.ItemReferenceLoopHandling;
231
if (_serializeStack.IndexOf(value) != -1)
233
string message = "Self referencing loop detected";
234
if (property != null)
235
message += " for property '{0}'".FormatWith(CultureInfo.InvariantCulture, property.PropertyName);
236
message += " with type '{0}'.".FormatWith(CultureInfo.InvariantCulture, value.GetType());
238
switch (referenceLoopHandling.GetValueOrDefault(Serializer.ReferenceLoopHandling))
240
case ReferenceLoopHandling.Error:
241
throw JsonSerializationException.Create(null, writer.ContainerPath, message, null);
242
case ReferenceLoopHandling.Ignore:
243
if (TraceWriter != null && TraceWriter.LevelFilter >= TraceLevel.Verbose)
244
TraceWriter.Trace(TraceLevel.Verbose, JsonPosition.FormatMessage(null, writer.Path, message + ". Skipping serializing self referenced value."), null);
247
case ReferenceLoopHandling.Serialize:
248
if (TraceWriter != null && TraceWriter.LevelFilter >= TraceLevel.Verbose)
249
TraceWriter.Trace(TraceLevel.Verbose, JsonPosition.FormatMessage(null, writer.Path, message + ". Serializing self referenced value."), null);
258
private void WriteReference(JsonWriter writer, object value)
260
string reference = GetReference(writer, value);
262
if (TraceWriter != null && TraceWriter.LevelFilter >= TraceLevel.Info)
263
TraceWriter.Trace(TraceLevel.Info, JsonPosition.FormatMessage(null, writer.Path, "Writing object reference to Id '{0}' for {1}.".FormatWith(CultureInfo.InvariantCulture, reference, value.GetType())), null);
265
writer.WriteStartObject();
266
writer.WritePropertyName(JsonTypeReflector.RefPropertyName);
267
writer.WriteValue(reference);
268
writer.WriteEndObject();
271
private string GetReference(JsonWriter writer, object value)
275
string reference = Serializer.ReferenceResolver.GetReference(this, value);
281
throw JsonSerializationException.Create(null, writer.ContainerPath, "Error writing object reference for '{0}'.".FormatWith(CultureInfo.InvariantCulture, value.GetType()), ex);
285
internal static bool TryConvertToString(object value, Type type, out string s)
287
#if !(PocketPC || NETFX_CORE || PORTABLE)
288
TypeConverter converter = ConvertUtils.GetConverter(type);
290
// use the objectType's TypeConverter if it has one and can convert to a string
291
if (converter != null
293
&& !(converter is ComponentConverter)
295
&& converter.GetType() != typeof(TypeConverter))
297
if (converter.CanConvertTo(typeof(string)))
300
s = converter.ConvertToInvariantString(value);
302
s = converter.ConvertToString(value);
310
#if SILVERLIGHT || PocketPC || NETFX_CORE
311
if (value is Guid || value is Uri || value is TimeSpan)
313
s = value.ToString();
320
s = ((Type)value).AssemblyQualifiedName;
328
private void SerializeString(JsonWriter writer, object value, JsonStringContract contract)
330
OnSerializing(writer, contract, value);
333
TryConvertToString(value, contract.UnderlyingType, out s);
334
writer.WriteValue(s);
336
OnSerialized(writer, contract, value);
339
private void OnSerializing(JsonWriter writer, JsonContract contract, object value)
341
if (TraceWriter != null && TraceWriter.LevelFilter >= TraceLevel.Info)
342
TraceWriter.Trace(TraceLevel.Info, JsonPosition.FormatMessage(null, writer.Path, "Started serializing {0}".FormatWith(CultureInfo.InvariantCulture, contract.UnderlyingType)), null);
344
contract.InvokeOnSerializing(value, Serializer.Context);
347
private void OnSerialized(JsonWriter writer, JsonContract contract, object value)
349
if (TraceWriter != null && TraceWriter.LevelFilter >= TraceLevel.Info)
350
TraceWriter.Trace(TraceLevel.Info, JsonPosition.FormatMessage(null, writer.Path, "Finished serializing {0}".FormatWith(CultureInfo.InvariantCulture, contract.UnderlyingType)), null);
352
contract.InvokeOnSerialized(value, Serializer.Context);
355
private void SerializeObject(JsonWriter writer, object value, JsonObjectContract contract, JsonProperty member, JsonContainerContract collectionContract, JsonProperty containerProperty)
357
OnSerializing(writer, contract, value);
359
_serializeStack.Add(value);
361
WriteObjectStart(writer, value, contract, member, collectionContract, containerProperty);
363
int initialDepth = writer.Top;
365
foreach (JsonProperty property in contract.Properties)
370
JsonContract memberContract;
372
if (!CalculatePropertyValues(writer, value, contract, member, property, out memberContract, out memberValue))
375
writer.WritePropertyName(property.PropertyName);
376
SerializeValue(writer, memberValue, memberContract, property, contract, member);
380
if (IsErrorHandled(value, contract, property.PropertyName, null, writer.ContainerPath, ex))
381
HandleError(writer, initialDepth);
387
writer.WriteEndObject();
389
_serializeStack.RemoveAt(_serializeStack.Count - 1);
391
OnSerialized(writer, contract, value);
394
private bool CalculatePropertyValues(JsonWriter writer, object value, JsonContainerContract contract, JsonProperty member, JsonProperty property, out JsonContract memberContract, out object memberValue)
396
if (!property.Ignored && property.Readable && ShouldSerialize(writer, property, value) && IsSpecified(writer, property, value))
398
if (property.PropertyContract == null)
399
property.PropertyContract = Serializer.ContractResolver.ResolveContract(property.PropertyType);
401
memberValue = property.ValueProvider.GetValue(value);
402
memberContract = (property.PropertyContract.UnderlyingType.IsSealed()) ? property.PropertyContract : GetContractSafe(memberValue);
404
if (ShouldWriteProperty(memberValue, property))
406
if (ShouldWriteReference(memberValue, property, memberContract, contract, member))
408
writer.WritePropertyName(property.PropertyName);
409
WriteReference(writer, memberValue);
413
if (!CheckForCircularReference(writer, memberValue, property, memberContract, contract, member))
416
if (memberValue == null)
418
JsonObjectContract objectContract = contract as JsonObjectContract;
419
Required resolvedRequired = property._required ?? ((objectContract != null) ? objectContract.ItemRequired : null) ?? Required.Default;
420
if (resolvedRequired == Required.Always)
421
throw JsonSerializationException.Create(null, writer.ContainerPath, "Cannot write a null value for property '{0}'. Property requires a value.".FormatWith(CultureInfo.InvariantCulture, property.PropertyName), null);
428
memberContract = null;
433
private void WriteObjectStart(JsonWriter writer, object value, JsonContract contract, JsonProperty member, JsonContainerContract collectionContract, JsonProperty containerProperty)
435
writer.WriteStartObject();
437
bool isReference = ResolveIsReference(contract, member, collectionContract, containerProperty) ?? HasFlag(Serializer.PreserveReferencesHandling, PreserveReferencesHandling.Objects);
440
WriteReferenceIdProperty(writer, contract.UnderlyingType, value);
442
if (ShouldWriteType(TypeNameHandling.Objects, contract, member, collectionContract, containerProperty))
444
WriteTypeProperty(writer, contract.UnderlyingType);
448
private void WriteReferenceIdProperty(JsonWriter writer, Type type, object value)
450
string reference = GetReference(writer, value);
452
if (TraceWriter != null && TraceWriter.LevelFilter >= TraceLevel.Verbose)
453
TraceWriter.Trace(TraceLevel.Verbose, JsonPosition.FormatMessage(null, writer.Path, "Writing object reference Id '{0}' for {1}.".FormatWith(CultureInfo.InvariantCulture, reference, type)), null);
455
writer.WritePropertyName(JsonTypeReflector.IdPropertyName);
456
writer.WriteValue(reference);
459
private void WriteTypeProperty(JsonWriter writer, Type type)
461
string typeName = ReflectionUtils.GetTypeName(type, Serializer.TypeNameAssemblyFormat, Serializer.Binder);
463
if (TraceWriter != null && TraceWriter.LevelFilter >= TraceLevel.Verbose)
464
TraceWriter.Trace(TraceLevel.Verbose, JsonPosition.FormatMessage(null, writer.Path, "Writing type name '{0}' for {1}.".FormatWith(CultureInfo.InvariantCulture, typeName, type)), null);
466
writer.WritePropertyName(JsonTypeReflector.TypePropertyName);
467
writer.WriteValue(typeName);
470
private bool HasFlag(DefaultValueHandling value, DefaultValueHandling flag)
472
return ((value & flag) == flag);
475
private bool HasFlag(PreserveReferencesHandling value, PreserveReferencesHandling flag)
477
return ((value & flag) == flag);
480
private bool HasFlag(TypeNameHandling value, TypeNameHandling flag)
482
return ((value & flag) == flag);
485
private void SerializeConvertable(JsonWriter writer, JsonConverter converter, object value, JsonContract contract, JsonContainerContract collectionContract, JsonProperty containerProperty)
487
if (ShouldWriteReference(value, null, contract, collectionContract, containerProperty))
489
WriteReference(writer, value);
493
if (!CheckForCircularReference(writer, value, null, contract, collectionContract, containerProperty))
496
_serializeStack.Add(value);
498
if (TraceWriter != null && TraceWriter.LevelFilter >= TraceLevel.Info)
499
TraceWriter.Trace(TraceLevel.Info, JsonPosition.FormatMessage(null, writer.Path, "Started serializing {0} with converter {1}.".FormatWith(CultureInfo.InvariantCulture, value.GetType(), converter.GetType())), null);
501
converter.WriteJson(writer, value, GetInternalSerializer());
503
if (TraceWriter != null && TraceWriter.LevelFilter >= TraceLevel.Info)
504
TraceWriter.Trace(TraceLevel.Info, JsonPosition.FormatMessage(null, writer.Path, "Finished serializing {0} with converter {1}.".FormatWith(CultureInfo.InvariantCulture, value.GetType(), converter.GetType())), null);
506
_serializeStack.RemoveAt(_serializeStack.Count - 1);
510
private void SerializeList(JsonWriter writer, IWrappedCollection values, JsonArrayContract contract, JsonProperty member, JsonContainerContract collectionContract, JsonProperty containerProperty)
512
OnSerializing(writer, contract, values.UnderlyingCollection);
514
_serializeStack.Add(values.UnderlyingCollection);
516
bool hasWrittenMetadataObject = WriteStartArray(writer, values.UnderlyingCollection, contract, member, collectionContract, containerProperty);
518
writer.WriteStartArray();
520
int initialDepth = writer.Top;
523
// note that an error in the IEnumerable won't be caught
524
foreach (object value in values)
528
JsonContract valueContract = contract.FinalItemContract ?? GetContractSafe(value);
530
if (ShouldWriteReference(value, null, valueContract, contract, member))
532
WriteReference(writer, value);
536
if (CheckForCircularReference(writer, value, null, valueContract, contract, member))
538
SerializeValue(writer, value, valueContract, null, contract, member);
544
if (IsErrorHandled(values.UnderlyingCollection, contract, index, null, writer.ContainerPath, ex))
545
HandleError(writer, initialDepth);
555
writer.WriteEndArray();
557
if (hasWrittenMetadataObject)
558
writer.WriteEndObject();
560
_serializeStack.RemoveAt(_serializeStack.Count - 1);
562
OnSerialized(writer, contract, values.UnderlyingCollection);
565
private void SerializeMultidimensionalArray(JsonWriter writer, Array values, JsonArrayContract contract, JsonProperty member, JsonContainerContract collectionContract, JsonProperty containerProperty)
567
OnSerializing(writer, contract, values);
569
_serializeStack.Add(values);
571
bool hasWrittenMetadataObject = WriteStartArray(writer, values, contract, member, collectionContract, containerProperty);
573
SerializeMultidimensionalArray(writer, values, contract, member, writer.Top, new int[0]);
575
if (hasWrittenMetadataObject)
576
writer.WriteEndObject();
578
_serializeStack.RemoveAt(_serializeStack.Count - 1);
580
OnSerialized(writer, contract, values);
583
private void SerializeMultidimensionalArray(JsonWriter writer, Array values, JsonArrayContract contract, JsonProperty member, int initialDepth, int[] indices)
585
int dimension = indices.Length;
586
int[] newIndices = new int[dimension + 1];
587
for (int i = 0; i < dimension; i++)
589
newIndices[i] = indices[i];
592
writer.WriteStartArray();
594
for (int i = 0; i < values.GetLength(dimension); i++)
596
newIndices[dimension] = i;
597
bool isTopLevel = (newIndices.Length == values.Rank);
601
object value = values.GetValue(newIndices);
605
JsonContract valueContract = contract.FinalItemContract ?? GetContractSafe(value);
607
if (ShouldWriteReference(value, null, valueContract, contract, member))
609
WriteReference(writer, value);
613
if (CheckForCircularReference(writer, value, null, valueContract, contract, member))
615
SerializeValue(writer, value, valueContract, null, contract, member);
621
if (IsErrorHandled(values, contract, i, null, writer.ContainerPath, ex))
622
HandleError(writer, initialDepth + 1);
629
SerializeMultidimensionalArray(writer, values, contract, member, initialDepth + 1, newIndices);
633
writer.WriteEndArray();
636
private bool WriteStartArray(JsonWriter writer, object values, JsonArrayContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerProperty)
638
bool isReference = ResolveIsReference(contract, member, containerContract, containerProperty) ?? HasFlag(Serializer.PreserveReferencesHandling, PreserveReferencesHandling.Arrays);
639
bool includeTypeDetails = ShouldWriteType(TypeNameHandling.Arrays, contract, member, containerContract, containerProperty);
640
bool writeMetadataObject = isReference || includeTypeDetails;
642
if (writeMetadataObject)
644
writer.WriteStartObject();
648
WriteReferenceIdProperty(writer, contract.UnderlyingType, values);
650
if (includeTypeDetails)
652
WriteTypeProperty(writer, values.GetType());
654
writer.WritePropertyName(JsonTypeReflector.ArrayValuesPropertyName);
657
if (contract.ItemContract == null)
658
contract.ItemContract = Serializer.ContractResolver.ResolveContract(contract.CollectionItemType ?? typeof (object));
660
return writeMetadataObject;
663
#if !(SILVERLIGHT || NETFX_CORE || PORTABLE)
664
#if !(NET20 || NET35)
665
[SecuritySafeCritical]
667
private void SerializeISerializable(JsonWriter writer, ISerializable value, JsonISerializableContract contract, JsonProperty member, JsonContainerContract collectionContract, JsonProperty containerProperty)
669
if (!JsonTypeReflector.FullyTrusted)
671
throw JsonSerializationException.Create(null, writer.ContainerPath, @"Type '{0}' implements ISerializable but cannot be serialized using the ISerializable interface because the current application is not fully trusted and ISerializable can expose secure data.
672
To fix this error either change the environment to be fully trusted, change the application to not deserialize the type, add JsonObjectAttribute to the type or change the JsonSerializer setting ContractResolver to use a new DefaultContractResolver with IgnoreSerializableInterface set to true.".FormatWith(CultureInfo.InvariantCulture, value.GetType()), null);
675
OnSerializing(writer, contract, value);
676
_serializeStack.Add(value);
678
WriteObjectStart(writer, value, contract, member, collectionContract, containerProperty);
680
SerializationInfo serializationInfo = new SerializationInfo(contract.UnderlyingType, new FormatterConverter());
681
value.GetObjectData(serializationInfo, Serializer.Context);
683
foreach (SerializationEntry serializationEntry in serializationInfo)
685
JsonContract valueContract = GetContractSafe(serializationEntry.Value);
687
if (CheckForCircularReference(writer, serializationEntry.Value, null, valueContract, contract, member))
689
writer.WritePropertyName(serializationEntry.Name);
690
SerializeValue(writer, serializationEntry.Value, valueContract, null, contract, member);
694
writer.WriteEndObject();
696
_serializeStack.RemoveAt(_serializeStack.Count - 1);
697
OnSerialized(writer, contract, value);
701
#if !(NET35 || NET20 || WINDOWS_PHONE || PORTABLE)
702
private void SerializeDynamic(JsonWriter writer, IDynamicMetaObjectProvider value, JsonDynamicContract contract, JsonProperty member, JsonContainerContract collectionContract, JsonProperty containerProperty)
704
OnSerializing(writer, contract, value);
705
_serializeStack.Add(value);
707
WriteObjectStart(writer, value, contract, member, collectionContract, containerProperty);
709
int initialDepth = writer.Top;
711
foreach (JsonProperty property in contract.Properties)
713
// only write non-dynamic properties that have an explicit attribute
714
if (property.HasMemberAttribute)
719
JsonContract memberContract;
721
if (!CalculatePropertyValues(writer, value, contract, member, property, out memberContract, out memberValue))
724
writer.WritePropertyName(property.PropertyName);
725
SerializeValue(writer, memberValue, memberContract, property, contract, member);
729
if (IsErrorHandled(value, contract, property.PropertyName, null, writer.ContainerPath, ex))
730
HandleError(writer, initialDepth);
737
foreach (string memberName in value.GetDynamicMemberNames())
740
if (value.TryGetMember(memberName, out memberValue))
744
JsonContract valueContract = GetContractSafe(memberValue);
746
if (CheckForCircularReference(writer, memberValue, null, valueContract, contract, member))
748
string resolvedPropertyName = (contract.PropertyNameResolver != null)
749
? contract.PropertyNameResolver(memberName)
752
writer.WritePropertyName(resolvedPropertyName);
753
SerializeValue(writer, memberValue, valueContract, null, contract, member);
758
if (IsErrorHandled(value, contract, memberName, null, writer.ContainerPath, ex))
759
HandleError(writer, initialDepth);
766
writer.WriteEndObject();
768
_serializeStack.RemoveAt(_serializeStack.Count - 1);
769
OnSerialized(writer, contract, value);
773
private bool ShouldWriteType(TypeNameHandling typeNameHandlingFlag, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerProperty)
775
TypeNameHandling resolvedTypeNameHandling =
776
((member != null) ? member.TypeNameHandling : null)
777
?? ((containerProperty != null) ? containerProperty.ItemTypeNameHandling : null)
778
?? ((containerContract != null) ? containerContract.ItemTypeNameHandling : null)
779
?? Serializer.TypeNameHandling;
781
if (HasFlag(resolvedTypeNameHandling, typeNameHandlingFlag))
784
// instance type and the property's type's contract default type are different (no need to put the type in JSON because the type will be created by default)
785
if (HasFlag(resolvedTypeNameHandling, TypeNameHandling.Auto))
789
if (contract.UnderlyingType != member.PropertyContract.CreatedType)
792
else if (containerContract != null && containerContract.ItemContract != null)
794
if (contract.UnderlyingType != containerContract.ItemContract.CreatedType)
802
private void SerializeDictionary(JsonWriter writer, IWrappedDictionary values, JsonDictionaryContract contract, JsonProperty member, JsonContainerContract collectionContract, JsonProperty containerProperty)
804
OnSerializing(writer, contract, values.UnderlyingDictionary);
805
_serializeStack.Add(values.UnderlyingDictionary);
807
WriteObjectStart(writer, values.UnderlyingDictionary, contract, member, collectionContract, containerProperty);
809
if (contract.ItemContract == null)
810
contract.ItemContract = Serializer.ContractResolver.ResolveContract(contract.DictionaryValueType ?? typeof(object));
812
int initialDepth = writer.Top;
814
// Mono Unity 3.0 fix
815
IWrappedDictionary d = values;
817
foreach (DictionaryEntry entry in d)
819
string propertyName = GetPropertyName(entry);
821
propertyName = (contract.PropertyNameResolver != null)
822
? contract.PropertyNameResolver(propertyName)
827
object value = entry.Value;
828
JsonContract valueContract = contract.FinalItemContract ?? GetContractSafe(value);
830
if (ShouldWriteReference(value, null, valueContract, contract, member))
832
writer.WritePropertyName(propertyName);
833
WriteReference(writer, value);
837
if (!CheckForCircularReference(writer, value, null, valueContract, contract, member))
840
writer.WritePropertyName(propertyName);
842
SerializeValue(writer, value, valueContract, null, contract, member);
847
if (IsErrorHandled(values.UnderlyingDictionary, contract, propertyName, null, writer.ContainerPath, ex))
848
HandleError(writer, initialDepth);
854
writer.WriteEndObject();
856
_serializeStack.RemoveAt(_serializeStack.Count - 1);
858
OnSerialized(writer, contract, values.UnderlyingDictionary);
861
private string GetPropertyName(DictionaryEntry entry)
865
if (ConvertUtils.IsConvertible(entry.Key))
866
return Convert.ToString(entry.Key, CultureInfo.InvariantCulture);
867
else if (TryConvertToString(entry.Key, entry.Key.GetType(), out propertyName))
870
return entry.Key.ToString();
873
private void HandleError(JsonWriter writer, int initialDepth)
877
if (writer.WriteState == WriteState.Property)
880
while (writer.Top > initialDepth)
886
private bool ShouldSerialize(JsonWriter writer, JsonProperty property, object target)
888
if (property.ShouldSerialize == null)
891
bool shouldSerialize = property.ShouldSerialize(target);
893
if (TraceWriter != null && TraceWriter.LevelFilter >= TraceLevel.Verbose)
894
TraceWriter.Trace(TraceLevel.Verbose, JsonPosition.FormatMessage(null, writer.Path, "ShouldSerialize result for property '{0}' on {1}: {2}".FormatWith(CultureInfo.InvariantCulture, property.PropertyName, property.DeclaringType, shouldSerialize)), null);
896
return shouldSerialize;
899
private bool IsSpecified(JsonWriter writer, JsonProperty property, object target)
901
if (property.GetIsSpecified == null)
904
bool isSpecified = property.GetIsSpecified(target);
906
if (TraceWriter != null && TraceWriter.LevelFilter >= TraceLevel.Verbose)
907
TraceWriter.Trace(TraceLevel.Verbose, JsonPosition.FormatMessage(null, writer.Path, "IsSpecified result for property '{0}' on {1}: {2}".FormatWith(CultureInfo.InvariantCulture, property.PropertyName, property.DeclaringType, isSpecified)), null);
b'\\ No newline at end of file'