<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />

JsonSerializerInternalWriter

using Newtonsoft.Json.Linq; using Newtonsoft.Json.Utilities; using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; using System.Dynamic; using System.Globalization; using System.IO; using System.Linq; using System.Runtime.CompilerServices; namespace Newtonsoft.Json.Serialization { [System.Runtime.CompilerServices.NullableContext(1)] [System.Runtime.CompilerServices.Nullable(0)] internal class JsonSerializerInternalWriter : JsonSerializerInternalBase { [System.Runtime.CompilerServices.Nullable(2)] private Type _rootType; private int _rootLevel; private readonly List<object> _serializeStack = new List<object>(); public JsonSerializerInternalWriter(JsonSerializer serializer) : base(serializer) { } [System.Runtime.CompilerServices.NullableContext(2)] public void Serialize([System.Runtime.CompilerServices.Nullable(1)] JsonWriter jsonWriter, object value, Type objectType) { if (jsonWriter == null) throw new ArgumentNullException("jsonWriter"); _rootType = objectType; _rootLevel = _serializeStack.Count + 1; JsonContract contractSafe = GetContractSafe(value); try { if (ShouldWriteReference(value, null, contractSafe, null, null)) WriteReference(jsonWriter, value); else SerializeValue(jsonWriter, value, contractSafe, null, null, null); } catch (Exception ex) { if (!IsErrorHandled(null, contractSafe, null, null, jsonWriter.Path, ex)) { ClearErrorContext(); throw; } HandleError(jsonWriter, 0); } finally { _rootType = null; } } private JsonSerializerProxy GetInternalSerializer() { if (InternalSerializer == null) InternalSerializer = new JsonSerializerProxy(this); return InternalSerializer; } [System.Runtime.CompilerServices.NullableContext(2)] private JsonContract GetContractSafe(object value) { if (value == null) return null; return GetContract(value); } private JsonContract GetContract(object value) { return Serializer._contractResolver.ResolveContract(value.GetType()); } private void SerializePrimitive(JsonWriter writer, object value, JsonPrimitiveContract contract, [System.Runtime.CompilerServices.Nullable(2)] JsonProperty member, [System.Runtime.CompilerServices.Nullable(2)] JsonContainerContract containerContract, [System.Runtime.CompilerServices.Nullable(2)] JsonProperty containerProperty) { if (contract.TypeCode == PrimitiveTypeCode.Bytes && ShouldWriteType(TypeNameHandling.Objects, contract, member, containerContract, containerProperty)) { writer.WriteStartObject(); WriteTypeProperty(writer, contract.CreatedType); writer.WritePropertyName("$value", false); JsonWriter.WriteValue(writer, contract.TypeCode, value); writer.WriteEndObject(); } else JsonWriter.WriteValue(writer, contract.TypeCode, value); } [System.Runtime.CompilerServices.NullableContext(2)] private void SerializeValue([System.Runtime.CompilerServices.Nullable(1)] JsonWriter writer, object value, JsonContract valueContract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerProperty) { if (value == null) writer.WriteNull(); else { JsonConverter jsonConverter = member?.Converter ?? containerProperty?.ItemConverter ?? containerContract?.ItemConverter ?? valueContract.Converter ?? Serializer.GetMatchingConverter(valueContract.UnderlyingType) ?? valueContract.InternalConverter; if (jsonConverter == null || !jsonConverter.CanWrite) { switch (valueContract.ContractType) { case JsonContractType.Serializable: break; case JsonContractType.Object: SerializeObject(writer, value, (JsonObjectContract)valueContract, member, containerContract, containerProperty); break; case JsonContractType.Array: { JsonArrayContract jsonArrayContract = (JsonArrayContract)valueContract; if (!jsonArrayContract.IsMultidimensionalArray) SerializeList(writer, (IEnumerable)value, jsonArrayContract, member, containerContract, containerProperty); else SerializeMultidimensionalArray(writer, (Array)value, jsonArrayContract, member, containerContract, containerProperty); break; } case JsonContractType.Primitive: SerializePrimitive(writer, value, (JsonPrimitiveContract)valueContract, member, containerContract, containerProperty); break; case JsonContractType.String: SerializeString(writer, value, (JsonStringContract)valueContract); break; case JsonContractType.Dictionary: { JsonDictionaryContract jsonDictionaryContract = (JsonDictionaryContract)valueContract; IDictionary dictionary = value as IDictionary; object values; if (dictionary == null) { IDictionary dictionary2 = jsonDictionaryContract.CreateWrapper(value); values = dictionary2; } else values = dictionary; SerializeDictionary(writer, (IDictionary)values, jsonDictionaryContract, member, containerContract, containerProperty); break; } case JsonContractType.Dynamic: SerializeDynamic(writer, (IDynamicMetaObjectProvider)value, (JsonDynamicContract)valueContract, member, containerContract, containerProperty); break; case JsonContractType.Linq: ((JToken)value).WriteTo(writer, Serializer.Converters.ToArray()); break; } } else SerializeConvertable(writer, jsonConverter, value, valueContract, containerContract, containerProperty); } } [System.Runtime.CompilerServices.NullableContext(2)] private bool? ResolveIsReference([System.Runtime.CompilerServices.Nullable(1)] JsonContract contract, JsonProperty property, JsonContainerContract collectionContract, JsonProperty containerProperty) { bool? result = null; if (property != null) result = property.IsReference; if (!result.HasValue && containerProperty != null) result = containerProperty.ItemIsReference; if (!result.HasValue && collectionContract != null) result = collectionContract.ItemIsReference; if (!result.HasValue) result = contract.IsReference; return result; } [System.Runtime.CompilerServices.NullableContext(2)] private bool ShouldWriteReference(object value, JsonProperty property, JsonContract valueContract, JsonContainerContract collectionContract, JsonProperty containerProperty) { if (value == null) return false; if (valueContract.ContractType == JsonContractType.Primitive || valueContract.ContractType == JsonContractType.String) return false; bool? nullable = ResolveIsReference(valueContract, property, collectionContract, containerProperty); if (!nullable.HasValue) nullable = ((valueContract.ContractType == JsonContractType.Array) ? new bool?(HasFlag(Serializer._preserveReferencesHandling, PreserveReferencesHandling.Arrays)) : new bool?(HasFlag(Serializer._preserveReferencesHandling, PreserveReferencesHandling.Objects))); if (!nullable.GetValueOrDefault()) return false; return Serializer.GetReferenceResolver().IsReferenced(this, value); } [System.Runtime.CompilerServices.NullableContext(2)] private bool ShouldWriteProperty(object memberValue, JsonObjectContract containerContract, [System.Runtime.CompilerServices.Nullable(1)] JsonProperty property) { if (memberValue == null && ResolvedNullValueHandling(containerContract, property) == NullValueHandling.Ignore) return false; if (HasFlag(property.DefaultValueHandling.GetValueOrDefault(Serializer._defaultValueHandling), DefaultValueHandling.Ignore) && MiscellaneousUtils.ValueEquals(memberValue, property.GetResolvedDefaultValue())) return false; return true; } [System.Runtime.CompilerServices.NullableContext(2)] private bool CheckForCircularReference([System.Runtime.CompilerServices.Nullable(1)] JsonWriter writer, object value, JsonProperty property, JsonContract contract, JsonContainerContract containerContract, JsonProperty containerProperty) { if (value == null) return true; if (contract.ContractType == JsonContractType.Primitive || contract.ContractType == JsonContractType.String) return true; ReferenceLoopHandling? nullable = null; if (property != null) nullable = property.ReferenceLoopHandling; if (!nullable.HasValue && containerProperty != null) nullable = containerProperty.ItemReferenceLoopHandling; if (!nullable.HasValue && containerContract != null) nullable = containerContract.ItemReferenceLoopHandling; if ((Serializer._equalityComparer != null) ? _serializeStack.Contains(value, Serializer._equalityComparer) : _serializeStack.Contains(value)) { string str = "Self referencing loop detected"; if (property != null) str += " for property '{0}'".FormatWith(CultureInfo.InvariantCulture, property.PropertyName); str += " with type '{0}'.".FormatWith(CultureInfo.InvariantCulture, value.GetType()); switch (nullable.GetValueOrDefault(Serializer._referenceLoopHandling)) { case ReferenceLoopHandling.Error: throw JsonSerializationException.Create(null, writer.ContainerPath, str, null); case ReferenceLoopHandling.Ignore: if (TraceWriter != null && TraceWriter.LevelFilter >= TraceLevel.Verbose) TraceWriter.Trace(TraceLevel.Verbose, JsonPosition.FormatMessage(null, writer.Path, str + ". Skipping serializing self referenced value."), null); return false; case ReferenceLoopHandling.Serialize: if (TraceWriter != null && TraceWriter.LevelFilter >= TraceLevel.Verbose) TraceWriter.Trace(TraceLevel.Verbose, JsonPosition.FormatMessage(null, writer.Path, str + ". Serializing self referenced value."), null); return true; } } return true; } private void WriteReference(JsonWriter writer, object value) { string reference = GetReference(writer, value); if (TraceWriter != null && TraceWriter.LevelFilter >= TraceLevel.Info) TraceWriter.Trace(TraceLevel.Info, JsonPosition.FormatMessage(null, writer.Path, "Writing object reference to Id '{0}' for {1}.".FormatWith(CultureInfo.InvariantCulture, reference, value.GetType())), null); writer.WriteStartObject(); writer.WritePropertyName("$ref", false); writer.WriteValue(reference); writer.WriteEndObject(); } private string GetReference(JsonWriter writer, object value) { try { return Serializer.GetReferenceResolver().GetReference(this, value); } catch (Exception ex) { throw JsonSerializationException.Create(null, writer.ContainerPath, "Error writing object reference for '{0}'.".FormatWith(CultureInfo.InvariantCulture, value.GetType()), ex); } } internal static bool TryConvertToString(object value, Type type, [System.Runtime.CompilerServices.Nullable(2)] [System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out string s) { if (value is Guid || value is Uri || value is TimeSpan) { s = value.ToString(); return true; } Type type2 = value as Type; if ((object)type2 != null) { s = type2.AssemblyQualifiedName; return true; } s = null; return false; } private void SerializeString(JsonWriter writer, object value, JsonStringContract contract) { OnSerializing(writer, contract, value); TryConvertToString(value, contract.UnderlyingType, out string s); writer.WriteValue(s); OnSerialized(writer, contract, value); } private void OnSerializing(JsonWriter writer, JsonContract contract, object value) { if (TraceWriter != null && TraceWriter.LevelFilter >= TraceLevel.Info) TraceWriter.Trace(TraceLevel.Info, JsonPosition.FormatMessage(null, writer.Path, "Started serializing {0}".FormatWith(CultureInfo.InvariantCulture, contract.UnderlyingType)), null); contract.InvokeOnSerializing(value, Serializer._context); } private void OnSerialized(JsonWriter writer, JsonContract contract, object value) { if (TraceWriter != null && TraceWriter.LevelFilter >= TraceLevel.Info) TraceWriter.Trace(TraceLevel.Info, JsonPosition.FormatMessage(null, writer.Path, "Finished serializing {0}".FormatWith(CultureInfo.InvariantCulture, contract.UnderlyingType)), null); contract.InvokeOnSerialized(value, Serializer._context); } private void SerializeObject(JsonWriter writer, object value, JsonObjectContract contract, [System.Runtime.CompilerServices.Nullable(2)] JsonProperty member, [System.Runtime.CompilerServices.Nullable(2)] JsonContainerContract collectionContract, [System.Runtime.CompilerServices.Nullable(2)] JsonProperty containerProperty) { OnSerializing(writer, contract, value); _serializeStack.Add(value); WriteObjectStart(writer, value, contract, member, collectionContract, containerProperty); int top = writer.Top; for (int i = 0; i < contract.Properties.Count; i++) { JsonProperty jsonProperty = contract.Properties[i]; try { if (CalculatePropertyValues(writer, value, contract, member, jsonProperty, out JsonContract memberContract, out object memberValue)) { jsonProperty.WritePropertyName(writer); SerializeValue(writer, memberValue, memberContract, jsonProperty, contract, member); } } catch (Exception ex) { if (!IsErrorHandled(value, contract, jsonProperty.PropertyName, null, writer.ContainerPath, ex)) throw; HandleError(writer, top); } } IEnumerable<KeyValuePair<object, object>> enumerable = contract.ExtensionDataGetter?.Invoke(value); if (enumerable != null) { foreach (KeyValuePair<object, object> item in enumerable) { JsonContract contract2 = GetContract(item.Key); JsonContract contractSafe = GetContractSafe(item.Value); string propertyName = GetPropertyName(writer, item.Key, contract2, out bool _); propertyName = ((contract.ExtensionDataNameResolver != null) ? contract.ExtensionDataNameResolver(propertyName) : propertyName); if (ShouldWriteReference(item.Value, null, contractSafe, contract, member)) { writer.WritePropertyName(propertyName); WriteReference(writer, item.Value); } else if (CheckForCircularReference(writer, item.Value, null, contractSafe, contract, member)) { writer.WritePropertyName(propertyName); SerializeValue(writer, item.Value, contractSafe, null, contract, member); } } } writer.WriteEndObject(); _serializeStack.RemoveAt(_serializeStack.Count - 1); OnSerialized(writer, contract, value); } private bool CalculatePropertyValues(JsonWriter writer, object value, JsonContainerContract contract, [System.Runtime.CompilerServices.Nullable(2)] JsonProperty member, JsonProperty property, [System.Runtime.CompilerServices.Nullable(2)] [System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out JsonContract memberContract, [System.Runtime.CompilerServices.Nullable(2)] [System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out object memberValue) { if (!property.Ignored && property.Readable && ShouldSerialize(writer, property, value) && IsSpecified(writer, property, value)) { if (property.PropertyContract == null) property.PropertyContract = Serializer._contractResolver.ResolveContract(property.PropertyType); memberValue = property.ValueProvider.GetValue(value); memberContract = (property.PropertyContract.IsSealed ? property.PropertyContract : GetContractSafe(memberValue)); if (ShouldWriteProperty(memberValue, contract as JsonObjectContract, property)) { if (ShouldWriteReference(memberValue, property, memberContract, contract, member)) { property.WritePropertyName(writer); WriteReference(writer, memberValue); return false; } if (!CheckForCircularReference(writer, memberValue, property, memberContract, contract, member)) return false; if (memberValue == null) { JsonObjectContract jsonObjectContract = contract as JsonObjectContract; switch (property._required ?? (jsonObjectContract?.ItemRequired).GetValueOrDefault()) { case Required.Always: throw JsonSerializationException.Create(null, writer.ContainerPath, "Cannot write a null value for property '{0}'. Property requires a value.".FormatWith(CultureInfo.InvariantCulture, property.PropertyName), null); case Required.DisallowNull: throw JsonSerializationException.Create(null, writer.ContainerPath, "Cannot write a null value for property '{0}'. Property requires a non-null value.".FormatWith(CultureInfo.InvariantCulture, property.PropertyName), null); } } return true; } } memberContract = null; memberValue = null; return false; } private void WriteObjectStart(JsonWriter writer, object value, JsonContract contract, [System.Runtime.CompilerServices.Nullable(2)] JsonProperty member, [System.Runtime.CompilerServices.Nullable(2)] JsonContainerContract collectionContract, [System.Runtime.CompilerServices.Nullable(2)] JsonProperty containerProperty) { writer.WriteStartObject(); if ((ResolveIsReference(contract, member, collectionContract, containerProperty) ?? HasFlag(Serializer._preserveReferencesHandling, PreserveReferencesHandling.Objects)) && (member == null || member.Writable || HasCreatorParameter(collectionContract, member))) WriteReferenceIdProperty(writer, contract.UnderlyingType, value); if (ShouldWriteType(TypeNameHandling.Objects, contract, member, collectionContract, containerProperty)) WriteTypeProperty(writer, contract.UnderlyingType); } private bool HasCreatorParameter([System.Runtime.CompilerServices.Nullable(2)] JsonContainerContract contract, JsonProperty property) { return (contract as JsonObjectContract)?.CreatorParameters.Contains(property.PropertyName) ?? false; } private void WriteReferenceIdProperty(JsonWriter writer, Type type, object value) { string reference = GetReference(writer, value); if (TraceWriter != null && TraceWriter.LevelFilter >= TraceLevel.Verbose) TraceWriter.Trace(TraceLevel.Verbose, JsonPosition.FormatMessage(null, writer.Path, "Writing object reference Id '{0}' for {1}.".FormatWith(CultureInfo.InvariantCulture, reference, type)), null); writer.WritePropertyName("$id", false); writer.WriteValue(reference); } private void WriteTypeProperty(JsonWriter writer, Type type) { string typeName = ReflectionUtils.GetTypeName(type, Serializer._typeNameAssemblyFormatHandling, Serializer._serializationBinder); if (TraceWriter != null && TraceWriter.LevelFilter >= TraceLevel.Verbose) TraceWriter.Trace(TraceLevel.Verbose, JsonPosition.FormatMessage(null, writer.Path, "Writing type name '{0}' for {1}.".FormatWith(CultureInfo.InvariantCulture, typeName, type)), null); writer.WritePropertyName("$type", false); writer.WriteValue(typeName); } private bool HasFlag(DefaultValueHandling value, DefaultValueHandling flag) { return (value & flag) == flag; } private bool HasFlag(PreserveReferencesHandling value, PreserveReferencesHandling flag) { return (value & flag) == flag; } private bool HasFlag(TypeNameHandling value, TypeNameHandling flag) { return (value & flag) == flag; } private void SerializeConvertable(JsonWriter writer, JsonConverter converter, object value, JsonContract contract, [System.Runtime.CompilerServices.Nullable(2)] JsonContainerContract collectionContract, [System.Runtime.CompilerServices.Nullable(2)] JsonProperty containerProperty) { if (ShouldWriteReference(value, null, contract, collectionContract, containerProperty)) WriteReference(writer, value); else if (CheckForCircularReference(writer, value, null, contract, collectionContract, containerProperty)) { _serializeStack.Add(value); if (TraceWriter != null && TraceWriter.LevelFilter >= TraceLevel.Info) TraceWriter.Trace(TraceLevel.Info, JsonPosition.FormatMessage(null, writer.Path, "Started serializing {0} with converter {1}.".FormatWith(CultureInfo.InvariantCulture, value.GetType(), converter.GetType())), null); converter.WriteJson(writer, value, GetInternalSerializer()); if (TraceWriter != null && TraceWriter.LevelFilter >= TraceLevel.Info) TraceWriter.Trace(TraceLevel.Info, JsonPosition.FormatMessage(null, writer.Path, "Finished serializing {0} with converter {1}.".FormatWith(CultureInfo.InvariantCulture, value.GetType(), converter.GetType())), null); _serializeStack.RemoveAt(_serializeStack.Count - 1); } } private void SerializeList(JsonWriter writer, IEnumerable values, JsonArrayContract contract, [System.Runtime.CompilerServices.Nullable(2)] JsonProperty member, [System.Runtime.CompilerServices.Nullable(2)] JsonContainerContract collectionContract, [System.Runtime.CompilerServices.Nullable(2)] JsonProperty containerProperty) { IWrappedCollection wrappedCollection = values as IWrappedCollection; object obj = (wrappedCollection != null) ? wrappedCollection.UnderlyingCollection : values; OnSerializing(writer, contract, obj); _serializeStack.Add(obj); bool flag = WriteStartArray(writer, obj, contract, member, collectionContract, containerProperty); writer.WriteStartArray(); int top = writer.Top; int num = 0; foreach (object value in values) { try { JsonContract jsonContract = contract.FinalItemContract ?? GetContractSafe(value); if (ShouldWriteReference(value, null, jsonContract, contract, member)) WriteReference(writer, value); else if (CheckForCircularReference(writer, value, null, jsonContract, contract, member)) { SerializeValue(writer, value, jsonContract, null, contract, member); } } catch (Exception ex) { if (!IsErrorHandled(obj, contract, num, null, writer.ContainerPath, ex)) throw; HandleError(writer, top); } finally { num++; } } writer.WriteEndArray(); if (flag) writer.WriteEndObject(); _serializeStack.RemoveAt(_serializeStack.Count - 1); OnSerialized(writer, contract, obj); } private void SerializeMultidimensionalArray(JsonWriter writer, Array values, JsonArrayContract contract, [System.Runtime.CompilerServices.Nullable(2)] JsonProperty member, [System.Runtime.CompilerServices.Nullable(2)] JsonContainerContract collectionContract, [System.Runtime.CompilerServices.Nullable(2)] JsonProperty containerProperty) { OnSerializing(writer, contract, values); _serializeStack.Add(values); bool num = WriteStartArray(writer, values, contract, member, collectionContract, containerProperty); SerializeMultidimensionalArray(writer, values, contract, member, writer.Top, CollectionUtils.ArrayEmpty<int>()); if (num) writer.WriteEndObject(); _serializeStack.RemoveAt(_serializeStack.Count - 1); OnSerialized(writer, contract, values); } private void SerializeMultidimensionalArray(JsonWriter writer, Array values, JsonArrayContract contract, [System.Runtime.CompilerServices.Nullable(2)] JsonProperty member, int initialDepth, int[] indices) { int num = indices.Length; int[] array = new int[num + 1]; for (int i = 0; i < num; i++) { array[i] = indices[i]; } writer.WriteStartArray(); for (int j = values.GetLowerBound(num); j <= values.GetUpperBound(num); j++) { array[num] = j; if (array.Length == values.Rank) { object value = values.GetValue(array); try { JsonContract jsonContract = contract.FinalItemContract ?? GetContractSafe(value); if (ShouldWriteReference(value, null, jsonContract, contract, member)) WriteReference(writer, value); else if (CheckForCircularReference(writer, value, null, jsonContract, contract, member)) { SerializeValue(writer, value, jsonContract, null, contract, member); } } catch (Exception ex) { if (!IsErrorHandled(values, contract, j, null, writer.ContainerPath, ex)) throw; HandleError(writer, initialDepth + 1); } } else SerializeMultidimensionalArray(writer, values, contract, member, initialDepth + 1, array); } writer.WriteEndArray(); } private bool WriteStartArray(JsonWriter writer, object values, JsonArrayContract contract, [System.Runtime.CompilerServices.Nullable(2)] JsonProperty member, [System.Runtime.CompilerServices.Nullable(2)] JsonContainerContract containerContract, [System.Runtime.CompilerServices.Nullable(2)] JsonProperty containerProperty) { bool flag = (ResolveIsReference(contract, member, containerContract, containerProperty) ?? HasFlag(Serializer._preserveReferencesHandling, PreserveReferencesHandling.Arrays)) && (member == null || member.Writable || HasCreatorParameter(containerContract, member)); bool flag2 = ShouldWriteType(TypeNameHandling.Arrays, contract, member, containerContract, containerProperty); bool num = flag | flag2; if (num) { writer.WriteStartObject(); if (flag) WriteReferenceIdProperty(writer, contract.UnderlyingType, values); if (flag2) WriteTypeProperty(writer, values.GetType()); writer.WritePropertyName("$values", false); } if (contract.ItemContract == null) contract.ItemContract = Serializer._contractResolver.ResolveContract(contract.CollectionItemType ?? typeof(object)); return num; } private void SerializeDynamic(JsonWriter writer, IDynamicMetaObjectProvider value, JsonDynamicContract contract, [System.Runtime.CompilerServices.Nullable(2)] JsonProperty member, [System.Runtime.CompilerServices.Nullable(2)] JsonContainerContract collectionContract, [System.Runtime.CompilerServices.Nullable(2)] JsonProperty containerProperty) { OnSerializing(writer, contract, value); _serializeStack.Add(value); WriteObjectStart(writer, value, contract, member, collectionContract, containerProperty); int top = writer.Top; for (int i = 0; i < contract.Properties.Count; i++) { JsonProperty jsonProperty = contract.Properties[i]; if (jsonProperty.HasMemberAttribute) try { if (CalculatePropertyValues(writer, value, contract, member, jsonProperty, out JsonContract memberContract, out object memberValue)) { jsonProperty.WritePropertyName(writer); SerializeValue(writer, memberValue, memberContract, jsonProperty, contract, member); } } catch (Exception ex) { if (!IsErrorHandled(value, contract, jsonProperty.PropertyName, null, writer.ContainerPath, ex)) throw; HandleError(writer, top); } } foreach (string dynamicMemberName in value.GetDynamicMemberNames()) { if (contract.TryGetMember(value, dynamicMemberName, out object value2)) try { JsonContract contractSafe = GetContractSafe(value2); if (ShouldWriteDynamicProperty(value2) && CheckForCircularReference(writer, value2, null, contractSafe, contract, member)) { string name = (contract.PropertyNameResolver != null) ? contract.PropertyNameResolver(dynamicMemberName) : dynamicMemberName; writer.WritePropertyName(name); SerializeValue(writer, value2, contractSafe, null, contract, member); } } catch (Exception ex2) { if (!IsErrorHandled(value, contract, dynamicMemberName, null, writer.ContainerPath, ex2)) throw; HandleError(writer, top); } } writer.WriteEndObject(); _serializeStack.RemoveAt(_serializeStack.Count - 1); OnSerialized(writer, contract, value); } [System.Runtime.CompilerServices.NullableContext(2)] private bool ShouldWriteDynamicProperty(object memberValue) { if (Serializer._nullValueHandling == NullValueHandling.Ignore && memberValue == null) return false; if (HasFlag(Serializer._defaultValueHandling, DefaultValueHandling.Ignore) && (memberValue == null || MiscellaneousUtils.ValueEquals(memberValue, ReflectionUtils.GetDefaultValue(memberValue.GetType())))) return false; return true; } [System.Runtime.CompilerServices.NullableContext(2)] private bool ShouldWriteType(TypeNameHandling typeNameHandlingFlag, [System.Runtime.CompilerServices.Nullable(1)] JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerProperty) { TypeNameHandling value = member?.TypeNameHandling ?? containerProperty?.ItemTypeNameHandling ?? containerContract?.ItemTypeNameHandling ?? Serializer._typeNameHandling; if (HasFlag(value, typeNameHandlingFlag)) return true; if (HasFlag(value, TypeNameHandling.Auto)) { if (member != null) { if ((object)contract.NonNullableUnderlyingType != member.PropertyContract.CreatedType) return true; } else if (containerContract != null) { if (containerContract.ItemContract == null || (object)contract.NonNullableUnderlyingType != containerContract.ItemContract.CreatedType) return true; } else if ((object)_rootType != null && _serializeStack.Count == _rootLevel) { JsonContract jsonContract = Serializer._contractResolver.ResolveContract(_rootType); if ((object)contract.NonNullableUnderlyingType != jsonContract.CreatedType) return true; } } return false; } private void SerializeDictionary(JsonWriter writer, IDictionary values, JsonDictionaryContract contract, [System.Runtime.CompilerServices.Nullable(2)] JsonProperty member, [System.Runtime.CompilerServices.Nullable(2)] JsonContainerContract collectionContract, [System.Runtime.CompilerServices.Nullable(2)] JsonProperty containerProperty) { IWrappedDictionary wrappedDictionary = values as IWrappedDictionary; object obj = (wrappedDictionary != null) ? wrappedDictionary.UnderlyingDictionary : values; OnSerializing(writer, contract, obj); _serializeStack.Add(obj); WriteObjectStart(writer, obj, contract, member, collectionContract, containerProperty); if (contract.ItemContract == null) contract.ItemContract = Serializer._contractResolver.ResolveContract(contract.DictionaryValueType ?? typeof(object)); if (contract.KeyContract == null) contract.KeyContract = Serializer._contractResolver.ResolveContract(contract.DictionaryKeyType ?? typeof(object)); int top = writer.Top; IDictionaryEnumerator enumerator = values.GetEnumerator(); try { while (enumerator.MoveNext()) { DictionaryEntry entry = enumerator.Entry; string propertyName = GetPropertyName(writer, entry.Key, contract.KeyContract, out bool escape); propertyName = ((contract.DictionaryKeyResolver != null) ? contract.DictionaryKeyResolver(propertyName) : propertyName); try { object value = entry.Value; JsonContract jsonContract = contract.FinalItemContract ?? GetContractSafe(value); if (ShouldWriteReference(value, null, jsonContract, contract, member)) { writer.WritePropertyName(propertyName, escape); WriteReference(writer, value); } else if (CheckForCircularReference(writer, value, null, jsonContract, contract, member)) { writer.WritePropertyName(propertyName, escape); SerializeValue(writer, value, jsonContract, null, contract, member); } } catch (Exception ex) { if (!IsErrorHandled(obj, contract, propertyName, null, writer.ContainerPath, ex)) throw; HandleError(writer, top); } } } finally { (enumerator as IDisposable)?.Dispose(); } writer.WriteEndObject(); _serializeStack.RemoveAt(_serializeStack.Count - 1); OnSerialized(writer, contract, obj); } private string GetPropertyName(JsonWriter writer, object name, JsonContract contract, out bool escape) { if (contract.ContractType == JsonContractType.Primitive) { JsonPrimitiveContract jsonPrimitiveContract = (JsonPrimitiveContract)contract; switch (jsonPrimitiveContract.TypeCode) { case PrimitiveTypeCode.DateTime: case PrimitiveTypeCode.DateTimeNullable: { DateTime value = DateTimeUtils.EnsureDateTime((DateTime)name, writer.DateTimeZoneHandling); escape = false; StringWriter stringWriter2 = new StringWriter(CultureInfo.InvariantCulture); DateTimeUtils.WriteDateTimeString(stringWriter2, value, writer.DateFormatHandling, writer.DateFormatString, writer.Culture); return stringWriter2.ToString(); } case PrimitiveTypeCode.DateTimeOffset: case PrimitiveTypeCode.DateTimeOffsetNullable: { escape = false; StringWriter stringWriter = new StringWriter(CultureInfo.InvariantCulture); DateTimeUtils.WriteDateTimeOffsetString(stringWriter, (DateTimeOffset)name, writer.DateFormatHandling, writer.DateFormatString, writer.Culture); return stringWriter.ToString(); } case PrimitiveTypeCode.Double: case PrimitiveTypeCode.DoubleNullable: { double num = (double)name; escape = false; return num.ToString("R", CultureInfo.InvariantCulture); } case PrimitiveTypeCode.Single: case PrimitiveTypeCode.SingleNullable: { float num2 = (float)name; escape = false; return num2.ToString("R", CultureInfo.InvariantCulture); } default: escape = true; if (jsonPrimitiveContract.IsEnum && EnumUtils.TryToString(jsonPrimitiveContract.NonNullableUnderlyingType, name, null, out string name2)) return name2; return Convert.ToString(name, CultureInfo.InvariantCulture); } } if (TryConvertToString(name, name.GetType(), out string s)) { escape = true; return s; } escape = true; return name.ToString(); } private void HandleError(JsonWriter writer, int initialDepth) { ClearErrorContext(); if (writer.WriteState == WriteState.Property) writer.WriteNull(); while (writer.Top > initialDepth) { writer.WriteEnd(); } } private bool ShouldSerialize(JsonWriter writer, JsonProperty property, object target) { if (property.ShouldSerialize == null) return true; bool flag = property.ShouldSerialize(target); if (TraceWriter != null && TraceWriter.LevelFilter >= TraceLevel.Verbose) TraceWriter.Trace(TraceLevel.Verbose, JsonPosition.FormatMessage(null, writer.Path, "ShouldSerialize result for property '{0}' on {1}: {2}".FormatWith(CultureInfo.InvariantCulture, property.PropertyName, property.DeclaringType, flag)), null); return flag; } private bool IsSpecified(JsonWriter writer, JsonProperty property, object target) { if (property.GetIsSpecified == null) return true; bool flag = property.GetIsSpecified(target); if (TraceWriter != null && TraceWriter.LevelFilter >= TraceLevel.Verbose) TraceWriter.Trace(TraceLevel.Verbose, JsonPosition.FormatMessage(null, writer.Path, "IsSpecified result for property '{0}' on {1}: {2}".FormatWith(CultureInfo.InvariantCulture, property.PropertyName, property.DeclaringType, flag)), null); return flag; } } }