Skip to content

Deserializing JSON with properties that differ in casing #109768

@MartyIX

Description

@MartyIX

Description

It appears there is a regression in STJ when one migrates from .NET 8 to .NET 9 when one wants to deserialize JSON where there are two properties that differ in casing (e.g. [JsonPropertyName("a")] and [JsonPropertyName("A")]).

Reproduction Steps

Put the following console app code in Program.cs and run it using dotnet run:

using System.Text.Json;
using System.Text.Json.Serialization;

internal class Program
{
    private static void Main(string[] args)
    {
        JsonSerializerOptions options = new() {
            PropertyNameCaseInsensitive  = false,
        };

        var box = JsonSerializer.Deserialize<Box>("""{"a": "Texas", "A": "California"}""", options);
    }
}

public class Box 
{
    [JsonPropertyName("a")]
    public string From { get; set; }

    [JsonPropertyName("A")]
    public string To { get; set; }

    [JsonConstructor]
    public Box(string from, string to)
    {
        From = from;
        To = to;
    }
}

Expected behavior

No exception should be thrown as in .NET 8.

Actual behavior

Unhandled exception. System.InvalidOperationException: Members 'A' and 'a' on type 'Box' cannot both bind with parameter 'to' in the deserialization constructor.
   at System.Text.Json.ThrowHelper.ThrowInvalidOperationException_MultiplePropertiesBindToConstructorParameters(Type parentType, String parameterName, String firstMatchName, String secondMatchName)
   at System.Text.Json.Serialization.Metadata.JsonTypeInfo.ConfigureConstructorParameters()
   at System.Text.Json.Serialization.Metadata.JsonTypeInfo.Configure()
   at System.Text.Json.Serialization.Metadata.JsonTypeInfo.<EnsureConfigured>g__ConfigureSynchronized|172_0()
   at System.Text.Json.JsonSerializerOptions.GetTypeInfoInternal(Type type, Boolean ensureConfigured, Nullable`1 ensureNotNull, Boolean resolveIfMutable, Boolean fallBackToNearestAncestorType)
   at System.Text.Json.JsonSerializerOptions.GetTypeInfoForRootType(Type type, Boolean fallBackToNearestAncestorType)
   at System.Text.Json.JsonSerializer.GetTypeInfo[T](JsonSerializerOptions options)
   at System.Text.Json.JsonSerializer.Deserialize[TValue](String json, JsonSerializerOptions options)
   at Program.Main(String[] args) in /Users/Net9StjBug/Program.cs:line 13

Regression?

Yes. This works well in .NET 8.

Known Workarounds

I couldn't find any.

Configuration

.NET 9 GA

The issue does not appear to be platform specific.

Other information

I'm not sure if this issue is related to #108790 or not. It's the most similar issue I could find.

Metadata

Metadata

Labels

area-System.Text.Jsonbugin-prThere is an active PR which will close this issue when it is merged

Type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions