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)); } }
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); }
/// <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); }
private bool SerializeObjectProperties(ObjectReflectionCache.ObjectPropertyList objectPropertyList, StringBuilder destination, JsonSerializeOptions options, SingleItemOptimizedHashSet <object> objectsInPath, int depth) { if (objectPropertyList.Count == 0) { //no props return(SerializeObjectAsString(objectPropertyList.ToString(), TypeCode.Object, destination, options)); } 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(':'); if (!SerializeObject(propertyValue.Value, propertyValue.TypeCode, destination, options, objectsInPath, depth + 1)) { destination.Length = originalLength; } else { first = false; } } } catch { //skip this property destination.Length = originalLength; } } destination.Append('}'); 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); }
/// <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); }
/// <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 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 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 bool SerializeDictionaryObject(IDictionary dictionary, string format, IFormatProvider formatProvider, StringBuilder builder, bool withoutFormat, SingleItemOptimizedHashSet <object> objectsInPath, int depth) { bool separator = false; foreach (DictionaryEntry item in dictionary) { if (builder.Length > MaxValueLength) { return(false); } if (separator) { builder.Append(", "); } if (item.Key is string || !(item.Key is IEnumerable)) { SerializeObject(item.Key, format, formatProvider, builder); } else { SerializeWithoutCyclicLoop((IEnumerable)item.Key, format, formatProvider, builder, withoutFormat, objectsInPath, depth + 1); } builder.Append("="); if (item.Value is string || !(item.Value is IEnumerable)) { SerializeObject(item.Value, format, formatProvider, builder); } else { SerializeWithoutCyclicLoop((IEnumerable)item.Value, format, formatProvider, builder, withoutFormat, objectsInPath, depth + 1); } separator = true; } return(true); }
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('}'); }
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 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)); } else if (value is DateTimeOffset) { QuoteValue(destination, $"{value:yyyy-MM-dd HH:mm:ss zzz}"); } else { 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)) { return(SerializeProperties(value, destination, options, objectsInPath, depth)); } } catch { //nothing to add, so return is OK destination.Length = originalLength; return(false); } } else { try { string str = Convert.ToString(value, CultureInfo.InvariantCulture); destination.Append('"'); AppendStringEscape(destination, str, options.EscapeUnicode); destination.Append('"'); } catch { return(false); } } } } else { if (IsNumericTypeCode(objTypeCode, false)) { SerializeNumber(value, destination, options, 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 SerializeCollectionItem(object item, string format, IFormatProvider formatProvider, StringBuilder builder, ref SingleItemOptimizedHashSet <object> objectsInPath, int depth) { if (item is IConvertible convertible) { SerializeConvertibleObject(convertible, format, formatProvider, builder); } else if (item is IEnumerable enumerable) { SerializeWithoutCyclicLoop(enumerable, format, formatProvider, builder, objectsInPath, depth + 1); } else { SerializeSimpleObject(item, format, formatProvider, builder); } }
private bool SerializeWithTypeCode(object value, TypeCode objTypeCode, StringBuilder destination, JsonSerializeOptions options, ref SingleItemOptimizedHashSet <object> objectsInPath, int depth) { var hasFormat = !StringHelpers.IsNullOrWhiteSpace(options.Format); if ((options.FormatProvider != null || hasFormat) && (value is IFormattable formattable)) { return(SerializeWithFormatProvider(value, objTypeCode, destination, options, formattable, options.Format, hasFormat)); } else { if (objTypeCode == TypeCode.Object) { 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)); } } }
private bool SerializeCollectionObject(IEnumerable collection, string format, IFormatProvider formatProvider, StringBuilder builder, bool withoutFormat, SingleItemOptimizedHashSet <object> objectsInPath, int depth) { bool separator = false; foreach (var item in collection) { if (builder.Length > MaxValueLength) { return(false); } if (separator) { builder.Append(", "); } if (item is string || !(item is IEnumerable)) { SerializeObject(item, format, formatProvider, builder); } else { SerializeWithoutCyclicLoop((IEnumerable)item, format, formatProvider, builder, withoutFormat, objectsInPath, depth + 1); } separator = true; } 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)); } }
private bool SerializeCollectionObject(IEnumerable collection, string format, IFormatProvider formatProvider, StringBuilder builder, SingleItemOptimizedHashSet <object> objectsInPath, int depth) { bool separator = false; foreach (var item in collection) { if (builder.Length > MaxValueLength) { return(false); } if (separator) { builder.Append(", "); } SerializeCollectionItem(item, format, formatProvider, builder, ref objectsInPath, depth); separator = true; } return(true); }
private static SingleItemOptimizedHashSet <object> .SingleItemScopedInsert StartCollectionScope(ref SingleItemOptimizedHashSet <object> objectsInPath, object value) { return(new SingleItemOptimizedHashSet <object> .SingleItemScopedInsert(value, ref objectsInPath, true, _referenceEqualsComparer)); }
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 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 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 (originalLength > MaxJsonLength) { break; } 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 { 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(':'); if (!SerializeObject(de.Value, destination, options, objectsInPath, depth + 1)) { destination.Length = originalLength; } else { first = false; } } } destination.Append('}'); }
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> /// Serialize Dictionary as JSON like structure, without { and } /// </summary> /// <example> /// "FirstOrder"=true, "Previous login"=20-12-2017 14:55:32, "number of tries"=1 /// </example> /// <param name="dictionary"></param> /// <param name="format">formatstring of an item</param> /// <param name="formatProvider"></param> /// <param name="builder"></param> /// <param name="objectsInPath"></param> /// <param name="depth"></param> /// <returns></returns> private bool SerializeDictionaryObject(IDictionary dictionary, string format, IFormatProvider formatProvider, StringBuilder builder, SingleItemOptimizedHashSet <object> objectsInPath, int depth) { bool separator = false; foreach (var item in new DictionaryEntryEnumerable(dictionary)) { if (builder.Length > MaxValueLength) { return(false); } if (separator) { builder.Append(", "); } SerializeCollectionItem(item.Key, format, formatProvider, builder, ref objectsInPath, depth); builder.Append("="); SerializeCollectionItem(item.Value, format, formatProvider, builder, ref objectsInPath, depth); separator = true; } return(true); }