private bool SerializeWithoutCyclicLoop(IEnumerable collection, string format, IFormatProvider formatProvider, StringBuilder builder, bool withoutFormat, SingleItemOptimizedHashSet <object> objectsInPath, int depth) { if (objectsInPath.Contains(collection)) { return(false); // detected reference loop, skip serialization } if (depth > MaxRecursionDepth) { return(false); // reached maximum recursion level, no further serialization } IDictionary dictionary = collection as IDictionary; if (dictionary != null) { using (new SingleItemOptimizedHashSet <object> .SingleItemScopedInsert(dictionary, ref objectsInPath, true)) { return(SerializeDictionaryObject(dictionary, format, formatProvider, builder, withoutFormat, objectsInPath, depth)); } } using (new SingleItemOptimizedHashSet <object> .SingleItemScopedInsert(collection, ref objectsInPath, true)) { return(SerializeCollectionObject(collection, format, formatProvider, builder, withoutFormat, objectsInPath, depth)); } }
/// <summary> /// Serialization of the object in JSON format to the destination StringBuilder /// </summary> /// <param name="value">The object to serialize to JSON.</param> /// <param name="destination">Write the resulting JSON to this destination.</param> /// <param name="options">serialisation options</param> /// <param name="objectsInPath">The objects in path (Avoid cyclic reference loop).</param> /// <param name="depth">The current depth (level) of recursion.</param> /// <returns>Object serialized succesfully (true/false).</returns> private bool SerializeObject(object value, StringBuilder destination, JsonSerializeOptions options, SingleItemOptimizedHashSet <object> objectsInPath, int depth) { if (objectsInPath.Contains(value)) { return(false); // detected reference loop, skip serialization } if (depth > MaxRecursionDepth) { return(false); // reached maximum recursion level, no further serialization } if (value == null) { destination.Append("null"); } else if (value is string str) { QuoteValue(destination, EscapeString(str, options.EscapeUnicode)); } else if (value is IDictionary dict) { using (new SingleItemOptimizedHashSet <object> .SingleItemScopedInsert(dict, ref objectsInPath, true)) { SerializeDictionaryObject(dict, destination, options, objectsInPath, depth); } } else if (value is IEnumerable enumerable) { using (new SingleItemOptimizedHashSet <object> .SingleItemScopedInsert(value, ref objectsInPath, true)) { SerializeCollectionObject(enumerable, destination, options, objectsInPath, depth); } } else { var format = options.Format; var hasFormat = !StringHelpers.IsNullOrWhiteSpace(format); if ((options.FormatProvider != null || hasFormat) && (value is IFormattable formattable)) { if (!SerializeWithFormatProvider(value, destination, options, formattable, format, hasFormat)) { return(false); } } else { if (!SerializeTypeCodeValue(value, destination, options, objectsInPath, depth)) { return(false); } } } return(true); }
/// <summary> /// Serialization of the object in JSON format to the destination StringBuilder /// </summary> /// <param name="value">The object to serialize to JSON.</param> /// <param name="destination">Write the resulting JSON to this destination.</param> /// <param name="options">serialisation options</param> /// <param name="objectsInPath">The objects in path (Avoid cyclic reference loop).</param> /// <param name="depth">The current depth (level) of recursion.</param> /// <returns>Object serialized succesfully (true/false).</returns> private bool SerializeObject(object value, StringBuilder destination, JsonSerializeOptions options, SingleItemOptimizedHashSet <object> objectsInPath, int depth) { if (objectsInPath.Contains(value)) { return(false); // detected reference loop, skip serialization } if (value == null) { destination.Append("null"); } else if (value is string str) { destination.Append('"'); AppendStringEscape(destination, str, options.EscapeUnicode); destination.Append('"'); } else if (value is IDictionary dict) { using (StartScope(ref objectsInPath, dict)) { SerializeDictionaryObject(dict, destination, options, objectsInPath, depth); } } else if (value is IEnumerable enumerable) { using (StartScope(ref objectsInPath, value)) { SerializeCollectionObject(enumerable, destination, options, objectsInPath, depth); } } else { var format = options.Format; var hasFormat = !StringHelpers.IsNullOrWhiteSpace(format); if ((options.FormatProvider != null || hasFormat) && (value is IFormattable formattable)) { if (!SerializeWithFormatProvider(value, destination, options, formattable, format, hasFormat)) { return(false); } } else { if (!SerializeTypeCodeValue(value, destination, options, objectsInPath, depth)) { return(false); } } } return(true); }
private bool SerializeObjectWithReflection(object value, StringBuilder destination, JsonSerializeOptions options, ref SingleItemOptimizedHashSet <object> objectsInPath, int depth) { int originalLength = destination.Length; if (originalLength > MaxJsonLength) { return(false); } if (objectsInPath.Contains(value)) { return(false); } if (value is IDictionary dict) { using (StartCollectionScope(ref objectsInPath, dict)) { SerializeDictionaryObject(dict, destination, options, objectsInPath, depth); return(true); } } if (value is IEnumerable enumerable) { if (_objectReflectionCache.TryLookupExpandoObject(value, out var propertyValues)) { if (propertyValues.ConvertToString || depth >= options.MaxRecursionLimit) { return(SerializeObjectAsString(value, destination, options)); } else { using (new SingleItemOptimizedHashSet <object> .SingleItemScopedInsert(value, ref objectsInPath, false, _referenceEqualsComparer)) { return(SerializeObjectProperties(propertyValues, destination, options, objectsInPath, depth)); } } } using (StartCollectionScope(ref objectsInPath, value)) { SerializeCollectionObject(enumerable, destination, options, objectsInPath, depth); return(true); } } else { return(SerializeObjectWithProperties(value, destination, options, ref objectsInPath, depth)); } }
/// <summary> /// Serialization of the object in JSON format to the destination StringBuilder /// </summary> /// <param name="value">The object to serialize to JSON.</param> /// <param name="objTypeCode">The TypeCode for the object to serialize.</param> /// <param name="destination">Write the resulting JSON to this destination.</param> /// <param name="options">serialisation options</param> /// <param name="objectsInPath">The objects in path (Avoid cyclic reference loop).</param> /// <param name="depth">The current depth (level) of recursion.</param> /// <returns>Object serialized succesfully (true/false).</returns> private bool SerializeObject(object value, TypeCode objTypeCode, StringBuilder destination, JsonSerializeOptions options, SingleItemOptimizedHashSet <object> objectsInPath, int depth) { if (objTypeCode == TypeCode.Object && objectsInPath.Contains(value)) { return(false); // detected reference loop, skip serialization } if (value == null) { destination.Append("null"); } else if (objTypeCode == TypeCode.String) { destination.Append('"'); AppendStringEscape(destination, value.ToString(), options.EscapeUnicode); destination.Append('"'); } else if (objTypeCode != TypeCode.Object) { return(SerializeWithTypeCode(value, objTypeCode, destination, options, ref objectsInPath, depth)); } else if (value is IDictionary dict) { using (StartCollectionScope(ref objectsInPath, dict)) { SerializeDictionaryObject(dict, destination, options, objectsInPath, depth); } } else if (value is IDictionary <string, object> expando) { // Special case for Expando-objects using (StartCollectionScope(ref objectsInPath, expando)) { return(SerializeObjectProperties(new ObjectReflectionCache.ObjectPropertyList(expando), destination, options, objectsInPath, depth)); } } else if (value is IEnumerable enumerable) { using (StartCollectionScope(ref objectsInPath, value)) { SerializeCollectionObject(enumerable, destination, options, objectsInPath, depth); } } else { return(SerializeWithTypeCode(value, objTypeCode, destination, options, ref objectsInPath, depth)); } return(true); }