You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Starting in .NET 11 RC 1, a configuration added by using AddConfiguration treats an empty string as a present value. The empty string therefore overrides values from providers registered earlier in the outer configuration instead of allowing those earlier values to remain effective.
This change was introduced by dotnet/runtime#131480. It continues the distinction between empty and null configuration values established by the .NET 10 change Null values preserved in configuration. The handling of null by chained configuration is unchanged.
Version
.NET 11 RC 1
Previous behavior
ChainedConfigurationProvider.TryGet reported an empty string as not found. Consequently, an empty value in a chained configuration did not override a value supplied by an earlier provider:
When there was no earlier value, reading the key returned null, and a section whose only value was the chained empty string was considered not to exist.
New behavior
Starting in .NET 11 RC 1, ChainedConfigurationProvider.TryGet reports an empty string as found. With the preceding example, the empty value from inner overrides the earlier value, and the output is:
Endpoint: ''
A section whose value is an empty string is now considered to exist. Binding also observes the empty value instead of an earlier provider's value. For example, binding an empty string over an earlier numeric value to an integer property now throws InvalidOperationException, consistently with an empty value supplied by a directly added provider.
A null value in the wrapped IConfiguration continues to be treated as absent, because the IConfiguration indexer cannot distinguish a key whose value is null from a missing key.
Type of breaking change
Binary incompatible: Existing binaries might encounter a breaking change in behavior, such as failure to load or execute, and if so, require recompilation.
Source incompatible: When recompiled using the new SDK or component or to target the new runtime, existing source code might require source changes to compile successfully.
Behavioral change: Existing binaries might behave differently at run time.
Reason for change
An empty string is a valid configuration value. Treating it as missing made chained configuration inconsistent with directly added configuration providers and prevented applications from intentionally clearing or disabling a setting by overriding it with an empty string. The new behavior preserves the configuration provider's distinction between an empty value and an absent value.
Recommended action
If an empty string is intended to override an earlier value, no action is required.
If an application relied on an empty string in a chained configuration allowing an earlier provider's value to win, remove that key from the chained configuration or represent it as missing or null. Applications that bind chained values to non-string types should also validate or normalise empty values before binding if an empty value is not valid for the target type. There is no compatibility switch to restore the previous behavior.
Feature area
Extensions
Affected APIs
Microsoft.Extensions.Configuration.ChainedConfigurationProvider.TryGet(string, out string?)
Microsoft.Extensions.Configuration.ChainedBuilderExtensions.AddConfiguration(IConfigurationBuilder, IConfiguration) and its shouldDisposeConfiguration overload
Description
Starting in .NET 11 RC 1, a configuration added by using
AddConfigurationtreats an empty string as a present value. The empty string therefore overrides values from providers registered earlier in the outer configuration instead of allowing those earlier values to remain effective.This change was introduced by dotnet/runtime#131480. It continues the distinction between empty and
nullconfiguration values established by the .NET 10 change Null values preserved in configuration. The handling ofnullby chained configuration is unchanged.Version
.NET 11 RC 1
Previous behavior
ChainedConfigurationProvider.TryGetreported an empty string as not found. Consequently, an empty value in a chained configuration did not override a value supplied by an earlier provider:Before .NET 11 RC 1, the output was:
When there was no earlier value, reading the key returned
null, and a section whose only value was the chained empty string was considered not to exist.New behavior
Starting in .NET 11 RC 1,
ChainedConfigurationProvider.TryGetreports an empty string as found. With the preceding example, the empty value frominneroverrides the earlier value, and the output is:A section whose value is an empty string is now considered to exist. Binding also observes the empty value instead of an earlier provider's value. For example, binding an empty string over an earlier numeric value to an integer property now throws
InvalidOperationException, consistently with an empty value supplied by a directly added provider.A
nullvalue in the wrappedIConfigurationcontinues to be treated as absent, because theIConfigurationindexer cannot distinguish a key whose value isnullfrom a missing key.Type of breaking change
Reason for change
An empty string is a valid configuration value. Treating it as missing made chained configuration inconsistent with directly added configuration providers and prevented applications from intentionally clearing or disabling a setting by overriding it with an empty string. The new behavior preserves the configuration provider's distinction between an empty value and an absent value.
Recommended action
If an empty string is intended to override an earlier value, no action is required.
If an application relied on an empty string in a chained configuration allowing an earlier provider's value to win, remove that key from the chained configuration or represent it as missing or
null. Applications that bind chained values to non-string types should also validate or normalise empty values before binding if an empty value is not valid for the target type. There is no compatibility switch to restore the previous behavior.Feature area
Extensions
Affected APIs
Microsoft.Extensions.Configuration.ChainedConfigurationProvider.TryGet(string, out string?)Microsoft.Extensions.Configuration.ChainedBuilderExtensions.AddConfiguration(IConfigurationBuilder, IConfiguration)and itsshouldDisposeConfigurationoverloadMicrosoft.Extensions.Configuration.ChainedConfigurationSource.Build(IConfigurationBuilder)Note
This issue was drafted with AI assistance from GitHub Copilot.