dotnet / dotnet/runtime

Provide more granular control over when the configuration binder throws exceptions.

Open
#121,586 3 comments 1 reaction 0 assignees View on GitHub
api-suggestion area-Extensions-Configuration feature-request
Dominant language
C#
Stars
18.3k
Forks
5.6k
PR merge metrics
PR metrics pending

Description

The default behavior of the configuration binder is to **suppress binding errors** and continue without throwing exceptions. However, the binder provides the [`ErrorOnUnknownConfiguration`](https://learn.microsoft.com/en-us/dotnet/api/microsoft.extensions.configuration.binderoptions.erroronunknownconfiguration?view=net-9.0-pp#microsoft-extensions-configuration-binderoptions-erroronunknownconfiguration) option, which allows it to surface binding issues by throwing exceptions when errors occur.

There are a few issues with the current behavior. Consider the following example:

```csharp
string jsonConfig = @"
{
""Options"": {
""IntValue"" : 2.5,
""ReadOnlyDictionaryValue"": ""Wrong Dictionary Value"",
""UnknownProperty"" : ""This should cause an error""
}
}";

var config = new ConfigurationBuilder()
.AddJsonStream(new MemoryStream(Encoding.UTF8.GetBytes(jsonConfig)))
.Build()
.GetSection("Options");

Options? options = config.Get();

public class Options
{
public int IntValue { get; set; }
public IReadOnlyDictionary? ReadOnlyDictionaryValue { get; set; }
}
```

In this configuration:

* `IntValue` is defined as an integer, but the configuration provides `2.5`.
* `ReadOnlyDictionaryValue` is a dictionary, but the configuration value is a string.
* `UnknownProperty` doesn’t exist in the `Options` class.

When running this code **without** setting `ErrorOnUnknownConfiguration`:

* An exception `System.InvalidOperationException: Failed to convert configuration value '2.5' at 'Options:IntValue' to type 'System.Int32'.` is thrown for `IntValue`. This is unexpected since `ErrorOnUnknownConfiguration` is not set.
* Fixing `IntValue` and rerunning results in **no exception**, even though the configuration still contains invalid or extra values such as `ReadOnlyDictionaryValue` and `UnknownProperty`.

When **enabling** `ErrorOnUnknownConfiguration`, for example:

```csharp
Options? options1 = config.Get(o => o.ErrorOnUnknownConfiguration = true);
```

we see:

* `System.InvalidOperationException: 'ErrorOnUnknownConfiguration' was set on the provided BinderOptions, but the following properties were not found on the instance of Options: 'UnknownProperty'`.

If `UnknownProperty` is removed from the configuration, a different exception appears:

* `System.InvalidOperationException: Failed to convert configuration value 'Wrong Dictionary Value' at 'Options:ReadOnlyDictionaryValue' to type 'System.Collections.Generic.IReadOnlyDictionary'2[System.String,System.String]'.`

This behavior shows that when `ErrorOnUnknownConfiguration` is enabled, the binder throws exceptions for both:

1. Configuration keys with no matching properties, and
2. Invalid configuration values that cannot be bound to their target type.

We’ve seen cases where users only want exceptions for invalid values (case 2), **not** for unknown keys (case 1).

---

### Proposed Improvements

1. **Introduce a new binder option**, for example `ErrorOnInvalidConfigurationValue`, which throws exceptions **only** when the configuration contains invalid values that cannot be bound (e.g., `IntValue` or `ReadOnlyDictionaryValue`), but **not** when the configuration contains extra keys (e.g., `UnknownProperty`).

2. **Ensure no exceptions are thrown** when neither `ErrorOnUnknownConfiguration` nor the proposed `ErrorOnInvalidConfigurationValue` is enabled, this should be consistent for all properties (including `IntValue` in the example).

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.