diff --git a/src/libraries/System.Text.Json/ref/System.Text.Json.cs b/src/libraries/System.Text.Json/ref/System.Text.Json.cs index 3cd4bb4959d28a..d4b05c6ea9f677 100644 --- a/src/libraries/System.Text.Json/ref/System.Text.Json.cs +++ b/src/libraries/System.Text.Json/ref/System.Text.Json.cs @@ -818,12 +818,14 @@ protected internal JsonConverter() { } public virtual bool HandleNull { get { throw null; } } public override bool CanConvert(System.Type typeToConvert) { throw null; } public abstract T? Read(ref System.Text.Json.Utf8JsonReader reader, System.Type typeToConvert, System.Text.Json.JsonSerializerOptions options); + public virtual T ReadAsPropertyName(ref System.Text.Json.Utf8JsonReader reader, System.Type typeToConvert, System.Text.Json.JsonSerializerOptions options) { throw null; } public abstract void Write( System.Text.Json.Utf8JsonWriter writer, #nullable disable T value, #nullable restore System.Text.Json.JsonSerializerOptions options); + public virtual void WriteAsPropertyName(System.Text.Json.Utf8JsonWriter writer, T value, System.Text.Json.JsonSerializerOptions options) { } } [System.AttributeUsageAttribute(System.AttributeTargets.Field | System.AttributeTargets.Property, AllowMultiple=false)] public sealed partial class JsonExtensionDataAttribute : System.Text.Json.Serialization.JsonAttribute diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/DictionaryDefaultConverter.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/DictionaryDefaultConverter.cs index 45e71830542e2b..330444d343eb73 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/DictionaryDefaultConverter.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/DictionaryDefaultConverter.cs @@ -55,7 +55,7 @@ protected internal override bool OnWriteResume( { state.Current.PropertyState = StackFramePropertyState.Name; TKey key = enumerator.Current.Key; - _keyConverter.WriteAsPropertyName(writer, key, options, ref state); + _keyConverter.WriteAsPropertyNameCore(writer, key, options, state.Current.IsWritingExtensionDataProperty); } TValue element = enumerator.Current.Value; diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/DictionaryOfTKeyTValueConverter.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/DictionaryOfTKeyTValueConverter.cs index 3620a683a51722..9927aff5ad6002 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/DictionaryOfTKeyTValueConverter.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/DictionaryOfTKeyTValueConverter.cs @@ -61,7 +61,7 @@ protected internal override bool OnWriteResume( do { TKey key = enumerator.Current.Key; - _keyConverter.WriteAsPropertyName(writer, key, options, ref state); + _keyConverter.WriteAsPropertyNameCore(writer, key, options, state.Current.IsWritingExtensionDataProperty); _valueConverter.Write(writer, enumerator.Current.Value, options); } while (enumerator.MoveNext()); } @@ -80,7 +80,7 @@ protected internal override bool OnWriteResume( state.Current.PropertyState = StackFramePropertyState.Name; TKey key = enumerator.Current.Key; - _keyConverter.WriteAsPropertyName(writer, key, options, ref state); + _keyConverter.WriteAsPropertyNameCore(writer, key, options, state.Current.IsWritingExtensionDataProperty); } TValue element = enumerator.Current.Value; diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/IDictionaryConverter.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/IDictionaryConverter.cs index 1d289ffa631a81..e8c658fb37f991 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/IDictionaryConverter.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/IDictionaryConverter.cs @@ -92,13 +92,13 @@ protected internal override bool OnWriteResume(Utf8JsonWriter writer, TDictionar if (key is string keyString) { _keyConverter ??= GetConverter(typeInfo.KeyTypeInfo!); - _keyConverter.WriteAsPropertyName(writer, keyString, options, ref state); + _keyConverter.WriteAsPropertyNameCore(writer, keyString, options, state.Current.IsWritingExtensionDataProperty); } else { // IDictionary is a special case since it has polymorphic object semantics on serialization // but needs to use JsonConverter on deserialization. - _valueConverter.WriteAsPropertyName(writer, key, options, ref state); + _valueConverter.WriteAsPropertyNameCore(writer, key, options, state.Current.IsWritingExtensionDataProperty); } } diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/JsonDictionaryConverter.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/JsonDictionaryConverter.cs index 5332d4e45dcac5..40e126914b1311 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/JsonDictionaryConverter.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/JsonDictionaryConverter.cs @@ -252,16 +252,17 @@ TKey ReadDictionaryKey(ref Utf8JsonReader reader, ref ReadStack state) TKey key; string unescapedPropertyNameAsString; + _keyConverter ??= GetConverter(state.Current.JsonTypeInfo.KeyTypeInfo!); + // Special case string to avoid calling GetString twice and save one allocation. - if (KeyType == typeof(string)) + if (_keyConverter.IsInternalConverter && KeyType == typeof(string)) { unescapedPropertyNameAsString = reader.GetString()!; key = (TKey)(object)unescapedPropertyNameAsString; } else { - _keyConverter ??= GetConverter(state.Current.JsonTypeInfo.KeyTypeInfo!); - key = _keyConverter.ReadAsPropertyName(ref reader, typeToConvert, options); + key = _keyConverter.ReadAsPropertyNameCore(ref reader, KeyType, options); unescapedPropertyNameAsString = reader.GetString()!; } diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Value/BooleanConverter.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Value/BooleanConverter.cs index 34b96144de1011..488769d49f10fb 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Value/BooleanConverter.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Value/BooleanConverter.cs @@ -17,7 +17,7 @@ public override void Write(Utf8JsonWriter writer, bool value, JsonSerializerOpti writer.WriteBooleanValue(value); } - internal override bool ReadAsPropertyName(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + internal override bool ReadAsPropertyNameCore(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { ReadOnlySpan propertyName = reader.GetSpan(); if (Utf8Parser.TryParse(propertyName, out bool value, out int bytesConsumed) @@ -29,7 +29,7 @@ internal override bool ReadAsPropertyName(ref Utf8JsonReader reader, Type typeTo throw ThrowHelper.GetFormatException(DataType.Boolean); } - internal override void WriteAsPropertyName(Utf8JsonWriter writer, bool value, JsonSerializerOptions options, ref WriteStack state) + internal override void WriteAsPropertyNameCore(Utf8JsonWriter writer, bool value, JsonSerializerOptions options, bool isWritingExtensionDataProperty) { writer.WritePropertyName(value); } diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Value/ByteConverter.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Value/ByteConverter.cs index 104dfb8c364b31..c927119345d937 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Value/ByteConverter.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Value/ByteConverter.cs @@ -20,12 +20,12 @@ public override void Write(Utf8JsonWriter writer, byte value, JsonSerializerOpti writer.WriteNumberValue(value); } - internal override byte ReadAsPropertyName(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + internal override byte ReadAsPropertyNameCore(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { return reader.GetByteWithQuotes(); } - internal override void WriteAsPropertyName(Utf8JsonWriter writer, byte value, JsonSerializerOptions options, ref WriteStack state) + internal override void WriteAsPropertyNameCore(Utf8JsonWriter writer, byte value, JsonSerializerOptions options, bool isWritingExtensionDataProperty) { writer.WritePropertyName(value); } diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Value/CharConverter.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Value/CharConverter.cs index 22d5ddfc370192..e4242836fe0918 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Value/CharConverter.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Value/CharConverter.cs @@ -28,10 +28,10 @@ public override void Write(Utf8JsonWriter writer, char value, JsonSerializerOpti ); } - internal override char ReadAsPropertyName(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + internal override char ReadAsPropertyNameCore(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) => Read(ref reader, typeToConvert, options); - internal override void WriteAsPropertyName(Utf8JsonWriter writer, char value, JsonSerializerOptions options, ref WriteStack state) + internal override void WriteAsPropertyNameCore(Utf8JsonWriter writer, char value, JsonSerializerOptions options, bool isWritingExtensionDataProperty) { writer.WritePropertyName( #if BUILDING_INBOX_LIBRARY diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Value/DateTimeConverter.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Value/DateTimeConverter.cs index e143baaee52255..85cb86b15e0cd8 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Value/DateTimeConverter.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Value/DateTimeConverter.cs @@ -15,12 +15,12 @@ public override void Write(Utf8JsonWriter writer, DateTime value, JsonSerializer writer.WriteStringValue(value); } - internal override DateTime ReadAsPropertyName(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + internal override DateTime ReadAsPropertyNameCore(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { return reader.GetDateTimeNoValidation(); } - internal override void WriteAsPropertyName(Utf8JsonWriter writer, DateTime value, JsonSerializerOptions options, ref WriteStack state) + internal override void WriteAsPropertyNameCore(Utf8JsonWriter writer, DateTime value, JsonSerializerOptions options, bool isWritingExtensionDataProperty) { writer.WritePropertyName(value); } diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Value/DateTimeOffsetConverter.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Value/DateTimeOffsetConverter.cs index 284e35706c11e7..82a6581be80e49 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Value/DateTimeOffsetConverter.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Value/DateTimeOffsetConverter.cs @@ -15,12 +15,12 @@ public override void Write(Utf8JsonWriter writer, DateTimeOffset value, JsonSeri writer.WriteStringValue(value); } - internal override DateTimeOffset ReadAsPropertyName(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + internal override DateTimeOffset ReadAsPropertyNameCore(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { return reader.GetDateTimeOffsetNoValidation(); } - internal override void WriteAsPropertyName(Utf8JsonWriter writer, DateTimeOffset value, JsonSerializerOptions options, ref WriteStack state) + internal override void WriteAsPropertyNameCore(Utf8JsonWriter writer, DateTimeOffset value, JsonSerializerOptions options, bool isWritingExtensionDataProperty) { writer.WritePropertyName(value); } diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Value/DecimalConverter.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Value/DecimalConverter.cs index d5881d9ba6a115..52c94458141bee 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Value/DecimalConverter.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Value/DecimalConverter.cs @@ -20,12 +20,12 @@ public override void Write(Utf8JsonWriter writer, decimal value, JsonSerializerO writer.WriteNumberValue(value); } - internal override decimal ReadAsPropertyName(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + internal override decimal ReadAsPropertyNameCore(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { return reader.GetDecimalWithQuotes(); } - internal override void WriteAsPropertyName(Utf8JsonWriter writer, decimal value, JsonSerializerOptions options, ref WriteStack state) + internal override void WriteAsPropertyNameCore(Utf8JsonWriter writer, decimal value, JsonSerializerOptions options, bool isWritingExtensionDataProperty) { writer.WritePropertyName(value); } diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Value/DoubleConverter.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Value/DoubleConverter.cs index b62a4234811bf6..34499fb350042a 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Value/DoubleConverter.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Value/DoubleConverter.cs @@ -20,12 +20,12 @@ public override void Write(Utf8JsonWriter writer, double value, JsonSerializerOp writer.WriteNumberValue(value); } - internal override double ReadAsPropertyName(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + internal override double ReadAsPropertyNameCore(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { return reader.GetDoubleWithQuotes(); } - internal override void WriteAsPropertyName(Utf8JsonWriter writer, double value, JsonSerializerOptions options, ref WriteStack state) + internal override void WriteAsPropertyNameCore(Utf8JsonWriter writer, double value, JsonSerializerOptions options, bool isWritingExtensionDataProperty) { writer.WritePropertyName(value); } diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Value/EnumConverter.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Value/EnumConverter.cs index 088f41c09bfbd5..0fa5561f3f83d5 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Value/EnumConverter.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Value/EnumConverter.cs @@ -84,7 +84,7 @@ public override T Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerial return default; } - return ReadAsPropertyName(ref reader, typeToConvert, options); + return ReadAsPropertyNameCore(ref reader, typeToConvert, options); } if (token != JsonTokenType.Number || !_converterOptions.HasFlag(EnumConverterOptions.AllowNumbers)) @@ -304,7 +304,7 @@ private string FormatEnumValueToString(string value, JavaScriptEncoder? encoder) return converted; } - internal override T ReadAsPropertyName(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + internal override T ReadAsPropertyNameCore(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { string? enumString = reader.GetString(); @@ -318,7 +318,7 @@ internal override T ReadAsPropertyName(ref Utf8JsonReader reader, Type typeToCon return value; } - internal override void WriteAsPropertyName(Utf8JsonWriter writer, T value, JsonSerializerOptions options, ref WriteStack state) + internal override void WriteAsPropertyNameCore(Utf8JsonWriter writer, T value, JsonSerializerOptions options, bool isWritingExtensionDataProperty) { // An EnumConverter that invokes this method // can only be created by JsonSerializerOptions.GetDictionaryKeyConverter @@ -330,7 +330,7 @@ internal override void WriteAsPropertyName(Utf8JsonWriter writer, T value, JsonS // Try to obtain values from caches if (options.DictionaryKeyPolicy != null) { - Debug.Assert(!state.Current.IgnoreDictionaryKeyPolicy); + Debug.Assert(!isWritingExtensionDataProperty); if (_dictionaryKeyPolicyCache != null && _dictionaryKeyPolicyCache.TryGetValue(key, out JsonEncodedText formatted)) { @@ -344,7 +344,6 @@ internal override void WriteAsPropertyName(Utf8JsonWriter writer, T value, JsonS return; } - // if there are not cached values string original = value.ToString(); if (IsValidIdentifier(original)) diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Value/GuidConverter.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Value/GuidConverter.cs index 47e02730c257dc..b0c358b67aa762 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Value/GuidConverter.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Value/GuidConverter.cs @@ -15,12 +15,12 @@ public override void Write(Utf8JsonWriter writer, Guid value, JsonSerializerOpti writer.WriteStringValue(value); } - internal override Guid ReadAsPropertyName(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + internal override Guid ReadAsPropertyNameCore(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { return reader.GetGuidNoValidation(); } - internal override void WriteAsPropertyName(Utf8JsonWriter writer, Guid value, JsonSerializerOptions options, ref WriteStack state) + internal override void WriteAsPropertyNameCore(Utf8JsonWriter writer, Guid value, JsonSerializerOptions options, bool isWritingExtensionDataProperty) { writer.WritePropertyName(value); } diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Value/Int16Converter.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Value/Int16Converter.cs index 64ed4bd23bf386..2ada98b75c0841 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Value/Int16Converter.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Value/Int16Converter.cs @@ -21,12 +21,12 @@ public override void Write(Utf8JsonWriter writer, short value, JsonSerializerOpt writer.WriteNumberValue((long)value); } - internal override short ReadAsPropertyName(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + internal override short ReadAsPropertyNameCore(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { return reader.GetInt16WithQuotes(); } - internal override void WriteAsPropertyName(Utf8JsonWriter writer, short value, JsonSerializerOptions options, ref WriteStack state) + internal override void WriteAsPropertyNameCore(Utf8JsonWriter writer, short value, JsonSerializerOptions options, bool isWritingExtensionDataProperty) { writer.WritePropertyName(value); } diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Value/Int32Converter.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Value/Int32Converter.cs index 953cae3e63681f..49ba9d15f3cc37 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Value/Int32Converter.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Value/Int32Converter.cs @@ -21,12 +21,12 @@ public override void Write(Utf8JsonWriter writer, int value, JsonSerializerOptio writer.WriteNumberValue((long)value); } - internal override int ReadAsPropertyName(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + internal override int ReadAsPropertyNameCore(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { return reader.GetInt32WithQuotes(); } - internal override void WriteAsPropertyName(Utf8JsonWriter writer, int value, JsonSerializerOptions options, ref WriteStack state) + internal override void WriteAsPropertyNameCore(Utf8JsonWriter writer, int value, JsonSerializerOptions options, bool isWritingExtensionDataProperty) { writer.WritePropertyName(value); } diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Value/Int64Converter.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Value/Int64Converter.cs index 73f34118b39fe0..038deb5524705d 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Value/Int64Converter.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Value/Int64Converter.cs @@ -20,12 +20,12 @@ public override void Write(Utf8JsonWriter writer, long value, JsonSerializerOpti writer.WriteNumberValue(value); } - internal override long ReadAsPropertyName(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + internal override long ReadAsPropertyNameCore(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { return reader.GetInt64WithQuotes(); } - internal override void WriteAsPropertyName(Utf8JsonWriter writer, long value, JsonSerializerOptions options, ref WriteStack state) + internal override void WriteAsPropertyNameCore(Utf8JsonWriter writer, long value, JsonSerializerOptions options, bool isWritingExtensionDataProperty) { writer.WritePropertyName(value); } diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Value/ObjectConverter.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Value/ObjectConverter.cs index 740627cfd7499d..ddb2a899947b64 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Value/ObjectConverter.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Value/ObjectConverter.cs @@ -30,13 +30,13 @@ public override void Write(Utf8JsonWriter writer, object? value, JsonSerializerO writer.WriteEndObject(); } - internal override object ReadAsPropertyName(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + internal override object ReadAsPropertyNameCore(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { ThrowHelper.ThrowNotSupportedException_DictionaryKeyTypeNotSupported(TypeToConvert, this); return null!; } - internal override void WriteAsPropertyName(Utf8JsonWriter writer, object? value, JsonSerializerOptions options, ref WriteStack state) + internal override void WriteAsPropertyNameCore(Utf8JsonWriter writer, object? value, JsonSerializerOptions options, bool isWritingExtensionDataProperty) { // This converter does not handle nulls. Debug.Assert(value != null); @@ -48,7 +48,7 @@ internal override void WriteAsPropertyName(Utf8JsonWriter writer, object? value, ThrowHelper.ThrowNotSupportedException_DictionaryKeyTypeNotSupported(runtimeType, this); } - runtimeConverter.WriteAsPropertyNameAsObject(writer, value, options, ref state); + runtimeConverter.WriteAsPropertyNameCoreAsObject(writer, value, options, isWritingExtensionDataProperty); } internal override object? ReadNumberWithCustomHandling(ref Utf8JsonReader reader, JsonNumberHandling handling, JsonSerializerOptions options) diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Value/SByteConverter.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Value/SByteConverter.cs index 042ac8aedbe9a1..198ec2d9e6e9bd 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Value/SByteConverter.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Value/SByteConverter.cs @@ -20,12 +20,12 @@ public override void Write(Utf8JsonWriter writer, sbyte value, JsonSerializerOpt writer.WriteNumberValue(value); } - internal override sbyte ReadAsPropertyName(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + internal override sbyte ReadAsPropertyNameCore(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { return reader.GetSByteWithQuotes(); } - internal override void WriteAsPropertyName(Utf8JsonWriter writer, sbyte value, JsonSerializerOptions options, ref WriteStack state) + internal override void WriteAsPropertyNameCore(Utf8JsonWriter writer, sbyte value, JsonSerializerOptions options, bool isWritingExtensionDataProperty) { writer.WritePropertyName(value); } diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Value/SingleConverter.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Value/SingleConverter.cs index 4ec8bc843222d7..5ce4cf603016a7 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Value/SingleConverter.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Value/SingleConverter.cs @@ -21,12 +21,12 @@ public override void Write(Utf8JsonWriter writer, float value, JsonSerializerOpt writer.WriteNumberValue(value); } - internal override float ReadAsPropertyName(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + internal override float ReadAsPropertyNameCore(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { return reader.GetSingleWithQuotes(); } - internal override void WriteAsPropertyName(Utf8JsonWriter writer, float value, JsonSerializerOptions options, ref WriteStack state) + internal override void WriteAsPropertyNameCore(Utf8JsonWriter writer, float value, JsonSerializerOptions options, bool isWritingExtensionDataProperty) { writer.WritePropertyName(value); } diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Value/StringConverter.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Value/StringConverter.cs index c611e33562d8ba..a2ef84679e4267 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Value/StringConverter.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Value/StringConverter.cs @@ -23,14 +23,14 @@ public override void Write(Utf8JsonWriter writer, string? value, JsonSerializerO } } - internal override string ReadAsPropertyName(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + internal override string ReadAsPropertyNameCore(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { return reader.GetString()!; } - internal override void WriteAsPropertyName(Utf8JsonWriter writer, string value, JsonSerializerOptions options, ref WriteStack state) + internal override void WriteAsPropertyNameCore(Utf8JsonWriter writer, string value, JsonSerializerOptions options, bool isWritingExtensionDataProperty) { - if (options.DictionaryKeyPolicy != null && !state.Current.IgnoreDictionaryKeyPolicy) + if (options.DictionaryKeyPolicy != null && !isWritingExtensionDataProperty) { value = options.DictionaryKeyPolicy.ConvertName(value); diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Value/UInt16Converter.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Value/UInt16Converter.cs index 0c9040328afc91..0ac6a644faf760 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Value/UInt16Converter.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Value/UInt16Converter.cs @@ -21,12 +21,12 @@ public override void Write(Utf8JsonWriter writer, ushort value, JsonSerializerOp writer.WriteNumberValue((long)value); } - internal override ushort ReadAsPropertyName(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + internal override ushort ReadAsPropertyNameCore(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { return reader.GetUInt16WithQuotes(); } - internal override void WriteAsPropertyName(Utf8JsonWriter writer, ushort value, JsonSerializerOptions options, ref WriteStack state) + internal override void WriteAsPropertyNameCore(Utf8JsonWriter writer, ushort value, JsonSerializerOptions options, bool isWritingExtensionDataProperty) { writer.WritePropertyName(value); } diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Value/UInt32Converter.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Value/UInt32Converter.cs index 26f57e25f585af..c0d2a754ee062c 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Value/UInt32Converter.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Value/UInt32Converter.cs @@ -21,12 +21,12 @@ public override void Write(Utf8JsonWriter writer, uint value, JsonSerializerOpti writer.WriteNumberValue((ulong)value); } - internal override uint ReadAsPropertyName(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + internal override uint ReadAsPropertyNameCore(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { return reader.GetUInt32WithQuotes(); } - internal override void WriteAsPropertyName(Utf8JsonWriter writer, uint value, JsonSerializerOptions options, ref WriteStack state) + internal override void WriteAsPropertyNameCore(Utf8JsonWriter writer, uint value, JsonSerializerOptions options, bool isWritingExtensionDataProperty) { writer.WritePropertyName(value); } diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Value/UInt64Converter.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Value/UInt64Converter.cs index 64a27bad515d45..f63d9175abb390 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Value/UInt64Converter.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Value/UInt64Converter.cs @@ -20,12 +20,12 @@ public override void Write(Utf8JsonWriter writer, ulong value, JsonSerializerOpt writer.WriteNumberValue(value); } - internal override ulong ReadAsPropertyName(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + internal override ulong ReadAsPropertyNameCore(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { return reader.GetUInt64WithQuotes(); } - internal override void WriteAsPropertyName(Utf8JsonWriter writer, ulong value, JsonSerializerOptions options, ref WriteStack state) + internal override void WriteAsPropertyNameCore(Utf8JsonWriter writer, ulong value, JsonSerializerOptions options, bool isWritingExtensionDataProperty) { writer.WritePropertyName(value); } diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonConverter.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonConverter.cs index c326e7685fa832..4009905fe680db 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonConverter.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonConverter.cs @@ -107,7 +107,7 @@ internal bool ShouldFlush(Utf8JsonWriter writer, ref WriteStack state) /// /// Loosely-typed WriteToPropertyName() that forwards to strongly-typed WriteToPropertyName(). /// - internal abstract void WriteAsPropertyNameAsObject(Utf8JsonWriter writer, object value, JsonSerializerOptions options, ref WriteStack state); + internal abstract void WriteAsPropertyNameCoreAsObject(Utf8JsonWriter writer, object value, JsonSerializerOptions options, bool isWritingExtensionDataProperty); // Whether a type (ConverterStrategy.Object) is deserialized using a parameterized constructor. internal virtual bool ConstructorIsParameterized { get; } diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonConverterFactory.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonConverterFactory.cs index 2163562afb4ed8..58dffd334514d1 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonConverterFactory.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonConverterFactory.cs @@ -119,10 +119,10 @@ internal sealed override bool WriteCoreAsObject( throw new InvalidOperationException(); } - internal sealed override void WriteAsPropertyNameAsObject( + internal sealed override void WriteAsPropertyNameCoreAsObject( Utf8JsonWriter writer, object value, JsonSerializerOptions options, - ref WriteStack state) + bool isWritingExtensionDataProperty) { Debug.Fail("We should never get here."); diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonConverterOfT.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonConverterOfT.cs index 53f2afc5f45fe8..b222942ae22f65 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonConverterOfT.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonConverterOfT.cs @@ -528,8 +528,8 @@ internal bool TryWriteDataExtensionProperty(Utf8JsonWriter writer, T value, Json state.Current.OriginalDepth = writer.CurrentDepth; } - // Ignore the naming policy for extension data. - state.Current.IgnoreDictionaryKeyPolicy = true; + // Extension data properties change how dictionary key naming policies are applied. + state.Current.IsWritingExtensionDataProperty = true; state.Current.DeclaredJsonPropertyInfo = state.Current.JsonTypeInfo.ElementTypeInfo!.PropertyInfoForTypeInfo; success = dictionaryConverter.OnWriteResume(writer, value, options, ref state); @@ -621,34 +621,82 @@ public abstract void Write( #nullable restore JsonSerializerOptions options); - internal virtual T ReadAsPropertyName(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + /// + /// Reads a dictionary key from a JSON property name. + /// + /// The to read from. + /// The being converted. + /// The being used. + /// The value that was converted. + /// Method should be overridden in custom converters of types used in deserialized dictionary keys. + public virtual T ReadAsPropertyName(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { if (!IsInternalConverter && options.TryGetDefaultSimpleConverter(TypeToConvert, out JsonConverter? defaultConverter)) { // .NET 5 backward compatibility: hardcode the default converter for primitive key serialization. Debug.Assert(defaultConverter.IsInternalConverter && defaultConverter is JsonConverter); - return ((JsonConverter)defaultConverter).ReadAsPropertyName(ref reader, TypeToConvert, options); + return ((JsonConverter)defaultConverter).ReadAsPropertyNameCore(ref reader, TypeToConvert, options); } ThrowHelper.ThrowNotSupportedException_DictionaryKeyTypeNotSupported(TypeToConvert, this); return default; } - internal virtual void WriteAsPropertyName(Utf8JsonWriter writer, T value, JsonSerializerOptions options, ref WriteStack state) + internal virtual T ReadAsPropertyNameCore(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + { + Debug.Assert(reader.TokenType == JsonTokenType.PropertyName); + + long originalBytesConsumed = reader.BytesConsumed; + T result = ReadAsPropertyName(ref reader, typeToConvert, options); + if (reader.BytesConsumed != originalBytesConsumed) + { + ThrowHelper.ThrowJsonException_SerializationConverterRead(this); + } + + return result; + } + + /// + /// Writes a dictionary key as a JSON property name. + /// + /// The to write to. + /// The value to convert. Note that the value of determines if the converter handles values. + /// The being used. + /// Method should be overridden in custom converters of types used in serialized dictionary keys. + public virtual void WriteAsPropertyName(Utf8JsonWriter writer, T value, JsonSerializerOptions options) { if (!IsInternalConverter && options.TryGetDefaultSimpleConverter(TypeToConvert, out JsonConverter? defaultConverter)) { // .NET 5 backward compatibility: hardcode the default converter for primitive key serialization. Debug.Assert(defaultConverter.IsInternalConverter && defaultConverter is JsonConverter); - ((JsonConverter)defaultConverter).WriteAsPropertyName(writer, value, options, ref state); + ((JsonConverter)defaultConverter).WriteAsPropertyNameCore(writer, value, options, isWritingExtensionDataProperty: false); return; } ThrowHelper.ThrowNotSupportedException_DictionaryKeyTypeNotSupported(TypeToConvert, this); } - internal sealed override void WriteAsPropertyNameAsObject(Utf8JsonWriter writer, object value, JsonSerializerOptions options, ref WriteStack state) - => WriteAsPropertyName(writer, (T)value, options, ref state); + internal virtual void WriteAsPropertyNameCore(Utf8JsonWriter writer, T value, JsonSerializerOptions options, bool isWritingExtensionDataProperty) + { + if (isWritingExtensionDataProperty) + { + // Extension data is meant as mechanism to gather unused JSON properties; + // do not apply any custom key conversions and hardcode the default behavior. + Debug.Assert(!IsInternalConverter && TypeToConvert == typeof(string)); + writer.WritePropertyName((string)(object)value!); + return; + } + + int originalDepth = writer.CurrentDepth; + WriteAsPropertyName(writer, value, options); + if (originalDepth != writer.CurrentDepth || writer.TokenType != JsonTokenType.PropertyName) + { + ThrowHelper.ThrowJsonException_SerializationConverterWrite(this); + } + } + + internal sealed override void WriteAsPropertyNameCoreAsObject(Utf8JsonWriter writer, object value, JsonSerializerOptions options, bool isWritingExtensionDataProperty) + => WriteAsPropertyNameCore(writer, (T)value, options, isWritingExtensionDataProperty); internal virtual T ReadNumberWithCustomHandling(ref Utf8JsonReader reader, JsonNumberHandling handling, JsonSerializerOptions options) => throw new InvalidOperationException(); diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/WriteStackFrame.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/WriteStackFrame.cs index 7d9ed3b6863f34..97002fbafdc99c 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/WriteStackFrame.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/WriteStackFrame.cs @@ -39,7 +39,7 @@ internal struct WriteStackFrame /// /// Used when processing extension data dictionaries. /// - public bool IgnoreDictionaryKeyPolicy; + public bool IsWritingExtensionDataProperty; /// /// The class (POCO or IEnumerable) that is being populated. diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.cs index 8c9ae27228b7ad..17e08065a39f91 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.cs @@ -81,6 +81,8 @@ public sealed partial class Utf8JsonWriter : IDisposable, IAsyncDisposable private int Indentation => CurrentDepth * JsonConstants.SpacesPerIndent; + internal JsonTokenType TokenType => _tokenType; + /// /// Tracks the recursive depth of the nested objects / arrays within the JSON text /// written so far. This provides the depth of the current token. diff --git a/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/Serialization/CustomConverterTests/CustomConverterTests.KeyConverters.cs b/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/Serialization/CustomConverterTests/CustomConverterTests.KeyConverters.cs new file mode 100644 index 00000000000000..7f3f0deb91fa48 --- /dev/null +++ b/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/Serialization/CustomConverterTests/CustomConverterTests.KeyConverters.cs @@ -0,0 +1,167 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Collections.Generic; +using System.Linq; +using System.Text.Encodings.Web; +using Xunit; + +namespace System.Text.Json.Serialization.Tests +{ + public static partial class CustomConverterTests + { + [Theory] + [MemberData(nameof(GetCustomKeysAndExpectedPropertyNameEncodings))] + public static void CustomKeyConverter_Serialization(TKey key, string expectedKeyEncoding) + { + var options = new JsonSerializerOptions { Converters = { new EmbeddedJsonKeyConverter() } }; + var value = new Dictionary { [key] = 42 }; + + string expectedJson = $"{{\"{expectedKeyEncoding}\":42}}"; + string json = JsonSerializer.Serialize(value, options); + + Assert.Equal(expectedJson, json); + } + + [Theory] + [MemberData(nameof(GetCustomKeysAndExpectedPropertyNameEncodings))] + public static void CustomKeyConverter_Deserialization(TKey key, string expectedKeyEncoding) + { + var options = new JsonSerializerOptions { Converters = { new EmbeddedJsonKeyConverter() } }; + + string json = $"{{\"{expectedKeyEncoding}\":42}}"; + var deserializedValue = JsonSerializer.Deserialize>(json, options); + + Assert.Equal(1, deserializedValue.Count); + Assert.Equal(key, deserializedValue.Keys.First()); + } + + public static IEnumerable GetCustomKeysAndExpectedPropertyNameEncodings() + { + yield return Wrap("key"); + yield return Wrap(42); + yield return Wrap(true); + yield return Wrap(new KeyValuePair("x", false)); + yield return Wrap(new int[] { 1, 2, 3 }); + + static object[] Wrap(TKey key) => new object[] { key, JavaScriptEncoder.Default.Encode(JsonSerializer.Serialize(key)) }; + } + + [Fact] + public static void ExtensionDataProperty_Serialization_IgnoreCustomStringKeyConverter() + { + var options = new JsonSerializerOptions { Converters = { new EmbeddedJsonKeyConverter() } }; + var value = new PocoWithExtensionDataProperty(); + + string expectedJson = @"{""key"":42}"; + string json = JsonSerializer.Serialize(value, options); + + Assert.Equal(expectedJson, json); + } + + public class PocoWithExtensionDataProperty + { + [JsonExtensionData] + public Dictionary Data { get; set; } = new Dictionary { ["key"] = 42 }; + } + + [Theory] + [InlineData(InvalidCustomKeyConverter.InvalidOperationType.DoNothing)] + [InlineData(InvalidCustomKeyConverter.InvalidOperationType.HandleEntireParentObject)] + [InlineData(InvalidCustomKeyConverter.InvalidOperationType.HandleEntireProperty)] + public static void InvalidCustomKeyConverter_Serialization(InvalidCustomKeyConverter.InvalidOperationType invalidOperationType) + { + var options = new JsonSerializerOptions { Converters = { new InvalidCustomKeyConverter { Type = invalidOperationType } } }; + var value = new Dictionary { ["key"] = 42 }; + + Assert.Throws(() => JsonSerializer.Serialize(value, options)); + } + + [Theory] + [InlineData(InvalidCustomKeyConverter.InvalidOperationType.HandleEntireParentObject, typeof(JsonException))] + [InlineData(InvalidCustomKeyConverter.InvalidOperationType.HandleEntireProperty, typeof(JsonException))] + [InlineData(InvalidCustomKeyConverter.InvalidOperationType.ReturnNull, typeof(ArgumentNullException))] + public static void InvalidCustomKeyConverter_Deserialization(InvalidCustomKeyConverter.InvalidOperationType invalidOperationType, Type exceptionType) + { + var options = new JsonSerializerOptions { Converters = { new InvalidCustomKeyConverter { Type = invalidOperationType } } }; + string json = @"{""key1"" : 1, ""key2"" : 2 }"; + + Assert.Throws(exceptionType, () => JsonSerializer.Deserialize>(json, options)); + } + + public class EmbeddedJsonKeyConverter : JsonConverter + { + public override T Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions _) + => throw new NotSupportedException(); + + public override void Write(Utf8JsonWriter writer, T value, JsonSerializerOptions _) + => throw new NotSupportedException(); + + public override void WriteAsPropertyName(Utf8JsonWriter writer, T value, JsonSerializerOptions _) + => writer.WritePropertyName(JsonSerializer.Serialize(value)); + + public override T ReadAsPropertyName(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions _) + => JsonSerializer.Deserialize(reader.GetString()); + } + + public class InvalidCustomKeyConverter : JsonConverter + { + public enum InvalidOperationType + { + DoNothing, HandleEntireProperty, HandleEntireParentObject, ReturnNull + } + + public InvalidOperationType Type { get; init; } + + public override string Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + => throw new NotSupportedException(); + public override void Write(Utf8JsonWriter writer, string value, JsonSerializerOptions options) + => throw new NotSupportedException(); + + public override void WriteAsPropertyName(Utf8JsonWriter writer, string value, JsonSerializerOptions _) + { + switch (Type) + { + case InvalidOperationType.HandleEntireProperty: + writer.WriteString("key", value); + break; + + case InvalidOperationType.HandleEntireParentObject: + writer.WriteEndObject(); + break; + + case InvalidOperationType.DoNothing: + default: + break; + } + } + + public override string ReadAsPropertyName(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions _) + { + switch (Type) + { + case InvalidOperationType.HandleEntireProperty: + reader.Read(); + reader.Skip(); + break; + + case InvalidOperationType.HandleEntireParentObject: + while (reader.TokenType != JsonTokenType.EndObject) + { + reader.Read(); + reader.Skip(); + } + break; + + case InvalidOperationType.ReturnNull: + return null; + + default: + break; + } + + return "key"; + } + } + } +} diff --git a/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/System.Text.Json.Tests.csproj b/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/System.Text.Json.Tests.csproj index 762ddff9f0cb7a..3485690c39a559 100644 --- a/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/System.Text.Json.Tests.csproj +++ b/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/System.Text.Json.Tests.csproj @@ -125,6 +125,7 @@ +