Skip to content

Support repeated elements in XML configuration #36561

@amoerie

Description

@amoerie

When repeating an element in appsettings.xml, an exception occurs because a duplicate key will be produced

Functional impact

Configuration that is possible from JSON is not always possible from XML, for example configuring Serilog sinks are configured as an array in JSON. Arrays in XML are not supported by the XmlConfigurationProvider.

Minimal repro steps

  1. Create a .NET Core 2.0 application with an appsettings.xml file
  2. Fill in the appsettings.xml file like this:
          <settings>
            <DefaultConnection>
                <ConnectionString>TestConnectionString1</ConnectionString>
                <Provider>SqlClient1</Provider>
            </DefaultConnection>
            <DefaultConnection>
                <ConnectionString>TestConnectionString2</ConnectionString>
                <Provider>SqlClient2</Provider>
            </DefaultConnection>
          </settings>
  1. Load this file with the following snippet in Program.cs or Startup.cs
new ConfigurationBuilder()
      .SetBasePath(Directory.GetCurrentDirectory())
      .AddXmlFile($"appsettings.xml")
      .Build();
  1. Startup the application

Expected result

Unique keys should be produced for each entry in the XML settings

I would expect the following output:

"DefaultConnection:0:ConnectionString"="TestConnectionString1"
"DefaultConnection:0:Provider"="SqlClient1"
"DefaultConnection:1:ConnectionString"="TestConnectionString2"
"DefaultConnection:1:Provider"="SqlClient2"

Actual result

System.FormatException occurred
  HResult=0x80131537
  Message=A duplicate key 'DefaultConnection:ConnectionString' was found.
  Source=<Cannot evaluate the exception source>

Further technical details

I took the liberty of actually implementing something like this, the full source code is available at https://github.com/amoerie/configuration.xml

I've added extra unit tests to cover the various scenarios (turns out there's a magical 'Name' attribute with some special rules there) and all tests seem to be green.

I refrained from immediately creating a pull request, because nobody (besides myself) was asking for this and it is actually a considerable refactoring of the existing code, so it seemed better to start a conversation first. Thank you for your consideration.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions