From: Layomi Akinrinade Date: Fri, 12 Jul 2019 22:55:11 +0000 (-0400) Subject: Do not use DictionaryKeyPolicy on deserialization (dotnet/corefx#39392) X-Git-Tag: submit/tizen/20210909.063632~11031^2~954 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=2fd57c63032efa8543495bd11e5646aef9c11db6;p=platform%2Fupstream%2Fdotnet%2Fruntime.git Do not use DictionaryKeyPolicy on deserialization (dotnet/corefx#39392) * Do not use DictionaryKeyPolicy on deserialization * Update policy doc Commit migrated from https://github.com/dotnet/corefx/commit/ba8641a3cdfc9372597e4dbd5ad62be4cbc32b8b --- diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Read.HandlePropertyName.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Read.HandlePropertyName.cs index 987dc80..ced83b4 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Read.HandlePropertyName.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Read.HandlePropertyName.cs @@ -26,20 +26,6 @@ namespace System.Text.Json if ((state.Current.IsProcessingDictionary || state.Current.IsProcessingIDictionaryConstructible) && state.Current.JsonClassInfo.DataExtensionProperty != state.Current.JsonPropertyInfo) { - string keyName = reader.GetString(); - - if (options.DictionaryKeyPolicy != null) - { - keyName = options.DictionaryKeyPolicy.ConvertName(keyName); - - if (keyName == null) - { - ThrowHelper.ThrowInvalidOperationException_SerializerDictionaryKeyNull(options.DictionaryKeyPolicy.GetType()); - } - - keyName = options.DictionaryKeyPolicy.ConvertName(keyName); - } - if (state.Current.IsDictionary || state.Current.IsIDictionaryConstructible) { state.Current.JsonPropertyInfo = state.Current.JsonClassInfo.PolicyProperty; @@ -51,7 +37,7 @@ namespace System.Text.Json state.Current.IsIDictionaryConstructible || (state.Current.IsIDictionaryConstructibleProperty && state.Current.JsonPropertyInfo != null)); - state.Current.KeyName = keyName; + state.Current.KeyName = reader.GetString(); } else { diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializerOptions.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializerOptions.cs index f326586..c3e3a74 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializerOptions.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializerOptions.cs @@ -97,6 +97,7 @@ namespace System.Text.Json /// /// /// This property can be set to to specify a camel-casing policy. + /// It is not used when deserializing. /// public JsonNamingPolicy DictionaryKeyPolicy { diff --git a/src/libraries/System.Text.Json/tests/Serialization/DictionaryTests.KeyPolicy.cs b/src/libraries/System.Text.Json/tests/Serialization/DictionaryTests.KeyPolicy.cs index cf3d3fc..65c97b1 100644 --- a/src/libraries/System.Text.Json/tests/Serialization/DictionaryTests.KeyPolicy.cs +++ b/src/libraries/System.Text.Json/tests/Serialization/DictionaryTests.KeyPolicy.cs @@ -16,17 +16,36 @@ namespace System.Text.Json.Serialization.Tests { var options = new JsonSerializerOptions { - DictionaryKeyPolicy = JsonNamingPolicy.CamelCase + DictionaryKeyPolicy = JsonNamingPolicy.CamelCase // e.g. Key1 -> key1. }; const string JsonString = @"[{""Key1"":1,""Key2"":2},{""Key1"":3,""Key2"":4}]"; - Dictionary[] obj = JsonSerializer.Deserialize[]>(JsonString, options); + + // Without key policy, deserialize keys as they are. + Dictionary[] obj = JsonSerializer.Deserialize[]>(JsonString); Assert.Equal(2, obj.Length); - Assert.Equal(1, obj[0]["key1"]); - Assert.Equal(2, obj[0]["key2"]); - Assert.Equal(3, obj[1]["key1"]); - Assert.Equal(4, obj[1]["key2"]); + + Assert.Equal(2, obj[0].Count); + Assert.Equal(1, obj[0]["Key1"]); + Assert.Equal(2, obj[0]["Key2"]); + + Assert.Equal(2, obj[1].Count); + Assert.Equal(3, obj[1]["Key1"]); + Assert.Equal(4, obj[1]["Key2"]); + + // Ensure we ignore key policy and deserialize keys as they are. + obj = JsonSerializer.Deserialize[]>(JsonString, options); + + Assert.Equal(2, obj.Length); + + Assert.Equal(2, obj[0].Count); + Assert.Equal(1, obj[0]["Key1"]); + Assert.Equal(2, obj[0]["Key2"]); + + Assert.Equal(2, obj[1].Count); + Assert.Equal(3, obj[1]["Key1"]); + Assert.Equal(4, obj[1]["Key2"]); } [Fact] @@ -34,7 +53,7 @@ namespace System.Text.Json.Serialization.Tests { var options = new JsonSerializerOptions() { - DictionaryKeyPolicy = JsonNamingPolicy.CamelCase + DictionaryKeyPolicy = JsonNamingPolicy.CamelCase // e.g. Key1 -> key1. }; Dictionary[] obj = new Dictionary[] @@ -60,11 +79,17 @@ namespace System.Text.Json.Serialization.Tests { var options = new JsonSerializerOptions { - DictionaryKeyPolicy = new UppercaseNamingPolicy() + DictionaryKeyPolicy = new UppercaseNamingPolicy() // e.g. myint -> MYINT. }; - Dictionary obj = JsonSerializer.Deserialize>(@"{""myint"":1}", options); - Assert.Equal(1, obj["MYINT"]); + + // Without key policy, deserialize keys as they are. + Dictionary obj = JsonSerializer.Deserialize>(@"{""myint"":1}"); + Assert.Equal(1, obj["myint"]); + + // Ensure we ignore key policy and deserialize keys as they are. + obj = JsonSerializer.Deserialize>(@"{""myint"":1}", options); + Assert.Equal(1, obj["myint"]); } [Fact] @@ -72,7 +97,7 @@ namespace System.Text.Json.Serialization.Tests { var options = new JsonSerializerOptions { - DictionaryKeyPolicy = new UppercaseNamingPolicy() + DictionaryKeyPolicy = new UppercaseNamingPolicy() // e.g. myint -> MYINT. }; Dictionary obj = new Dictionary { { "myint1", 1 }, { "myint2", 2 } }; @@ -97,30 +122,18 @@ namespace System.Text.Json.Serialization.Tests DictionaryKeyPolicy = new NullNamingPolicy() }; - // A policy that returns null is not allowed. - Assert.Throws(() => JsonSerializer.Deserialize>(@"{""onlyKey"": 1}", options)); + // A naming policy that returns null is not allowed. Assert.Throws(() => JsonSerializer.Serialize(new Dictionary { { "onlyKey", 1 } }, options)); - } - - [Fact] - public static void KeyConflictDeserialize_LastValueWins() - { - var options = new JsonSerializerOptions - { - DictionaryKeyPolicy = JsonNamingPolicy.CamelCase - }; - // The camel case policy resolves two keys to the same output key. - string json = @"{""myInt"":1,""MyInt"":2}"; - Dictionary obj = JsonSerializer.Deserialize>(json, options); + // We don't use policy on deserialize, so we populate dictionary. + Dictionary obj = JsonSerializer.Deserialize>(@"{""onlyKey"": 1}", options); - // Check that the last value wins. - Assert.Equal(2, obj["myInt"]); Assert.Equal(1, obj.Count); + Assert.Equal(1, obj["onlyKey"]); } [Fact] - public static void KeyConflictSerialize_WriteAll() + public static void KeyConflict_Serialize_WriteAll() { var options = new JsonSerializerOptions {