-
Notifications
You must be signed in to change notification settings - Fork 6.1k
Description
Description
If BinderOptions.ErrorOnUnknownConfiguration is set and a value in specified in config that cannot be bound to the corresponding property in the bound model, an InvalidOperationException is now thrown.
Previously, BinderOptions.ErrorOnUnknownConfiguration was solely used to raise an exception if a value existed in config but didn't exist in the model being bound to.
As part of PR dotnet/runtime#77708 (which fixes #73915), this property is now also used to throw exceptions if the value in config cannot be converted to the type of value in the model being bound to.
Version
.NET 8 Preview 1
Previous behavior
Previously, this would silently swallow the exceptions for the fields containing invalid enums:
public enum TestSettingsEnum
{
Option1,
Option2,
}
public class MyModelContainingArray
{
public TestSettingsEnum[] Enums { get; set; }
}
public void SilentlySwallowsInvalidItems()
{
var dic = new Dictionary<string, string>
{
{"Section:Enums:0", "Option1"},
{"Section:Enums:1", "Option3"}, // invalid - ignored
{"Section:Enums:2", "Option4"}, // invalid - ignored
{"Section:Enums:3", "Option2"},
};
var configurationBuilder = new ConfigurationBuilder();
configurationBuilder.AddInMemoryCollection(dic);
var config = configurationBuilder.Build();
var configSection = config.GetSection("Section");
var model = configSection.Get<MyModelContainingArray>(o => o.ErrorOnUnknownConfiguration = true);
// we previously would end up with just Option1 and Option2 in the bound collection
}New behavior
Now, if the value cannot be converted to the type of the value in the model, an InvalidOperationException is thrown.
Type of breaking change
- Binary incompatible: Existing binaries may encounter a breaking change in behavior, such as failure to load/execute or different run-time behavior.
- Source incompatible: Source code may encounter a breaking change in behavior when targeting the new runtime/component/SDK, such as compile errors or different run-time behavior.
Reason for change
In the bug report, users were setting BinderOptions.ErrorOnUnknownConfiguration and expecting that to throw if there were any issues in binding configuration.
But the original intention of it was to just throw if something was missing from the bound model.
Perhaps if I'd originally chosen a clearer name, this might've avoided this confusion. I suggested adding another property in BinderOptions, but we went instead with making the existing property dual purpose.
Recommended action
The recommended action is to change or remove the configuration values that cannot be converted to the properties in the bound model.
Alternatively, change BinderOptions.ErrorOnUnknownConfiguration from true to false
Feature area
Core .NET libraries, Serialization
Affected APIs
All of the following in ConfigurationBinder:
public static T? Get<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] T>(this IConfiguration configuration, Action<BinderOptions>? configureOptions)public static object? Get(this IConfiguration configuration, Type type, Action<BinderOptions>? configureOptions)public static void Bind(this IConfiguration configuration, object? instance, Action<BinderOptions>? configureOptions)