microsoft / dotnet

This repo is the official home of .NET on GitHub. It's a great starting point to find many .NET OSS projects from Microsoft and the community, including many that are part of the .NET Foundation.
https://devblogs.microsoft.com/dotnet/
MIT License
14.43k stars 2.21k forks source link

Deserializing a record instance is causing child elements to be duplicated when using configuration binder Get<T> method #1451

Open rajasekarshanmugam opened 1 month ago

rajasekarshanmugam commented 1 month ago

When deserializing the configuration using the binder via configurationRoot.Get() method, some of the child elements are duplicated.

In the below code snipped:

using Microsoft.Extensions.Configuration;
using System.Text.Json;

public static class Program
{
    public static void Main()
    {
        var sample1 = new Root("root1", [new("c1", "c1n1", "c1n1value")]);
        var sampl1Json = sample1.ToJson();
        //Console.WriteLine(sampl1Json);

        var cbjson = new ConfigurationBuilder()
            //.AddJsonFile("appsettings.json", optional: false)
            .AddJsonStream(new MemoryStream(System.Text.Encoding.UTF8.GetBytes(sampl1Json)))
            .Build();

        var sample1copy = cbjson.Get<Root>();
        var sample1copyJson = sample1copy.ToJson();
        Console.WriteLine(sample1copyJson);
    }

    public record Root(string Id, ChildElement[] Elements);

    public record ChildElement(string Id, string Name, string Value);
}

file static class Utils
{
    static readonly JsonSerializerOptions _SERIALIZER = new()
    {
        WriteIndented = true
    };
    public static string ToJson<T>(this T obj) => JsonSerializer.Serialize<T>(obj, _SERIALIZER);
}

Actual output:

{
  "Id": "root1",
  "Elements": [
    {
      "Id": "c1",
      "Name": "c1n1",
      "Value": "c1n1value"
    },
    {
      "Id": "c1",
      "Name": "c1n1",
      "Value": "c1n1value"
    }
  ]
}

Expected Output:

{
  "Id": "root1",
  "Elements": [
    {
      "Id": "c1",
      "Name": "c1n1",
      "Value": "c1n1value"
    }
  ]
}

In the sample below, expected output is a child with just t

Runtimes Checked: .NET runtime used: .NET 8 - 8.0.10, .NET RC2 - 9.0.100-rc.2.24474.11.

Environment Details: .NET SDK: Version: 9.0.100-rc.2.24474.11 Commit: 315e1305db Workload version: 9.0.100-manifests.cea95dba MSBuild version: 17.12.0-preview-24473-03+fea15fbd1

Runtime Environment: OS Name: Windows OS Version: 10.0.22631 OS Platform: Windows RID: win-x64 Base Path: C:\Program Files\dotnet\sdk\9.0.100-rc.2.24474.11\

rajasekarshanmugam commented 1 month ago

moved to https://github.com/dotnet/runtime/issues/109139