From d3f4de1c7ab45eda70f2e084c3b47a38cfca8d74 Mon Sep 17 00:00:00 2001 From: Eirik Tsarpalis Date: Thu, 14 Nov 2024 08:08:56 +0000 Subject: [PATCH] Fix regression in constructor parameter binding logic. (#109786) --- .../Serialization/Metadata/JsonTypeInfo.cs | 3 ++- .../ConstructorTests.ParameterMatching.cs | 27 +++++++++++++++++++ .../Serialization/ConstructorTests.cs | 2 ++ 3 files changed, 31 insertions(+), 1 deletion(-) diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Metadata/JsonTypeInfo.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Metadata/JsonTypeInfo.cs index 00c4245a4c87bd..bd3e3d9241f857 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Metadata/JsonTypeInfo.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Metadata/JsonTypeInfo.cs @@ -1209,7 +1209,8 @@ internal void ConfigureConstructorParameters() continue; } - ParameterLookupKey paramKey = new(propertyInfo.PropertyType, propertyInfo.Name); + string propertyName = propertyInfo.MemberName ?? propertyInfo.Name; + ParameterLookupKey paramKey = new(propertyInfo.PropertyType, propertyName); if (!parameterIndex.TryAdd(paramKey, parameterInfo)) { // Multiple object properties cannot bind to the same constructor parameter. diff --git a/src/libraries/System.Text.Json/tests/Common/ConstructorTests/ConstructorTests.ParameterMatching.cs b/src/libraries/System.Text.Json/tests/Common/ConstructorTests/ConstructorTests.ParameterMatching.cs index e134d42286de91..d46253c65761e1 100644 --- a/src/libraries/System.Text.Json/tests/Common/ConstructorTests/ConstructorTests.ParameterMatching.cs +++ b/src/libraries/System.Text.Json/tests/Common/ConstructorTests/ConstructorTests.ParameterMatching.cs @@ -1668,5 +1668,32 @@ public async Task RespectRequiredConstructorParameters_NoParameterMissing_Succee Assert.Equal(2, result.Y); Assert.Equal(3, result.Z); } + + [Fact] + public async Task ClassWithConflictingCaseInsensitiveProperties_Succeeds_When_CaseSensitive() + { + // Regression test for https://github.com/dotnet/runtime/issues/109768 + + string json = """{"a": "lower", "A": "upper"}"""; + ClassWithConflictingCaseInsensitiveProperties result = await Serializer.DeserializeWrapper(json); + Assert.Equal("lower", result.From); + Assert.Equal("upper", result.To); + } + + public class ClassWithConflictingCaseInsensitiveProperties + { + [JsonPropertyName("a")] + public string From { get; set; } + + [JsonPropertyName("A")] + public string To { get; set; } + + [JsonConstructor] + public ClassWithConflictingCaseInsensitiveProperties(string from, string to) + { + From = from; + To = to; + } + } } } diff --git a/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Tests/Serialization/ConstructorTests.cs b/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Tests/Serialization/ConstructorTests.cs index 1f2fe901f456ea..06ff3b6e39bb1c 100644 --- a/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Tests/Serialization/ConstructorTests.cs +++ b/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Tests/Serialization/ConstructorTests.cs @@ -154,6 +154,7 @@ protected ConstructorTests_Metadata(JsonSerializerWrapper stringWrapper) [JsonSerializable(typeof(TypeWithEnumParameters))] [JsonSerializable(typeof(ClassWithIgnoredPropertyDefaultParam))] [JsonSerializable(typeof(ClassWithCustomConverterOnCtorParameter))] + [JsonSerializable(typeof(ClassWithConflictingCaseInsensitiveProperties))] internal sealed partial class ConstructorTestsContext_Metadata : JsonSerializerContext { } @@ -303,6 +304,7 @@ public ConstructorTests_Default(JsonSerializerWrapper jsonSerializer) : base(jso [JsonSerializable(typeof(TypeWithEnumParameters))] [JsonSerializable(typeof(ClassWithIgnoredPropertyDefaultParam))] [JsonSerializable(typeof(ClassWithCustomConverterOnCtorParameter))] + [JsonSerializable(typeof(ClassWithConflictingCaseInsensitiveProperties))] internal sealed partial class ConstructorTestsContext_Default : JsonSerializerContext { }