Skip to content

Commit fab73a8

Browse files
authored
Config binding breaking change (dotnet#36434)
1 parent 1707786 commit fab73a8

File tree

3 files changed

+97
-1
lines changed

3 files changed

+97
-1
lines changed

docs/core/compatibility/8.0.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,10 +71,11 @@ If you're migrating an app to .NET 8, the breaking changes listed here might aff
7171
## Extensions
7272

7373
| Title | Type of change | Introduced |
74-
| --------------------------------------------------------------------------------------------------------------------------------- | ----------------- | ---------- |
74+
|-----------------------------------------------------------------------------------------------------------------------------------|-------------------|------------|
7575
| [ActivatorUtilities.CreateInstance behaves consistently](extensions/8.0/activatorutilities-createinstance-behavior.md) | Behavioral change | Preview 1 |
7676
| [ActivatorUtilities.CreateInstance requires non-null provider](extensions/8.0/activatorutilities-createinstance-null-provider.md) | Behavioral change | Preview 1 |
7777
| [ConfigurationBinder throws for mismatched value](extensions/8.0/configurationbinder-exceptions.md) | Behavioral change | Preview 1 |
78+
| [Empty keys added to dictionary by configuration binder](extensions/8.0/dictionary-configuration-binding.md) | Behavioral change | Preview 5 |
7879
| [HostApplicationBuilderSettings.Args respected by HostApplicationBuilder ctor](extensions/8.0/hostapplicationbuilder-ctor.md) | Behavioral change | Preview 2 |
7980

8081
## Globalization
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
---
2+
title: "Breaking change: Empty keys added to dictionary by configuration binder"
3+
description: Learn about the .NET 8 breaking change in .NET extensions where empty keys are now added to dictionary types by the configuration binder.
4+
ms.date: 07/27/2023
5+
---
6+
# Empty keys added to dictionary by configuration binder
7+
8+
In previous versions, when configuration was bound to a dictionary type, any keys without corresponding values in the configuration were skipped and weren't added to the dictionary. The behavior has changed such that those keys are longer skipped but instead automatically created with their default values. This change ensures that all keys listed in the configuration will be present within the dictionary.
9+
10+
## Version introduced
11+
12+
.NET 8 Preview 5
13+
14+
## Previous behavior
15+
16+
Previously, empty keys in the configuration were skipped when bound to a dictionary type. Consider the following configuration string and binding code.
17+
18+
```csharp
19+
var json = @"{
20+
""Queues"": {
21+
""q1"": {
22+
""V"": 1
23+
},
24+
""q2"": {
25+
""V"": 2
26+
},
27+
""q3"": {
28+
}
29+
}
30+
}";
31+
```
32+
33+
```csharp
34+
public class Q
35+
{
36+
public Dictionary<string, QueueValue> Queues { get; set; } = new();
37+
}
38+
39+
public class QueueValue
40+
{
41+
public int V { get; set; }
42+
}
43+
44+
var configuration = new ConfigurationBuilder()
45+
.AddJsonStream(StringToStream(json))
46+
.Build();
47+
48+
Q options = new Q();
49+
configuration.Bind(options);
50+
foreach (var kvp in options.Queues)
51+
{
52+
Console.WriteLine($"{kvp.Key}: {kvp.Value.V}");
53+
}
54+
```
55+
56+
Previously, you'd see the following output (notice that key `q3` is missing):
57+
58+
```output
59+
q1: 1
60+
q2: 2
61+
```
62+
63+
## New behavior
64+
65+
Starting in .NET 8, empty configuration keys are added to the dictionary with their default value during configuration binding.
66+
67+
Consider the code from the [previous behavior](#previous-behavior) section, which now outputs the following text showing that `q3` was added to the dictionary with its default value:
68+
69+
```output
70+
q1: 1
71+
q2: 2
72+
q3: 0
73+
```
74+
75+
## Type of breaking change
76+
77+
This change is a [behavioral change](../../categories.md#behavioral-change).
78+
79+
## Reason for change
80+
81+
This user-requested change ensures that all keys listed in the configuration are present within the dictionary. Having all keys present streamlines the process and avoids potential issues with missing keys.
82+
83+
## Recommended action
84+
85+
Verify and adapt your application logic to accommodate the presence of the newly created dictionary entries with empty values. If the new behavior is undesirable, remove empty-value entries from the configuration. By eliminating these entries, no dictionary entries with empty values will be added during the binding process.
86+
87+
## Affected APIs
88+
89+
- <xref:Microsoft.Extensions.Configuration.ConfigurationBinder?displayProperty=fullName>
90+
- [IConfigurationRoot extension methods](xref:Microsoft.Extensions.Configuration.IConfigurationRoot#extension-methods)
91+
- <xref:Microsoft.Extensions.DependencyInjection.OptionsConfigurationServiceCollectionExtensions?displayProperty=fullName>

docs/core/compatibility/toc.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,8 @@ items:
7676
href: extensions/8.0/activatorutilities-createinstance-null-provider.md
7777
- name: ConfigurationBinder throws for mismatched value
7878
href: extensions/8.0/configurationbinder-exceptions.md
79+
- name: Empty keys added to dictionary by configuration binder
80+
href: extensions/8.0/dictionary-configuration-binding.md
7981
- name: HostApplicationBuilderSettings.Args respected by constructor
8082
href: extensions/8.0/hostapplicationbuilder-ctor.md
8183
- name: Globalization
@@ -1278,6 +1280,8 @@ items:
12781280
href: extensions/8.0/activatorutilities-createinstance-null-provider.md
12791281
- name: ConfigurationBinder throws for mismatched value
12801282
href: extensions/8.0/configurationbinder-exceptions.md
1283+
- name: Empty keys added to dictionary by configuration binder
1284+
href: extensions/8.0/dictionary-configuration-binding.md
12811285
- name: HostApplicationBuilderSettings.Args respected by constructor
12821286
href: extensions/8.0/hostapplicationbuilder-ctor.md
12831287
- name: .NET 7

0 commit comments

Comments
 (0)