Skip to content

Configuration binder doesn't bind IReadOnlySet<Guid> properly in latest dotnet #115564

Closed as duplicate of#102926
@alonkadosh

Description

@alonkadosh

Description

When attempting to bind IReadOnlySet<Guid> to a list of guids in appsettings the value will be empty unless we use IReadOnlySet<string> instead.

Reproduction Steps

using System.Runtime.InteropServices;
using System.Text.Json;
using Microsoft.Extensions.Options;

var builder = WebApplication.CreateBuilder(args);
builder.Services.AddOptions<TopLevelKey>()
    .BindConfiguration("TopLevelKey");

var app = builder.Build();
Console.WriteLine($"Running on .NET version: {RuntimeInformation.FrameworkDescription}");
Console.WriteLine(JsonSerializer.Serialize(app.Services.GetRequiredService<IOptions<TopLevelKey>>().Value));

record TopLevelKey
{
    public IReadOnlySet<Guid> IReadOnlySetGuidTest { get; init; } = new HashSet<Guid>();
    public IReadOnlySet<string> IReadOnlySetStringTest { get; init; } = new HashSet<string>();
    public HashSet<Guid> HashSetGuidTest { get; init; } = new HashSet<Guid>();
}

Appsettings:

{
  "TopLevelKey": {
    "IReadOnlySetGuidTest" : [ "26a0f21c-89fd-4c61-8575-08a903cf3363" ],
    "IReadOnlySetStringTest" : [ "26a0f21c-89fd-4c61-8575-08a903cf3363" ],
    "HashSetGuidTest" : [ "26a0f21c-89fd-4c61-8575-08a903cf3363" ]
  }
}

Expected behavior

I would expect IReadOnlySetGuidTest to bind the values successfully in a similar fashion to IReadOnlySetStringTest and HashSetTest

Actual behavior

IReadOnlySetGuidTest is empty, while IReadOnlySetStringTest and HashSetTest contain the expected value.
See output of the console logs from my examples:

Running on .NET version: .NET 9.0.5
{
    "IReadOnlySetGuidTest": [],
    "IReadOnlySetStringTest": [
        "26a0f21c-89fd-4c61-8575-08a903cf3363"
    ],
    "HashSetGuidTest": [
        "26a0f21c-89fd-4c61-8575-08a903cf3363"
    ]
}

Regression?

No response

Known Workarounds

Using a non-public HashSet and exposing it as IReadOnlySet works, but makes it a lot harder to test.
Also forces the use of:
services.AddOptions(..).BindConfiguration("section", o => o.BindNonPublicProperties = true)
(Thanks @aelij )

Configuration

Running on .NET version: .NET 9.0.5
OS Name: Microsoft Windows 11 Enterprise
Version: 10.0.26100 Build 26100
System Type: x64-based PC

Other information

I found a similar issue with JSON deserialization: #91875
But I have it on a good authority the binder doesn't use a JSON serializer, so I created this issue.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions