Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ConfigurationBinder Source Generator is comparing configuration keys case-sensitively #88112

Closed
eerhardt opened this issue Jun 27, 2023 · 1 comment · Fixed by #88338
Closed
Assignees
Labels
area-Extensions-Configuration bug source-generator Indicates an issue with a source generator feature
Milestone

Comments

@eerhardt
Copy link
Member

Description

The ConfigurationBinder Source Generator is generating code like this:

            foreach (IConfigurationSection section in configuration.GetChildren())
            {
                switch (section.Key)
                {
                    case "ConnectionString":
                        {
                            obj.ConnectionString = configuration["ConnectionString"]!;
                        }
                        break;
                    case "JwtSigningKey":
                        {
                            obj.JwtSigningKey = configuration["JwtSigningKey"]!;
                        }
                        break;

This is not correct because it is comparing the section's Key with "ConnectionString" in a case sensitive manner. However, configuration keys are case-insensitive. This causes setting environment variables like APPSETTINGS__CONNECTIONSTRING to no longer bind correctly.

You can see this happening in the debugger below:

image

Reproduction Steps

Write an app with an options class like:

internal class AppSettings
{
    public required string ConnectionString { get; set; }

    public string? JwtSigningKey { get; set; }

    public bool SuppressDbInitialization { get; set; }
}

During app startup, bind the AppSettings to the configuration like (ensure you are using EnableConfigurationBindingGenerator=true):

    public static IServiceCollection ConfigureAppSettings(this IServiceCollection services, IConfigurationRoot configurationRoot, IHostEnvironment hostEnvironment)
    {
        services.AddSingleton<IValidateOptions<AppSettings>, AppSettingsValidator>()
            .AddOptions<AppSettings>()
            .BindConfiguration(nameof(AppSettings))
            .ValidateOnStart();

Run the app with an environment variable set: $env:APPSETTINGS__CONNECTIONSTRING="Server=127.0.01;User Id=benchmarkdbuser;Password=benchmarkdbpass;Database=postgres".

Expected behavior

The environment variable configuration should bind successfully. The AppSettings object should get its ConnectionString property set to the above.

Actual behavior

The environment variable fails to bind correctly. The ConnectionString property is left empty.

Regression?

This is a regression from the reflection based ConfigurationBinder.

Known Workarounds

No response

Configuration

No response

Other information

No response

@eerhardt eerhardt added area-Extensions-Configuration source-generator Indicates an issue with a source generator feature labels Jun 27, 2023
@ghost ghost added the untriaged New issue has not been triaged by the area owner label Jun 27, 2023
@ghost
Copy link

ghost commented Jun 27, 2023

Tagging subscribers to this area: @dotnet/area-extensions-configuration
See info in area-owners.md if you want to be subscribed.

Issue Details

Description

The ConfigurationBinder Source Generator is generating code like this:

            foreach (IConfigurationSection section in configuration.GetChildren())
            {
                switch (section.Key)
                {
                    case "ConnectionString":
                        {
                            obj.ConnectionString = configuration["ConnectionString"]!;
                        }
                        break;
                    case "JwtSigningKey":
                        {
                            obj.JwtSigningKey = configuration["JwtSigningKey"]!;
                        }
                        break;

This is not correct because it is comparing the section's Key with "ConnectionString" in a case sensitive manner. However, configuration keys are case-insensitive. This causes setting environment variables like APPSETTINGS__CONNECTIONSTRING to no longer bind correctly.

You can see this happening in the debugger below:

image

Reproduction Steps

Write an app with an options class like:

internal class AppSettings
{
    public required string ConnectionString { get; set; }

    public string? JwtSigningKey { get; set; }

    public bool SuppressDbInitialization { get; set; }
}

During app startup, bind the AppSettings to the configuration like (ensure you are using EnableConfigurationBindingGenerator=true):

    public static IServiceCollection ConfigureAppSettings(this IServiceCollection services, IConfigurationRoot configurationRoot, IHostEnvironment hostEnvironment)
    {
        services.AddSingleton<IValidateOptions<AppSettings>, AppSettingsValidator>()
            .AddOptions<AppSettings>()
            .BindConfiguration(nameof(AppSettings))
            .ValidateOnStart();

Run the app with an environment variable set: $env:APPSETTINGS__CONNECTIONSTRING="Server=127.0.01;User Id=benchmarkdbuser;Password=benchmarkdbpass;Database=postgres".

Expected behavior

The environment variable configuration should bind successfully. The AppSettings object should get its ConnectionString property set to the above.

Actual behavior

The environment variable fails to bind correctly. The ConnectionString property is left empty.

Regression?

This is a regression from the reflection based ConfigurationBinder.

Known Workarounds

No response

Configuration

No response

Other information

No response

Author: eerhardt
Assignees: -
Labels:

area-Extensions-Configuration, source-generator

Milestone: -

@layomia layomia self-assigned this Jun 28, 2023
@layomia layomia removed the untriaged New issue has not been triaged by the area owner label Jun 28, 2023
@layomia layomia added this to the 8.0.0 milestone Jun 28, 2023
@layomia layomia added the bug label Jun 29, 2023
@ghost ghost added the in-pr There is an active PR which will close this issue when it is merged label Jul 3, 2023
@ghost ghost removed the in-pr There is an active PR which will close this issue when it is merged label Jul 12, 2023
@ghost ghost locked as resolved and limited conversation to collaborators Aug 13, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area-Extensions-Configuration bug source-generator Indicates an issue with a source generator feature
Projects
None yet
2 participants