From 5efba011e0b39b79ae7e04a414c776230a6c5c02 Mon Sep 17 00:00:00 2001 From: Layomi Akinrinade Date: Tue, 27 Jul 2021 19:12:09 -0700 Subject: [PATCH] Fix regression where NSE is thrown when serializing string dictionary keys with custom converter --- .../Json/Serialization/JsonConverterOfT.cs | 10 +++++- .../CustomConverterTests.cs | 31 +++++++++++++++++++ 2 files changed, 40 insertions(+), 1 deletion(-) 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 3a83812d3396e..09485ecc9142b 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 @@ -594,7 +594,15 @@ internal virtual T ReadWithQuotes(ref Utf8JsonReader reader) } internal virtual void WriteWithQuotes(Utf8JsonWriter writer, [DisallowNull] T value, JsonSerializerOptions options, ref WriteStack state) - => ThrowHelper.ThrowNotSupportedException_DictionaryKeyTypeNotSupported(TypeToConvert, this); + { + if (typeof(T) == typeof(string)) + { + JsonMetadataServices.StringConverter.WriteWithQuotes(writer, (string)(object)value, options, ref state); + return; + } + + ThrowHelper.ThrowNotSupportedException_DictionaryKeyTypeNotSupported(TypeToConvert, this); + } internal sealed override void WriteWithQuotesAsObject(Utf8JsonWriter writer, object value, JsonSerializerOptions options, ref WriteStack state) => WriteWithQuotes(writer, (T)value, options, ref state); diff --git a/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/Serialization/CustomConverterTests/CustomConverterTests.cs b/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/Serialization/CustomConverterTests/CustomConverterTests.cs index 80067292399c4..175229e1e67f4 100644 --- a/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/Serialization/CustomConverterTests/CustomConverterTests.cs +++ b/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/Serialization/CustomConverterTests/CustomConverterTests.cs @@ -1,6 +1,7 @@ // 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 Xunit; namespace System.Text.Json.Serialization.Tests @@ -181,5 +182,35 @@ public static void GetConverterTypeToConvertNull() { Assert.Throws(() => (new JsonSerializerOptions()).GetConverter(typeToConvert: null!)); } + + [Fact] + public static void CustomStringConverter_UsedInDictionaries() + { + var options = new JsonSerializerOptions + { + Converters = { new CustomStringConverter() }, + DictionaryKeyPolicy = JsonNamingPolicy.CamelCase + }; + + var value = new Dictionary() + { + ["Key"] = "value" + }; + + string serialized = JsonSerializer.Serialize(value, options); + Assert.Equal(@"{""key"":""value""}", serialized); + + value = JsonSerializer.Deserialize>(serialized, options); + Assert.Equal("value", value["key"]); + } + + internal sealed class CustomStringConverter : JsonConverter + { + public override string? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + => reader.GetString(); + + public override void Write(Utf8JsonWriter writer, string value, JsonSerializerOptions options) + => writer.WriteStringValue(value); + } } }