private bool SerializeTypeCodeValue(object value, StringBuilder destination, JsonSerializeOptions options, SingleItemOptimizedHashSet <object> objectsInPath, int depth) { TypeCode objTypeCode = Convert.GetTypeCode(value); if (objTypeCode == TypeCode.Object) { if (value is Guid || value is TimeSpan || value is MemberInfo || value is Assembly) { //object without property, to string QuoteValue(destination, Convert.ToString(value, CultureInfo.InvariantCulture)); return(true); } else if (value is DateTimeOffset) { QuoteValue(destination, $"{value:yyyy-MM-dd HH:mm:ss zzz}"); return(true); } else { return(SerializeObjectWithProperties(value, destination, options, ref objectsInPath, depth)); } } else { return(SerializeSimpleTypeCodeValue(value, objTypeCode, destination, options)); } }
/// <summary> /// Returns a serialization of an object into JSON format. /// </summary> /// <param name="value">The object to serialize to JSON.</param> /// <param name="options">serialisation options</param> /// <returns>Serialized value.</returns> public string SerializeObject(object value, JsonSerializeOptions options) { if (value == null) { return("null"); } else if (value is string str) { for (int i = 0; i < str.Length; ++i) { if (RequiresJsonEscape(str[i], options)) { StringBuilder sb = new StringBuilder(str.Length + 4); sb.Append('"'); AppendStringEscape(sb, str, options); sb.Append('"'); return(sb.ToString()); } } return(QuoteValue(str)); } else { IConvertible convertibleValue = value as IConvertible; TypeCode objTypeCode = convertibleValue?.GetTypeCode() ?? TypeCode.Object; if (objTypeCode != TypeCode.Object && objTypeCode != TypeCode.Char && StringHelpers.IsNullOrWhiteSpace(options.Format) && options.FormatProvider == null) { Enum enumValue; if (!options.EnumAsInteger && IsNumericTypeCode(objTypeCode, false) && (enumValue = value as Enum) != null) { return(QuoteValue(EnumAsString(enumValue))); } else { string xmlStr = XmlHelper.XmlConvertToString(convertibleValue, objTypeCode); if (SkipQuotes(convertibleValue, objTypeCode)) { return(xmlStr); } else { return(QuoteValue(xmlStr)); } } } else { StringBuilder sb = new StringBuilder(); if (!SerializeObject(value, sb, options)) { return(null); } return(sb.ToString()); } } }
/// <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 void SerializeNumber(object value, StringBuilder destination, JsonSerializeOptions options, TypeCode objTypeCode) { Enum enumValue; if (!options.EnumAsInteger && (enumValue = value as Enum) != null) { QuoteValue(destination, EnumAsString(enumValue)); } else { destination.AppendIntegerAsString(value, objTypeCode); } }
/// <summary> /// Returns a serialization of an object /// int JSON format. /// </summary> /// <param name="value">The object to serialize to JSON.</param> /// <param name="options">Options</param> /// <returns>Serialized value.</returns> public string SerializeObject(object value, JsonSerializeOptions options) { string str; if (value == null) { return("null"); } else if ((str = value as string) != null) { return(QuoteValue(EscapeString(str, options.EscapeUnicode))); } else { TypeCode objTypeCode = Convert.GetTypeCode(value); if (objTypeCode != TypeCode.Object && StringHelpers.IsNullOrWhiteSpace(options.Format) && options.FormatProvider == null) { Enum enumValue; if (!options.EnumAsInteger && IsNumericTypeCode(objTypeCode, false) && (enumValue = value as Enum) != null) { return(QuoteValue(EnumAsString(enumValue))); } else { str = XmlHelper.XmlConvertToString(value, objTypeCode); if (SkipQuotes(objTypeCode)) { return(str); } else { return(QuoteValue(str)); } } } else { StringBuilder sb = new StringBuilder(); if (!SerializeObject(value, sb, options)) { return(null); } return(sb.ToString()); } } }
/// <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 successfully (true/false).</returns> private bool SerializeObject(object value, StringBuilder destination, JsonSerializeOptions options, SingleItemOptimizedHashSet <object> objectsInPath, int depth) { int originalLength = destination.Length; try { if (SerializeSimpleObjectValue(value, destination, options)) { return(true); } return(SerializeObjectWithReflection(value, destination, options, ref objectsInPath, depth)); } catch { destination.Length = originalLength; return(false); } }
private void SerializeCollectionObject(IEnumerable value, StringBuilder destination, JsonSerializeOptions options, SingleItemOptimizedHashSet <object> objectsInPath, int depth) { bool first = true; int nextDepth = objectsInPath.Count <= 1 ? depth : (depth + 1); // Allow serialization of list-items if (nextDepth > options.MaxRecursionLimit) { destination.Append("[]"); return; } int originalLength; destination.Append('['); foreach (var val in value) { originalLength = destination.Length; if (originalLength > MaxJsonLength) { break; } if (!first) { destination.Append(','); } if (!SerializeObject(val, destination, options, objectsInPath, nextDepth)) { destination.Length = originalLength; } else { first = false; } } destination.Append(']'); }
private bool SerializeObjectWithProperties(object value, StringBuilder destination, JsonSerializeOptions options, ref SingleItemOptimizedHashSet <object> objectsInPath, int depth) { if (depth < options.MaxRecursionLimit) { var objectPropertyList = _objectReflectionCache.LookupObjectProperties(value); if (!objectPropertyList.ConvertToString) { if (ReferenceEquals(options, Instance._serializeOptions) && value is Exception) { // Exceptions are seldom under control, and can include random Data-Dictionary-keys, so we sanitize by default options = Instance._exceptionSerializeOptions; } using (new SingleItemOptimizedHashSet <object> .SingleItemScopedInsert(value, ref objectsInPath, false, _referenceEqualsComparer)) { return(SerializeObjectProperties(objectPropertyList, destination, options, objectsInPath, depth)); } } } return(SerializeObjectAsString(value, destination, options)); }
private bool SerializeWithFormatProvider(object value, StringBuilder destination, JsonSerializeOptions options, IFormattable formattable, string format, bool hasFormat) { int originalLength = destination.Length; try { TypeCode objTypeCode = Convert.GetTypeCode(value); bool includeQuotes = !SkipQuotes(objTypeCode); if (includeQuotes) { destination.Append('"'); } if (hasFormat) { var formatProvider = options.FormatProvider ?? _defaultFormatProvider; destination.AppendFormat(formatProvider, string.Concat("{0:", format, "}"), value); } else { //format provider passed without FormatProvider destination.Append(EscapeString(formattable.ToString("", options.FormatProvider), options.EscapeUnicode)); } if (includeQuotes) { destination.Append('"'); } return(true); } catch { destination.Length = originalLength; return(false); } }
private void SerializeDictionaryObject(IDictionary dictionary, StringBuilder destination, JsonSerializeOptions options, SingleItemOptimizedHashSet <object> objectsInPath, int depth) { bool first = true; int nextDepth = objectsInPath.Count <= 1 ? depth : (depth + 1); if (nextDepth > options.MaxRecursionLimit) { destination.Append("{}"); return; } destination.Append('{'); foreach (var item in new DictionaryEntryEnumerable(dictionary)) { var originalLength = destination.Length; if (originalLength > MaxJsonLength) { break; } if (!first) { destination.Append(','); } var itemKey = item.Key; if (options.QuoteKeys) { if (!SerializeObjectAsString(itemKey, destination, options)) { destination.Length = originalLength; continue; } } else { if (!SerializeObject(itemKey, destination, options, objectsInPath, nextDepth)) { destination.Length = originalLength; continue; } } if (options.SanitizeDictionaryKeys) { int quoteSkipCount = options.QuoteKeys ? 1 : 0; int keyEndIndex = destination.Length - quoteSkipCount; int keyStartIndex = originalLength + (first ? 0 : 1) + quoteSkipCount; if (!SanitizeDictionaryKey(destination, keyStartIndex, keyEndIndex - keyStartIndex)) { destination.Length = originalLength; // Empty keys are not allowed continue; } } destination.Append(':'); //only serialize, if key and value are serialized without error (e.g. due to reference loop) var itemValue = item.Value; if (!SerializeObject(itemValue, destination, options, objectsInPath, nextDepth)) { destination.Length = originalLength; } else { first = false; } } destination.Append('}'); }
internal static bool RequiresJsonEscape(char ch, JsonSerializeOptions options) { return(RequiresJsonEscape(ch, options.EscapeUnicode, options.EscapeForwardSlash)); }
private bool SerializeObjectAsString(object value, StringBuilder destination, JsonSerializeOptions options) { var originalLength = destination.Length; try { if (SerializeSimpleObjectValue(value, destination, options, true)) { return(true); } var hasFormat = !StringHelpers.IsNullOrWhiteSpace(options.Format); if ((options.FormatProvider != null || hasFormat) && (value is IFormattable formattable)) { SerializeWithFormatProvider(formattable, true, destination, options, hasFormat); return(true); } var str = Convert.ToString(value, CultureInfo.InvariantCulture); destination.Append('"'); AppendStringEscape(destination, str, options); destination.Append('"'); return(true); } catch { // skip bad object destination.Length = originalLength; return(false); } }
/// <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> /// <returns>Object serialized successfully (true/false).</returns> public bool SerializeObject(object value, StringBuilder destination, JsonSerializeOptions options) { return(SerializeObject(value, destination, options, default(SingleItemOptimizedHashSet <object>), 0)); }
private void SerializeSimpleNumericValue(IConvertible value, TypeCode objTypeCode, StringBuilder destination, JsonSerializeOptions options, bool forceToString) { if (!options.EnumAsInteger && value is Enum enumValue) { QuoteValue(destination, EnumAsString(enumValue)); } else { if (forceToString) { destination.Append('"'); } destination.AppendIntegerAsString(value, objTypeCode); if (forceToString) { destination.Append('"'); } } }
private bool SerializeProperties(object value, StringBuilder destination, JsonSerializeOptions options, SingleItemOptimizedHashSet <object> objectsInPath, int depth) { var props = GetProps(value); if (props.Key.Length == 0) { try { //no props QuoteValue(destination, EscapeString(Convert.ToString(value, CultureInfo.InvariantCulture), options.EscapeUnicode)); return(true); } catch { return(false); } } destination.Append('{'); bool first = true; int originalLength = 0; bool useLateBoundMethods = props.Key.Length == props.Value.Length; for (var i = 0; i < props.Key.Length; i++) { originalLength = destination.Length; try { var prop = props.Key[i]; var propValue = useLateBoundMethods ? props.Value[i](value, null) : prop.GetValue(value, null); if (propValue != null) { if (!first) { destination.Append(", "); } if (options.QuoteKeys) { QuoteValue(destination, prop.Name); } else { destination.Append(prop.Name); } destination.Append(':'); if (!SerializeObject(propValue, destination, options, objectsInPath, depth + 1)) { destination.Length = originalLength; } else { first = false; } } } catch { //skip this property destination.Length = originalLength; } } destination.Append('}'); return(true); }
private bool SerializeSimpleTypeCodeValue(object value, TypeCode objTypeCode, StringBuilder destination, JsonSerializeOptions options, bool forceQuotes = false) { if (objTypeCode == TypeCode.String || objTypeCode == TypeCode.Char) { destination.Append('"'); AppendStringEscape(destination, value.ToString(), options.EscapeUnicode); destination.Append('"'); } else if (IsNumericTypeCode(objTypeCode, false)) { if (!options.EnumAsInteger && value is Enum enumValue) { QuoteValue(destination, EnumAsString(enumValue)); } else { if (forceQuotes) { destination.Append('"'); } destination.AppendIntegerAsString(value, objTypeCode); if (forceQuotes) { destination.Append('"'); } } } else { string str = XmlHelper.XmlConvertToString(value, objTypeCode); if (str == null) { return(false); } if (!forceQuotes && SkipQuotes(value, objTypeCode)) { destination.Append(str); } else { QuoteValue(destination, str); } } return(true); }
private bool SerializeTypeCodeValue(object value, StringBuilder destination, JsonSerializeOptions options, SingleItemOptimizedHashSet <object> objectsInPath, int depth) { TypeCode objTypeCode = Convert.GetTypeCode(value); if (objTypeCode == TypeCode.Object) { if (value is Guid || value is TimeSpan) { //object without property, to string QuoteValue(destination, Convert.ToString(value, CultureInfo.InvariantCulture)); } else if (value is DateTimeOffset) { QuoteValue(destination, string.Format("{0:yyyy-MM-dd HH:mm:ss zzz}", value)); } else { int originalLength = destination.Length; try { using (new SingleItemOptimizedHashSet <object> .SingleItemScopedInsert(value, ref objectsInPath, false)) { return(SerializeProperties(value, destination, options, objectsInPath, depth)); } } catch { //nothing to add, so return is OK destination.Length = originalLength; return(false); } } } else { if (IsNumericTypeCode(objTypeCode, false)) { Enum enumValue; if (!options.EnumAsInteger && (enumValue = value as Enum) != null) { QuoteValue(destination, EnumAsString(enumValue)); } else { AppendIntegerAsString(destination, value, objTypeCode); } } else { string str = XmlHelper.XmlConvertToString(value, objTypeCode); if (str == null) { return(false); } if (SkipQuotes(objTypeCode)) { destination.Append(str); } else { QuoteValue(destination, str); } } } return(true); }
private void SerializeCollectionObject(IEnumerable value, StringBuilder destination, JsonSerializeOptions options, SingleItemOptimizedHashSet <object> objectsInPath, int depth) { bool first = true; int originalLength; destination.Append('['); foreach (var val in value) { originalLength = destination.Length; if (!first) { destination.Append(','); } if (!SerializeObject(val, destination, options, objectsInPath, depth + 1)) { destination.Length = originalLength; } else { first = false; } } destination.Append(']'); }
private void SerializeDictionaryObject(IDictionary value, StringBuilder destination, JsonSerializeOptions options, SingleItemOptimizedHashSet <object> objectsInPath, int depth) { bool first = true; int originalLength; destination.Append('{'); foreach (DictionaryEntry de in value) { originalLength = destination.Length; if (!first) { destination.Append(','); } //only serialize, if key and value are serialized without error (e.g. due to reference loop) if (!SerializeObject(de.Key, destination, options, objectsInPath, depth + 1)) { destination.Length = originalLength; } else { destination.Append(':'); if (!SerializeObject(de.Value, destination, options, objectsInPath, depth + 1)) { destination.Length = originalLength; } else { first = false; } } } destination.Append('}'); }
private void SerializeSimpleTypeCodeValue(IConvertible value, TypeCode objTypeCode, StringBuilder destination, JsonSerializeOptions options, bool forceToString = false) { if (objTypeCode == TypeCode.Empty || value == null) { destination.Append(forceToString ? "\"\"" : "null"); } else if (objTypeCode == TypeCode.String || objTypeCode == TypeCode.Char) { destination.Append('"'); AppendStringEscape(destination, value.ToString(), options); destination.Append('"'); } else { var hasFormat = !StringHelpers.IsNullOrWhiteSpace(options.Format); if ((options.FormatProvider != null || hasFormat) && (value is IFormattable formattable)) { bool includeQuotes = forceToString || objTypeCode == TypeCode.Object || !SkipQuotes(value, objTypeCode); SerializeWithFormatProvider(formattable, includeQuotes, destination, options, hasFormat); } else { SerializeSimpleTypeCodeValueNoEscape(value, objTypeCode, destination, options, forceToString); } } }
private bool SerializeObjectWithProperties(object value, StringBuilder destination, JsonSerializeOptions options, ref SingleItemOptimizedHashSet <object> objectsInPath, int depth) { int originalLength = destination.Length; if (originalLength > MaxJsonLength) { return(false); } if (depth < options.MaxRecursionLimit) { try { if (value is Exception && ReferenceEquals(options, instance._serializeOptions)) { // Exceptions are seldom under control, and can include random Data-Dictionary-keys, so we sanitize by default options = instance._exceptionSerializeOptions; } using (new SingleItemOptimizedHashSet <object> .SingleItemScopedInsert(value, ref objectsInPath, false, _referenceEqualsComparer)) { return(SerializeProperties(value, destination, options, objectsInPath, depth)); } } catch { //nothing to add, so return is OK destination.Length = originalLength; return(false); } } else { return(SerializeObjectAsString(value, TypeCode.Object, destination, options)); } }
private void SerializeSimpleTypeCodeValueNoEscape(IConvertible value, TypeCode objTypeCode, StringBuilder destination, JsonSerializeOptions options, bool forceToString) { if (IsNumericTypeCode(objTypeCode, false)) { SerializeSimpleNumericValue(value, objTypeCode, destination, options, forceToString); } else if (objTypeCode == TypeCode.DateTime) { destination.Append('"'); destination.AppendXmlDateTimeRoundTrip(value.ToDateTime(CultureInfo.InvariantCulture)); destination.Append('"'); } else { string str = XmlHelper.XmlConvertToString(value, objTypeCode); if (!forceToString && SkipQuotes(value, objTypeCode) && !string.IsNullOrEmpty(str)) { destination.Append(str); } else { QuoteValue(destination, str); } } }
private bool SerializeSimpleObjectValue(object value, StringBuilder destination, JsonSerializeOptions options, bool forceToString = false) { var convertibleValue = value as IConvertible; var objTypeCode = value == null ? TypeCode.Empty : (convertibleValue?.GetTypeCode() ?? TypeCode.Object); if (objTypeCode != TypeCode.Object) { SerializeSimpleTypeCodeValue(convertibleValue, objTypeCode, destination, options, forceToString); return(true); } if (value is DateTimeOffset) { QuoteValue(destination, $"{value:yyyy-MM-dd HH:mm:ss zzz}"); return(true); } return(false); // Not simple }
/// <summary> /// Checks input string if it needs JSON escaping, and makes necessary conversion /// </summary> /// <param name="destination">Destination Builder</param> /// <param name="text">Input string</param> /// <param name="options">all options</param> /// <returns>JSON escaped string</returns> private static void AppendStringEscape(StringBuilder destination, string text, JsonSerializeOptions options) { AppendStringEscape(destination, text, options.EscapeUnicode, options.EscapeForwardSlash); }
private bool SerializeSimpleObjectValue(object value, StringBuilder destination, JsonSerializeOptions options, bool forceToString = false) { var convertibleValue = value as IConvertible; var objTypeCode = value == null ? TypeCode.Empty : (convertibleValue?.GetTypeCode() ?? TypeCode.Object); if (objTypeCode != TypeCode.Object) { SerializeSimpleTypeCodeValue(convertibleValue, objTypeCode, destination, options, forceToString); return(true); } if (value is DateTimeOffset dateTimeOffset) { QuoteValue(destination, dateTimeOffset.ToString("yyyy-MM-dd HH:mm:ss zzz", CultureInfo.InvariantCulture)); return(true); } if (value is IFormattable formattable) { var hasFormat = !StringHelpers.IsNullOrWhiteSpace(options.Format); SerializeWithFormatProvider(formattable, true, destination, options, hasFormat); return(true); } return(false); // Not simple }
private bool SerializeObjectProperties(ObjectReflectionCache.ObjectPropertyList objectPropertyList, StringBuilder destination, JsonSerializeOptions options, SingleItemOptimizedHashSet <object> objectsInPath, int depth) { destination.Append('{'); bool first = true; foreach (var propertyValue in objectPropertyList) { var originalLength = destination.Length; try { if (HasNameAndValue(propertyValue)) { if (!first) { destination.Append(", "); } if (options.QuoteKeys) { QuoteValue(destination, propertyValue.Name); } else { destination.Append(propertyValue.Name); } destination.Append(':'); var objTypeCode = propertyValue.TypeCode; if (objTypeCode != TypeCode.Object) { SerializeSimpleTypeCodeValue((IConvertible)propertyValue.Value, objTypeCode, destination, options); first = false; } else { if (!SerializeObject(propertyValue.Value, destination, options, objectsInPath, depth + 1)) { destination.Length = originalLength; } else { first = false; } } } } catch { // skip single property destination.Length = originalLength; } } destination.Append('}'); return(true); }
private void SerializeWithFormatProvider(IFormattable formattable, bool includeQuotes, StringBuilder destination, JsonSerializeOptions options, bool hasFormat) { if (includeQuotes) { destination.Append('"'); } var formatProvider = options.FormatProvider ?? (hasFormat ? _defaultFormatProvider : null); var str = formattable.ToString(hasFormat ? options.Format : "", formatProvider); if (includeQuotes) { AppendStringEscape(destination, str, options); } else { destination.Append(str); } if (includeQuotes) { destination.Append('"'); } }
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)); } }
private bool SerializeObjectAsString(object value, TypeCode objTypeCode, StringBuilder destination, JsonSerializeOptions options) { try { if (objTypeCode == TypeCode.Object) { var str = Convert.ToString(value, CultureInfo.InvariantCulture); destination.Append('"'); AppendStringEscape(destination, str, options.EscapeUnicode); destination.Append('"'); return(true); } else { return(SerializeSimpleTypeCodeValue(value, objTypeCode, destination, options, true)); } } catch { return(false); } }