1

If I have a configuration file with the following list of values in the configuration.

The configuration file is an xml file...

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <Employees foor="bar">
    <Employee name="aaa" surname="bbb"/>
    <Employee name="ddd" surname="eee"/>
    <Employee name="fff" surname="ggg"/>
  </Employees>
</configuration>

Using Microsoft.Extensions.Configuration, I try to load the xml as follow

public class Employee
{
  public string Name{get;set;}
  public string Surname{get;set;}
}
...
public class Employees
{
  public List<Employee> Employees{ get; set;}

  public string Foo {get; set; }
}
...
var configurationBuilder = new ConfigurationBuilder()
AddXmlFile(path: "\\MyConfig.config")
        .Build();

var employees = configurationBuilder.GetSection("Employees").Get<Employees>()
...

But the list returned is null, I am able to read single values if I move them up one level, but I would like to read a list of values inside my list.

It also does not work if I have a class within a class

For example

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <Outer foor="bar">
    <Inner name="aaa" surname="bbb"/>
  </Outer>
</configuration>
FFMG
  • 1,208
  • 1
  • 10
  • 24

2 Answers2

2

Scenario 1 - keeping the Employees xml wrapper element

In order to load the Employee xml elements, the corresponding property on the wrapper class must have the same name; so change Employees to Employee.

Lets also correct that foor attribute in the xml from <Employees foor="bar"> to <Employees foo="bar"> since the Employees class has a Foo property.

public class Employees
{
    public List<Employee> Employee { get; set;}

    public string Foo { get; set; }
}

Below shows the result of retrieving the employees section.

var employees = configurationBuilder.GetSection("Employees").Get<Employees>();

enter image description here

If you don't like the singular Employee property, then you can make that one private, but have to take that into account on retrieval.
You then define a public Employees as a 'pass through' property.
Note that you can't have an Employees class and a property with that same name because of an CS0542 compile error, which is to be fixed by renaming that class, to e.g. Staff.

public class Staff
{
    private List<Employee> Employee { get; set; }

    public List<Employee> Employees => Employee;

    public string Foo { get; set; }
}

var employees = configurationBuilder.GetSection("Employees")
    .Get<Staff>(o => o.BindNonPublicProperties = true);

Scenario 2 - not using an Employees xml wrapper element

Declare the xml as below.

<configuration>
  <Employee name="aaa" surname="bbb" />
  <Employee name="ddd" surname="eee" />
  <Employee name="fff" surname="ggg" />
</configuration>

Retrieve the employees as a list of Employee.

var employees = configurationBuilder.GetSection("Employee").Get<List<Employee>>();
pfx
  • 20,323
  • 43
  • 37
  • 57
-1

This is one of the way, you can do it as shown:

<util:list id="myColours" value-type="java.lang.String">
        <value>red</value>
        <value>green</value>
        <value>blue</value>
        <value>yellow</value>
        <value>brown</value>
        <value>orange</value>
    </util:list>
Umesh Sulakude
  • 286
  • 2
  • 14