/// <summary> /// Copies the options from a <see cref="JsonSerializerOptions"/> instance to a new instance. /// </summary> /// <param name="options">The <see cref="JsonSerializerOptions"/> instance to copy options from.</param> /// <exception cref="System.ArgumentNullException"> /// <paramref name="options"/> is <see langword="null"/>. /// </exception> public JsonSerializerOptions(JsonSerializerOptions options) { if (options == null) { throw new ArgumentNullException(nameof(options)); } _memberAccessorStrategy = options._memberAccessorStrategy; _dictionaryKeyPolicy = options._dictionaryKeyPolicy; _jsonPropertyNamingPolicy = options._jsonPropertyNamingPolicy; _readCommentHandling = options._readCommentHandling; _referenceHandler = options._referenceHandler; _encoder = options._encoder; _defaultIgnoreCondition = options._defaultIgnoreCondition; _numberHandling = options._numberHandling; _defaultBufferSize = options._defaultBufferSize; _maxDepth = options._maxDepth; _allowTrailingCommas = options._allowTrailingCommas; _ignoreNullValues = options._ignoreNullValues; _ignoreReadOnlyProperties = options._ignoreReadOnlyProperties; _ignoreReadonlyFields = options._ignoreReadonlyFields; _includeFields = options._includeFields; _propertyNameCaseInsensitive = options._propertyNameCaseInsensitive; _writeIndented = options._writeIndented; Converters = new ConverterList(this, (ConverterList)options.Converters); EffectiveMaxDepth = options.EffectiveMaxDepth; // _classes is not copied as sharing the JsonClassInfo and JsonPropertyInfo caches can result in // unnecessary references to type metadata, potentially hindering garbage collection on the source options. // _haveTypesBeenCreated is not copied; it's okay to make changes to this options instance as (de)serialization has not occurred. }
internal static bool IsValidNumberHandlingValue(JsonNumberHandling handling) => JsonHelpers.IsInRangeInclusive((int)handling, 0, (int)( JsonNumberHandling.Strict | JsonNumberHandling.AllowReadingFromString | JsonNumberHandling.WriteAsString | JsonNumberHandling.AllowNamedFloatingPointLiterals));
/// <summary> /// Creates serialization metadata for an object. /// </summary> public JsonTypeInfoInternal( JsonSerializerOptions options, Func <T>?createObjectFunc, Func <JsonSerializerContext, JsonPropertyInfo[]>?propInitFunc, JsonNumberHandling numberHandling, Action <Utf8JsonWriter, T>?serializeFunc ) : base(typeof(T), options, ConverterStrategy.Object) { if (propInitFunc == null && serializeFunc == null) { ThrowHelper.ThrowInvalidOperationException_PropInitAndSerializeFuncsNull(); } #pragma warning disable CS8714 // The type cannot be used as type parameter in the generic type or method. // Nullability of type argument doesn't match 'notnull' constraint. JsonConverter converter = new JsonMetadataServicesConverter <T>(() => new ObjectDefaultConverter <T>(), ConverterStrategy.Object, keyType: null, elementType: null); #pragma warning restore CS8714 PropertyInfoForTypeInfo = JsonMetadataServices.CreateJsonPropertyInfoForClassInfo(typeof(T), this, converter, Options); NumberHandling = numberHandling; PropInitFunc = propInitFunc; Serialize = serializeFunc; SetCreateObjectFunc(createObjectFunc); }
/// <summary> /// Initializes metadata for a class or struct. /// </summary> /// <typeparam name="T">The type of the class or struct</typeparam> /// <param name="info"></param> /// <param name="options"></param> /// <param name="createObjectFunc"></param> /// <param name="propInitFunc"></param> /// <param name="numberHandling"></param> /// <exception cref="ArgumentNullException">Thrown when <paramref name="options"/>, <paramref name="info"/>, or <paramref name="propInitFunc"/> is null.</exception> /// <exception cref="ArgumentException">Thrown when <paramref name="info"/>, does not represent a complex class or struct type.</exception> public static void InitializeObjectInfo <T>( JsonTypeInfo <T> info, JsonSerializerOptions options, Func <T>?createObjectFunc, Func <JsonSerializerContext, JsonPropertyInfo[]> propInitFunc, JsonNumberHandling numberHandling) where T : notnull { if (info == null) { throw new ArgumentNullException(nameof(info)); } if (info.PropertyInfoForTypeInfo != null) { // ConverterStrategy.Object is the only info type we won't have set PropertyInfoForTypeInfo for at this point. throw new ArgumentException(SR.InitializeTypeInfoAsObjectInvalid, nameof(info)); } if (options == null) { throw new ArgumentNullException(nameof(options)); } if (propInitFunc == null) { throw new ArgumentNullException(nameof(propInitFunc)); } ((JsonTypeInfoInternal <T>)info).InitializeAsObject(options, createObjectFunc, propInitFunc, numberHandling); Debug.Assert(info.PropertyInfoForTypeInfo !.ConverterStrategy == ConverterStrategy.Object); }
/// <summary> /// Creates metadata for a complex class or struct. /// </summary> /// <param name="options">The <see cref="JsonSerializerOptions"/> to initialize the metadata with.</param> /// <param name="createObjectFunc">Provides a mechanism to create an instance of the class or struct when deserializing.</param> /// <param name="propInitFunc">Provides a mechanism to initialize metadata for properties and fields of the class or struct.</param> /// <param name="serializeFunc">Provides a serialization implementation for instances of the class or struct which assumes options specified by <see cref="JsonSerializerOptionsAttribute"/>.</param> /// <param name="numberHandling">Specifies how number properties and fields should be processed when serializing and deserializing.</param> /// <typeparam name="T">The type of the class or struct.</typeparam> /// <exception cref="InvalidOperationException">Thrown when <paramref name="options"/> and <paramref name="propInitFunc"/> are both null.</exception> /// <returns>A <see cref="JsonTypeInfo{T}"/> instance representing the class or struct.</returns> public static JsonTypeInfo <T> CreateObjectInfo <T>( JsonSerializerOptions options, Func <T>?createObjectFunc, Func <JsonSerializerContext, JsonPropertyInfo[]>?propInitFunc, JsonNumberHandling numberHandling, Action <Utf8JsonWriter, T>?serializeFunc) where T : notnull => new JsonTypeInfoInternal <T>(options, createObjectFunc, propInitFunc, numberHandling, serializeFunc);
/// <summary> /// Creates metadata for a property or field. /// </summary> /// <typeparam name="T">The type that the converter for the property returns or accepts when converting JSON data.</typeparam> /// <returns>A <see cref="JsonPropertyInfo"/> instance intialized with the provided metadata.</returns> public static JsonPropertyInfo CreatePropertyInfo <T>( JsonSerializerOptions options, bool isProperty, Type declaringType, JsonTypeInfo propertyTypeInfo, JsonConverter <T>?converter, Func <object, T>?getter, Action <object, T>?setter, JsonIgnoreCondition ignoreCondition, JsonNumberHandling numberHandling, string propertyName, JsonEncodedText jsonPropertyName) { if (options == null) { throw new ArgumentNullException(nameof(options)); } if (declaringType == null) { throw new ArgumentNullException(nameof(declaringType)); } if (propertyTypeInfo == null) { throw new ArgumentNullException(nameof(propertyTypeInfo)); } if (propertyName == null) { throw new ArgumentNullException(propertyName); } if (converter == null) { converter = propertyTypeInfo.PropertyInfoForTypeInfo.ConverterBase as JsonConverter <T>; if (converter == null) { throw new InvalidOperationException(SR.Format(SR.ConverterForPropertyMustBeValid, declaringType, propertyName, typeof(T))); } } JsonPropertyInfo <T> jsonPropertyInfo = new JsonPropertyInfo <T>(); jsonPropertyInfo.InitializeForSourceGen( options, isProperty, declaringType, propertyTypeInfo, converter, getter, setter, ignoreCondition, numberHandling, propertyName, jsonPropertyName); return(jsonPropertyInfo); }
/// <summary> /// Initializes a new instance of <see cref="JsonNumberHandlingAttribute"/>. /// </summary> public JsonNumberHandlingAttribute(JsonNumberHandling handling) { if (!JsonSerializer.IsValidNumberHandlingValue(handling)) { throw new ArgumentOutOfRangeException(nameof(handling)); } Handling = handling; }
/// <summary> /// Creates metadata for an array. /// </summary> /// <typeparam name="TElement">The generic definition of the element type.</typeparam> /// <param name="options">The <see cref="JsonSerializerOptions"/> to use.</param> /// <param name="elementInfo">A <see cref="JsonTypeInfo"/> instance representing the element type.</param> /// <param name="numberHandling">The <see cref="JsonNumberHandling"/> option to apply to number collection elements.</param> /// <returns></returns> public static JsonTypeInfo <TElement[]> CreateArrayInfo <TElement>( JsonSerializerOptions options, JsonTypeInfo elementInfo, JsonNumberHandling numberHandling) => new JsonTypeInfoInternal <TElement[]>( options, createObjectFunc: null, new ArrayConverter <TElement[], TElement>(), elementInfo, numberHandling);
#pragma warning disable CS1574 // XML comment has cref attribute that could not be resolved /// <summary> /// Creates metadata for <see cref="System.Collections.Immutable.ImmutableDictionary{TKey, TValue}"/> and /// types assignable to <see cref="System.Collections.Immutable.IImmutableDictionary{TKey, TValue}"/>. /// </summary> /// <typeparam name="TCollection">The generic definition of the type.</typeparam> /// <typeparam name="TKey">The generic definition of the key type.</typeparam> /// <typeparam name="TValue">The generic definition of the value type.</typeparam> /// <param name="options"></param> /// <param name="createObjectFunc">A <see cref="Func{TResult}"/> to create an instance of the list when deserializing.</param> /// <param name="keyInfo">A <see cref="JsonTypeInfo"/> instance representing the key type.</param> /// <param name="valueInfo">A <see cref="JsonTypeInfo"/> instance representing the value type.</param> /// <param name="numberHandling">The <see cref="JsonNumberHandling"/> option to apply to number collection elements.</param> /// <param name="serializeFunc">An optimized serialization implementation assuming pre-determined <see cref="JsonSourceGenerationOptionsAttribute"/> defaults.</param> /// <param name="createRangeFunc">A method to create an immutable dictionary instance.</param> /// <returns></returns> #pragma warning restore CS1574 // XML comment has cref attribute that could not be resolved public static JsonTypeInfo <TCollection> CreateImmutableDictionaryInfo <TCollection, TKey, TValue>( JsonSerializerOptions options, Func <TCollection> createObjectFunc, JsonTypeInfo keyInfo, JsonTypeInfo valueInfo, JsonNumberHandling numberHandling, Action <Utf8JsonWriter, TCollection>?serializeFunc, Func <IEnumerable <KeyValuePair <TKey, TValue> >, TCollection> createRangeFunc) where TCollection : IReadOnlyDictionary <TKey, TValue> where TKey : notnull => new JsonTypeInfoInternal <TCollection>(
/// <summary> /// Initializes a new instance of <see cref="JsonNumberHandlingAttribute"/>. /// </summary> public JsonNumberHandlingAttribute(JsonNumberHandling handling) { var handlingValue = (int)handling; if (handlingValue < 0 || 7 < handlingValue) { throw new ArgumentOutOfRangeException(nameof(handling)); } Handling = handling; }
internal override T?ReadNumberWithCustomHandling(ref Utf8JsonReader reader, JsonNumberHandling numberHandling, JsonSerializerOptions options) { if (reader.TokenType == JsonTokenType.Null) { return(null); } T value = _elementConverter.ReadNumberWithCustomHandling(ref reader, numberHandling, options); return(value); }
/// <summary> /// Creates metadata for types assignable to <see cref="List{T}"/>. /// </summary> /// <typeparam name="TCollection">The generic definition of the type.</typeparam> /// <typeparam name="TElement">The generic definition of the element type.</typeparam> /// <param name="options"></param> /// <param name="createObjectFunc">A <see cref="Func{TResult}"/> to create an instance of the list when deserializing.</param> /// <param name="elementInfo">A <see cref="JsonTypeInfo"/> instance representing the element type.</param> /// <param name="numberHandling">The <see cref="JsonNumberHandling"/> option to apply to number collection elements.</param> /// <returns></returns> public static JsonTypeInfo <TCollection> CreateListInfo <TCollection, TElement>( JsonSerializerOptions options, Func <TCollection>?createObjectFunc, JsonTypeInfo elementInfo, JsonNumberHandling numberHandling) where TCollection : List <TElement> => new JsonTypeInfoInternal <TCollection>( options, createObjectFunc, new ListOfTConverter <TCollection, TElement>(), elementInfo, numberHandling);
internal override T?ReadNumberWithCustomHandling(ref Utf8JsonReader reader, JsonNumberHandling numberHandling) { // We do not check _converter.HandleNull, as the underlying struct cannot be null. // A custom converter for some type T? can handle null. if (reader.TokenType == JsonTokenType.Null) { return(null); } T value = _converter.ReadNumberWithCustomHandling(ref reader, numberHandling); return(value); }
/// <summary> /// Creates metadata for an array. /// </summary> /// <typeparam name="TElement">The generic definition of the element type.</typeparam> /// <param name="options">The <see cref="JsonSerializerOptions"/> to use.</param> /// <param name="elementInfo">A <see cref="JsonTypeInfo"/> instance representing the element type.</param> /// <param name="numberHandling">The <see cref="JsonNumberHandling"/> option to apply to number collection elements.</param> /// <param name="serializeFunc">An optimized serialization implementation assuming pre-determined <see cref="JsonSourceGenerationOptionsAttribute"/> defaults.</param> /// <returns></returns> public static JsonTypeInfo <TElement[]> CreateArrayInfo <TElement>( JsonSerializerOptions options, JsonTypeInfo elementInfo, JsonNumberHandling numberHandling, Action <Utf8JsonWriter, TElement[]>?serializeFunc) => new JsonTypeInfoInternal <TElement[]>( options, createObjectFunc: null, () => new ArrayConverter <TElement[], TElement>(), elementInfo, numberHandling, serializeFunc, typeof(TElement));
/// <summary> /// Constructs a new <see cref="JsonSerializerOptions"/> instance with a predefined set of options determined by the specified <see cref="JsonSerializerDefaults"/>. /// </summary> /// <param name="defaults"> The <see cref="JsonSerializerDefaults"/> to reason about.</param> public JsonSerializerOptions(JsonSerializerDefaults defaults) : this() { if (defaults == JsonSerializerDefaults.Web) { _propertyNameCaseInsensitive = true; _jsonPropertyNamingPolicy = JsonNamingPolicy.CamelCase; _numberHandling = JsonNumberHandling.AllowReadingFromString; } else if (defaults != JsonSerializerDefaults.General) { throw new ArgumentOutOfRangeException(nameof(defaults)); } }
/// <summary> /// Creates metadata for types assignable to <see cref="List{T}"/>. /// </summary> /// <typeparam name="TCollection">The generic definition of the type.</typeparam> /// <typeparam name="TElement">The generic definition of the element type.</typeparam> /// <param name="options"></param> /// <param name="createObjectFunc">A <see cref="Func{TResult}"/> to create an instance of the list when deserializing.</param> /// <param name="elementInfo">A <see cref="JsonTypeInfo"/> instance representing the element type.</param> /// <param name="numberHandling">The <see cref="JsonNumberHandling"/> option to apply to number collection elements.</param> /// <param name="serializeFunc">An optimized serialization implementation assuming pre-determined <see cref="JsonSourceGenerationOptionsAttribute"/> defaults.</param> /// <returns></returns> public static JsonTypeInfo <TCollection> CreateListInfo <TCollection, TElement>( JsonSerializerOptions options, Func <TCollection>?createObjectFunc, JsonTypeInfo elementInfo, JsonNumberHandling numberHandling, Action <Utf8JsonWriter, TCollection>?serializeFunc) where TCollection : List <TElement> => new JsonTypeInfoInternal <TCollection>( options, createObjectFunc, () => new ListOfTConverter <TCollection, TElement>(), elementInfo, numberHandling, serializeFunc, typeof(TElement));
/// <summary> /// Creates metadata for types assignable to <see cref="Dictionary{TKey, TValue}"/>. /// </summary> /// <typeparam name="TCollection">The generic definition of the type.</typeparam> /// <typeparam name="TKey">The generic definition of the key type.</typeparam> /// <typeparam name="TValue">The generic definition of the value type.</typeparam> /// <param name="options"></param> /// <param name="createObjectFunc">A <see cref="Func{TResult}"/> to create an instance of the list when deserializing.</param> /// <param name="keyInfo">A <see cref="JsonTypeInfo"/> instance representing the key type.</param> /// <param name="valueInfo">A <see cref="JsonTypeInfo"/> instance representing the value type.</param> /// <param name="numberHandling">The <see cref="JsonNumberHandling"/> option to apply to number collection elements.</param> /// <returns></returns> public static JsonTypeInfo <TCollection> CreateDictionaryInfo <TCollection, TKey, TValue>( JsonSerializerOptions options, Func <TCollection> createObjectFunc, JsonTypeInfo keyInfo, JsonTypeInfo valueInfo, JsonNumberHandling numberHandling) where TCollection : Dictionary <TKey, TValue> where TKey : notnull => new JsonTypeInfoInternal <TCollection>( options, createObjectFunc, new DictionaryOfTKeyTValueConverter <TCollection, TKey, TValue>(), keyInfo, valueInfo, numberHandling);
/// <summary> /// Creates serialization metadata for a <see cref="ConverterStrategy.Enumerable"/>. /// </summary> public JsonTypeInfoInternal( JsonSerializerOptions options, Func <T>?createObjectFunc, Func <JsonConverter <T> > converterCreator, JsonTypeInfo?elementInfo, JsonNumberHandling numberHandling, Action <Utf8JsonWriter, T>?serializeFunc, Type elementType) : base(typeof(T), options, ConverterStrategy.Enumerable) { JsonConverter <T> converter = new JsonMetadataServicesConverter <T>(converterCreator, ConverterStrategy.Enumerable, keyType: null, elementType); ElementType = converter.ElementType; ElementTypeInfo = elementInfo ?? throw new ArgumentNullException(nameof(elementInfo)); NumberHandling = numberHandling; PropertyInfoForTypeInfo = JsonMetadataServices.CreateJsonPropertyInfoForClassInfo(typeof(T), this, converter, options); Serialize = serializeFunc; SetCreateObjectFunc(createObjectFunc); }
/// <summary> /// Creates metadata for types assignable to <see cref="Dictionary{TKey, TValue}"/>. /// </summary> /// <typeparam name="TCollection">The generic definition of the type.</typeparam> /// <typeparam name="TKey">The generic definition of the key type.</typeparam> /// <typeparam name="TValue">The generic definition of the value type.</typeparam> /// <param name="options"></param> /// <param name="createObjectFunc">A <see cref="Func{TResult}"/> to create an instance of the list when deserializing.</param> /// <param name="keyInfo">A <see cref="JsonTypeInfo"/> instance representing the key type.</param> /// <param name="valueInfo">A <see cref="JsonTypeInfo"/> instance representing the value type.</param> /// <param name="numberHandling">The <see cref="JsonNumberHandling"/> option to apply to number collection elements.</param> /// <param name="serializeFunc">An optimized serialization implementation assuming pre-determined <see cref="JsonSourceGenerationOptionsAttribute"/> defaults.</param> /// <returns></returns> public static JsonTypeInfo <TCollection> CreateDictionaryInfo <TCollection, TKey, TValue>( JsonSerializerOptions options, Func <TCollection> createObjectFunc, JsonTypeInfo keyInfo, JsonTypeInfo valueInfo, JsonNumberHandling numberHandling, Action <Utf8JsonWriter, TCollection>?serializeFunc) where TCollection : Dictionary <TKey, TValue> where TKey : notnull => new JsonTypeInfoInternal <TCollection>( options, createObjectFunc, () => new DictionaryOfTKeyTValueConverter <TCollection, TKey, TValue>(), keyInfo, valueInfo, numberHandling, serializeFunc, typeof(TKey), typeof(TValue));
/// <summary> /// Copies the options from a <see cref="JsonSerializerOptions"/> instance to a new instance. /// </summary> /// <param name="options">The <see cref="JsonSerializerOptions"/> instance to copy options from.</param> /// <exception cref="System.ArgumentNullException"> /// <paramref name="options"/> is <see langword="null"/>. /// </exception> public JsonSerializerOptions(JsonSerializerOptions options) { if (options is null) { ThrowHelper.ThrowArgumentNullException(nameof(options)); } _memberAccessorStrategy = options._memberAccessorStrategy; _dictionaryKeyPolicy = options._dictionaryKeyPolicy; _jsonPropertyNamingPolicy = options._jsonPropertyNamingPolicy; _readCommentHandling = options._readCommentHandling; _referenceHandler = options._referenceHandler; _converters = new ConverterList(this, options._converters); _encoder = options._encoder; _defaultIgnoreCondition = options._defaultIgnoreCondition; _numberHandling = options._numberHandling; _unknownTypeHandling = options._unknownTypeHandling; _defaultBufferSize = options._defaultBufferSize; _maxDepth = options._maxDepth; _allowTrailingCommas = options._allowTrailingCommas; _ignoreNullValues = options._ignoreNullValues; _ignoreReadOnlyProperties = options._ignoreReadOnlyProperties; _ignoreReadonlyFields = options._ignoreReadonlyFields; _includeFields = options._includeFields; _propertyNameCaseInsensitive = options._propertyNameCaseInsensitive; _writeIndented = options._writeIndented; // Preserve backward compatibility with .NET 6 // This should almost certainly be changed, cf. https://github.com/dotnet/aspnetcore/issues/38720 _typeInfoResolver = options._typeInfoResolver is JsonSerializerContext ? null : options._typeInfoResolver; EffectiveMaxDepth = options.EffectiveMaxDepth; ReferenceHandlingStrategy = options.ReferenceHandlingStrategy; // _cachingContext is not copied as sharing the JsonTypeInfo and JsonPropertyInfo caches can result in // unnecessary references to type metadata, potentially hindering garbage collection on the source options. TrackOptionsInstance(this); }
internal override void WriteNumberWithCustomHandling(Utf8JsonWriter writer, uint value, JsonNumberHandling handling) { if ((JsonNumberHandling.WriteAsString & handling) != 0) { writer.WriteNumberValueAsString(value); } else { // For performance, lift up the writer implementation. writer.WriteNumberValue((ulong)value); } }
internal override uint ReadNumberWithCustomHandling(ref Utf8JsonReader reader, JsonNumberHandling handling, JsonSerializerOptions options) { if (reader.TokenType == JsonTokenType.String && (JsonNumberHandling.AllowReadingFromString & handling) != 0) { return(reader.GetUInt32WithQuotes()); } return(reader.GetUInt32()); }
internal override void WriteNumberWithCustomHandling(Utf8JsonWriter writer, T value, JsonNumberHandling handling) => _sourceConverter.WriteNumberWithCustomHandling(writer, CastOnWrite(value), handling);
internal override T ReadNumberWithCustomHandling(ref Utf8JsonReader reader, JsonNumberHandling handling, JsonSerializerOptions options) => CastOnRead(_sourceConverter.ReadNumberWithCustomHandling(ref reader, handling, options));
internal void InitializeForSourceGen( JsonSerializerOptions options, bool isProperty, Type declaringType, JsonTypeInfo typeInfo, JsonConverter <T> converter, Func <object, T>?getter, Action <object, T>?setter, JsonIgnoreCondition ignoreCondition, JsonNumberHandling numberHandling, string propertyName, string?jsonPropertyName) { Options = options; ClrName = propertyName; // Property name settings. if (jsonPropertyName != null) { NameAsString = jsonPropertyName; } else if (options.PropertyNamingPolicy == null) { NameAsString = ClrName; } else { NameAsString = options.PropertyNamingPolicy.ConvertName(ClrName); if (NameAsString == null) { ThrowHelper.ThrowInvalidOperationException_SerializerPropertyNameNull(DeclaringType, this); } } NameAsUtf8Bytes ??= Encoding.UTF8.GetBytes(NameAsString !); EscapedNameSection ??= JsonHelpers.GetEscapedPropertyNameSection(NameAsUtf8Bytes, Options.Encoder); if (ignoreCondition == JsonIgnoreCondition.Always) { IsIgnored = true; Debug.Assert(!ShouldSerialize); Debug.Assert(!ShouldDeserialize); } else { Get = getter; Set = setter; HasGetter = Get != null; HasSetter = Set != null; ConverterBase = converter; RuntimeTypeInfo = typeInfo; DeclaredPropertyType = typeof(T); DeclaringType = declaringType; IgnoreCondition = ignoreCondition; MemberType = isProperty ? MemberTypes.Property : MemberTypes.Field; _converterIsExternalAndPolymorphic = !converter.IsInternalConverter && DeclaredPropertyType != converter.TypeToConvert; PropertyTypeCanBeNull = typeof(T).CanBeNull(); _propertyTypeEqualsTypeToConvert = converter.TypeToConvert == typeof(T); ConverterStrategy = Converter !.ConverterStrategy; RuntimePropertyType = DeclaredPropertyType; DetermineIgnoreCondition(IgnoreCondition); // TODO: this method needs to also take the number handling option for the declaring type. DetermineNumberHandlingForProperty(numberHandling, declaringTypeNumberHandling: null); DetermineSerializationCapabilities(IgnoreCondition); } }
internal override void WriteNumberWithCustomHandling(Utf8JsonWriter writer, T?value, JsonNumberHandling handling) { if (!value.HasValue) { // We do not check _converter.HandleNull, as the underlying struct cannot be null. // A custom converter for some type T? can handle null. writer.WriteNullValue(); } else { _converter.WriteNumberWithCustomHandling(writer, value.Value, handling); } }
internal override float ReadNumberWithCustomHandling(ref Utf8JsonReader reader, JsonNumberHandling handling, JsonSerializerOptions options) { if (reader.TokenType == JsonTokenType.String) { if ((JsonNumberHandling.AllowReadingFromString & handling) != 0) { return(reader.GetSingleWithQuotes()); } else if ((JsonNumberHandling.AllowNamedFloatingPointLiterals & handling) != 0) { return(reader.GetSingleFloatingPointConstant()); } } return(reader.GetSingle()); }
internal override decimal ReadNumberWithCustomHandling(ref Utf8JsonReader reader, JsonNumberHandling handling) { if (reader.TokenType == JsonTokenType.String && (JsonNumberHandling.AllowReadingFromString & handling) != 0) { return(reader.GetDecimalWithQuotes()); } return(reader.GetDecimal()); }
internal override void WriteNumberWithCustomHandling(Utf8JsonWriter writer, decimal value, JsonNumberHandling handling) { if ((JsonNumberHandling.WriteAsString & handling) != 0) { writer.WriteNumberValueAsString(value); } else { writer.WriteNumberValue(value); } }
internal override void WriteNumberWithCustomHandling(Utf8JsonWriter writer, float value, JsonNumberHandling handling) { if ((JsonNumberHandling.WriteAsString & handling) != 0) { writer.WriteNumberValueAsString(value); } else if ((JsonNumberHandling.AllowNamedFloatingPointLiterals & handling) != 0) { writer.WriteFloatingPointConstant(value); } else { writer.WriteNumberValue(value); } }