From: Anirudh Agnihotry Date: Mon, 17 Jun 2019 22:48:41 +0000 (-0700) Subject: Providing support for duplicate keys in dictionary (dotnet/corefx#38524) X-Git-Tag: submit/tizen/20210909.063632~11031^2~1263 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=c111f40f0ae24c697ff627d3f74bd1d83be364e2;p=platform%2Fupstream%2Fdotnet%2Fruntime.git Providing support for duplicate keys in dictionary (dotnet/corefx#38524) * providing support for duplicate keys in dictionary * Improving failure message * fixing merge conflicts Commit migrated from https://github.com/dotnet/corefx/commit/ef0578fd6abeba406ddffbb1591c1a618bca9dae --- diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Read.HandleArray.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Read.HandleArray.cs index 04bd680..b7ac54a 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Read.HandleArray.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Read.HandleArray.cs @@ -198,14 +198,7 @@ namespace System.Text.Json string key = state.Current.KeyName; Debug.Assert(!string.IsNullOrEmpty(key)); - if (!dictionary.Contains(key)) - { - dictionary.Add(key, value); - } - else - { - ThrowHelper.ThrowJsonException_DeserializeDuplicateKey(key, reader, state.JsonPath); - } + dictionary[key] = value; } else if (state.Current.IsIDictionaryConstructible || (state.Current.IsIDictionaryConstructibleProperty && !setPropertyDirectly) || @@ -217,14 +210,7 @@ namespace System.Text.Json string key = state.Current.KeyName; Debug.Assert(!string.IsNullOrEmpty(key)); - if (!dictionary.Contains(key)) - { - dictionary.Add(key, value); - } - else - { - ThrowHelper.ThrowJsonException_DeserializeDuplicateKey(key, reader, state.JsonPath); - } + dictionary[key] = value; } else { @@ -280,14 +266,7 @@ namespace System.Text.Json string key = state.Current.KeyName; Debug.Assert(!string.IsNullOrEmpty(key)); - if (!dictionary.ContainsKey(key)) // The IDictionary.TryAdd extension method is not available in netstandard. - { - dictionary.Add(key, value); - } - else - { - ThrowHelper.ThrowJsonException_DeserializeDuplicateKey(key, reader, state.JsonPath); - } + dictionary[key] = value; } else if (state.Current.IsProcessingIDictionaryConstructibleOrKeyValuePair) { @@ -296,14 +275,7 @@ namespace System.Text.Json string key = state.Current.KeyName; Debug.Assert(!string.IsNullOrEmpty(key)); - if (!dictionary.ContainsKey(key)) // The IDictionary.TryAdd extension method is not available in netstandard. - { - dictionary.Add(key, value); - } - else - { - ThrowHelper.ThrowJsonException_DeserializeDuplicateKey(key, reader, state.JsonPath); - } + dictionary[key] = value; } else { diff --git a/src/libraries/System.Text.Json/tests/Serialization/DictionaryTests.cs b/src/libraries/System.Text.Json/tests/Serialization/DictionaryTests.cs index 6efcfdf..590d580 100644 --- a/src/libraries/System.Text.Json/tests/Serialization/DictionaryTests.cs +++ b/src/libraries/System.Text.Json/tests/Serialization/DictionaryTests.cs @@ -140,22 +140,6 @@ namespace System.Text.Json.Serialization.Tests } [Fact] - public static void DuplicateKeysFail() - { - // Non-generic IDictionary case. - Assert.Throws(() => JsonSerializer.Parse( - @"{""Hello"":""World"", ""Hello"":""World""}")); - - // Strongly-typed IDictionary<,> case. - Assert.Throws(() => JsonSerializer.Parse>( - @"{""Hello"":""World"", ""Hello"":""World""}")); - - // Weakly-typed IDictionary case. - Assert.Throws(() => JsonSerializer.Parse>( - @"{""Hello"":null, ""Hello"":null}")); - } - - [Fact] public static void DictionaryOfObject() { { @@ -790,6 +774,21 @@ namespace System.Text.Json.Serialization.Tests } [Fact] + public static void DeserializeDictionaryWithDuplicateKeys() + { + // Strongly-typed IDictionary<,> case. + Dictionary deserialize = JsonSerializer.Parse>(@"{""Hello"":""World"", ""Hello"":""NewValue""}"); + Assert.Equal("NewValue", deserialize["Hello"]); + + deserialize = JsonSerializer.Parse>(@"{""Hello"":""World"", ""myKey"" : ""myValue"", ""Hello"":""NewValue""}"); + Assert.Equal("NewValue", deserialize["Hello"]); + + // Weakly-typed IDictionary case. + Dictionary deserializeObject = JsonSerializer.Parse>(@"{""Hello"":""World"", ""Hello"": null}"); + Assert.Null(deserializeObject["Hello"]); + } + + [Fact] public static void ClassWithNoSetter() { string json = @"{""MyDictionary"":{""Key"":""Value""}}"; diff --git a/src/libraries/System.Text.Json/tests/Serialization/ExceptionTests.cs b/src/libraries/System.Text.Json/tests/Serialization/ExceptionTests.cs index c909971..3bbeb0c 100644 --- a/src/libraries/System.Text.Json/tests/Serialization/ExceptionTests.cs +++ b/src/libraries/System.Text.Json/tests/Serialization/ExceptionTests.cs @@ -34,14 +34,14 @@ namespace System.Text.Json.Serialization.Tests { try { - JsonSerializer.Parse>(@"{""Key"":1, ""Key"":2}"); - Assert.True(false, "Expected JsonException was not thrown."); + JsonSerializer.Parse>(@"{""Key"":1, ""Key"":2}"); + Assert.True(false, "We follow 'Last value wins' approach for duplicate keys."); } catch (JsonException e) { Assert.Equal(0, e.LineNumber); - Assert.Equal(17, e.BytePositionInLine); - Assert.Contains("LineNumber: 0 | BytePositionInLine: 17.", e.Message); + Assert.Equal(8, e.BytePositionInLine); + Assert.Contains("LineNumber: 0 | BytePositionInLine: 8.", e.Message); Assert.Contains("$.Key", e.Path); // Verify Path is not repeated.