Skip to content

Add feature to bind a single element to an array on ConfigurationBinder. #57325

@safern

Description

@safern

Background and motivation

Currently with the JSON Configuration Provider you can do:

{
   "tvshow": {
        "metadata": [
            {
               "name": "PrisonBreak"
            }
         ]
    }
}

and then bind to without any problem:

public class TvShow
{
  public Metadata[] Metadata { get; set; }
}

public class Metadata
{
  public string Name { get; set; }
}

However if we want to bind to this from the xml configuration provider using:

<TvShow>
  <Metadata>
    <Name>Prison Break</Name>
  </Metadata>
</TvShow>

We don't have a way to know that TvShows can contain multiple Metadata elements and that is bound to an array, so we fail to bind when a single element is provided as the key doesn't contain any index in the target array as the binder expects when binding to an array, and we return a Metadata[] with a null object.

In order to fix this we would need to change the binder to account for a key without the index suffix when the child elements don't contain any index (a single element); but this would be breaking for other providers where this is not expected. Consider changing the original JSON so that tvshows is an object with a single metadata, this would bind even though json is not specifying an array:

{
   "tvshow": {
        "metadata": {
            "name": "PrisonBreak"
          }
    }

We want to introduce a new flag to enable this behavior.

API Proposal

namespace Microsoft.Extensions.Configuration
{
     public class BinderOptions
     {
          public bool BindSingleElementsToArray { get; set; }
     }
}

API Usage

With the given xml example above.

var configuration = new ConfigurationBuilder().AddXmlFile("MyFile.xml").Build();

var tvShow = new tvShow();
configuration.Bind(tvShow, o => { o.BindSingleElementsToArray = true });

Risks

This would be a breaking change and could impact perf a little bit but only if the flag is set to true.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions