Skip to content

IConfiguration binding behave unexpectedly when binding empty strings from nested configurations #62532

Description

@FynZ

Describe the bug

Binding configuration with empty string as value ("") will result in null if the section it binds to comes from a nested configuration.

To Reproduce

// code

using Microsoft.AspNetCore;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;

// we build the configuration upfront to configure stuff (logging, ..)
var configuration = new ConfigurationBuilder()
    .AddJsonFile("appsettings.NotIncluedByDefault.json")
    .AddEnvironmentVariables()
    .AddCommandLine(args)
    .Build();

var host = WebHost.CreateDefaultBuilder(args)
    .UseStartup<Startup>()
    .UseUrls(configuration["Urls"])
    .UseConfiguration(configuration)
    // we add the previously built configuration manually
    .ConfigureAppConfiguration(builder => builder.AddConfiguration(configuration));

await host.Build().RunAsync();

public class Startup
{
    private readonly IConfiguration _configuration;

    public Startup(IConfiguration configuration)
    {
        _configuration = configuration;
    }

    /// <summary>
    ///     This method gets called by the runtime. Use this method to add services to the container.
    /// </summary>
    /// <param name="services">Collection of service descriptors.</param>
    public void ConfigureServices(IServiceCollection services)
    {
        // This configuration binds from the main settings files
        var ok = new WorkingConfiguration();
        _configuration.GetSection("BindingOk").Bind(ok);

        // This configuration binds from a settings files added "manually"
        var faulted = new FaultedConfiguration();
        _configuration.GetSection("BindingNotOk").Bind(faulted);

        services.AddSingleton(ok);
        services.AddSingleton(faulted);
    }

    /// <summary>
    ///     Application configuration.
    /// </summary>
    /// <param name="app">The application builder.</param>
    public void Configure(IApplicationBuilder app)
    {
    }
}

public class WorkingConfiguration
{
    public string ThisBindingWillBindToString { get; set; }
}

public class FaultedConfiguration
{
    public string ThisBindingWillBindToNull { get; set; }
}

// appsettings.json
{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  },
  "BindingOk": {
    "ThisBindingWillBindToString": ""
  }
}

// appsettings.NotIncluedByDefault.json
{
  "BindingNotOk": {
    "ThisBindingWillBindToNull": "" 
  }
}

Further technical details

  • ASP.NET Core version: 6.0.100
  • The IDE (VS / VS Code/ VS4Mac) you're running on, and its version: VisualStudioProfessional 2022 17.0.2, also observed in Rider from a colleague (dont know the version) and in production (base image is mcr.microsoft.com/dotnet/aspnet:6.0)
  • Include the output of dotnet --info:
dotnet --info Output
.NET SDK (reflecting any global.json):
 Version:   6.0.100
 Commit:    9e8b04bbff

Runtime Environment:
 OS Name:     Windows
 OS Version:  10.0.19043
 OS Platform: Windows
 RID:         win10-x64
 Base Path:   C:\Program Files\dotnet\sdk\6.0.100\

Host (useful for support):
  Version: 6.0.0
  Commit:  4822e3c3aa

.NET SDKs installed:
  5.0.403 [C:\Program Files\dotnet\sdk]
  6.0.100 [C:\Program Files\dotnet\sdk]

.NET runtimes installed:
  Microsoft.AspNetCore.App 3.1.21 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
  Microsoft.AspNetCore.App 5.0.12 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
  Microsoft.AspNetCore.App 6.0.0 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
  Microsoft.NETCore.App 3.1.21 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.NETCore.App 5.0.12 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.NETCore.App 6.0.0 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.WindowsDesktop.App 3.1.21 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
  Microsoft.WindowsDesktop.App 5.0.12 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
  Microsoft.WindowsDesktop.App 6.0.0 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]

To install additional .NET runtimes or SDKs:
  https://aka.ms/dotnet-download

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions