Skip to content

Fix ConfigurationBinder failing to bind empty array to constructor parameter#126470

Draft
svick wants to merge 2 commits intodotnet:mainfrom
svick:configuration-binder-empty-array
Draft

Fix ConfigurationBinder failing to bind empty array to constructor parameter#126470
svick wants to merge 2 commits intodotnet:mainfrom
svick:configuration-binder-empty-array

Conversation

@svick
Copy link
Copy Markdown
Member

@svick svick commented Apr 2, 2026

Fix #126312

When binding an empty JSON array ([]) to a constructor parameter of type string[], ConfigurationBinder threw:

ArgumentException: Object of type 'System.String' cannot be converted to type 'System.String[]'.

Root Cause

In BindParameter, the BindingPoint was initialized with config.GetSection(parameterName).Value — the config section's string value. For an empty JSON array [], this value is "" (empty string). This caused BindInstance to skip the empty-collection creation code path, which requires bindingPoint.Value to be null. The empty string value was then returned as the parameter value, causing the ArgumentException when the constructor was invoked via reflection.

For comparison, property binding correctly initializes the BindingPoint with property.GetValue(instance) (typically null for uninitialized arrays), so the empty-collection path works.

Fix

Remove the initialValue argument from the BindingPoint constructor in BindParameter, so it defaults to null. This is correct because:

  • Constructor parameters have no "existing value" to preserve
  • The config section's value is already read inside BindInstance from the config parameter directly — passing it as initialValue was redundant
  • For simple types (string, int, etc.), TryConvertValue succeeds and overwrites the initial value regardless

Test

Added TestBindingEmptyArrayToConstructorParameter — reproduces the exact scenario from the issue (empty JSON array bound to a string[] constructor parameter with a null default).

…rameter

When binding constructor parameters, the BindingPoint was incorrectly
initialized with the config section's string value. For an empty JSON
array [], this value is an empty string, which prevented BindInstance
from entering the empty-collection handling code path (which requires
bindingPoint.Value to be null).

For property binding, the BindingPoint is initialized with the existing
property value (typically null for uninitialized arrays). Constructor
parameters have no existing value, so the initial value should be null
(the default), not the config section's string value. The config
section's value is already read inside BindInstance from the config
parameter directly.

Fix dotnet#126312

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@dotnet-policy-service
Copy link
Copy Markdown
Contributor

Tagging subscribers to this area: @dotnet/area-extensions-configuration
See info in area-owners.md if you want to be subscribed.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Fixes ConfigurationBinder throwing when binding an empty JSON array ([]) to an array-typed constructor parameter (e.g., string[]), by ensuring constructor-parameter binding starts from a null binding point so the existing “empty collection” binding path can run.

Changes:

  • Update BindParameter to stop seeding the BindingPoint with the configuration section’s string value.
  • Add a regression test covering empty-array binding to an optional array constructor parameter.
  • Add a small helper test type used by the new regression test.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.

File Description
src/libraries/Microsoft.Extensions.Configuration.Binder/src/ConfigurationBinder.cs Adjusts constructor-parameter binding to initialize the BindingPoint without a config-derived initial string value.
src/libraries/Microsoft.Extensions.Configuration.Binder/tests/Common/ConfigurationBinderTests.cs Adds a regression test for binding [] into an array constructor parameter.
src/libraries/Microsoft.Extensions.Configuration.Binder/tests/Common/ConfigurationBinderTests.TestClasses.cs Introduces a helper type with an optional array constructor parameter for the new test.
Comments suppressed due to low confidence (1)

src/libraries/Microsoft.Extensions.Configuration.Binder/src/ConfigurationBinder.cs:1146

  • In BindParameter, the local is named propertyBindingPoint, but it actually represents a constructor-parameter binding point. Renaming it to something like parameterBindingPoint would improve readability and avoid confusion with the real property-binding path (BindProperty).
            var propertyBindingPoint = new BindingPoint(isReadOnly: false);

            BindInstance(
                parameter.ParameterType,
                propertyBindingPoint,
                config.GetSection(parameterName),

@tarekgh tarekgh added this to the 11.0.0 milestone Apr 2, 2026
Copy link
Copy Markdown
Member

@tarekgh tarekgh left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @svick for fixing the issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

ConfigurationBinder fails to bind empty array in Net 10.0

3 participants