1

I'm trying to bind a JSON file to a model for configuration settings in a dotnet core project.

The json looks like:

"Settings": {
  "Values": [
  { "Value1": "1" },
  { "Value2": "2" }
]}

My model looks like:

public class Settings
{
    public List<Value> Values{ get; set; }
}

public class Value
{
    public string Value1 { get; set; }

    public string Value2 { get; set; }
}

I bind with the following:

var settings = _configuration.GetSection("Settings").Get<Settings>();

But this results in settings containing two Value objects in the list - the first Value object has Value1 = 1 & Value2 = null, and the second Value object has Value1 = null & Value2 = 2. How can I bind such that it settings only has one Value object in Values with both properties populated?

This is not the same as suggested here: https://stackoverflow.com/questions/51488845/how-to-read-a-string-array-in-appsettings-json

This is because each object in the array in this case have different properties whereas in the proposed duplicate all objects are consistent.

9
  • If you want only one Value object, define only one Value object: "Values": [ { "Value1": "1", "Value2": "2" } ] Commented May 28, 2019 at 20:06
  • @EdPlunkett in the Json file? Commented May 28, 2019 at 20:07
  • Yes. What you're getting now is exactly what the current JSON describes. Commented May 28, 2019 at 20:08
  • @EdPlunkett - Is there any other way to achieve this without changing the JSON? Commented May 28, 2019 at 20:10
  • You could write some weird code to condense/coalesce/whatever the list into a single object, I guess. You can write code to do just about anything. How did it get this way? Why do you want to do this? Commented May 28, 2019 at 20:11

2 Answers 2

1

Ok, so it actually needs to look like:

public class Settings
{
    public List<Dictionary<string, string>> Values{ get; set; }
}

Since the JSON Values is actually an array of dictionaries.

For the following to work:

public class Settings
{
    public Dictionary<string, string> Values{ get; set; }
}

The JSON would need to look like:

"Settings": {
    "Values": {    
        "Value1": "1",
        "Value2": "2"
    }
}
Sign up to request clarification or add additional context in comments.

4 Comments

You're right, but I have no idea why, since in JSON it is simply an array of KeyValuePair
But that's the same isn't it - an array of KeyValuePair is an array of dictionaries? But it was not easy to spot - I tried the dictionary earlier today but missed that it was an array of them
A dictionary is an array itself, it's a collection of KeyValuePair
true, I guess the JSON here is an array of JSON objects - those objects being KeyValuePairs can be represented with a dictionary in C# - but it is still an array of said objects
1

The easiest way to get your values is probably to make your Class look like this:

public class Settings
{
    public Dictionary<string, string>[] Values{ get; set; }
}

This will be parsed as an Array of Dictionary items, where each item will contain only 1 key-value of your Values.

UPDATE:

You can add a function inside your Settings class to get all the settings as 1 dictionary:

public Dictionary<string, string> GetSettings()
{
    var settingsValues = new Dictionary<string, string>();
    foreach (var valueDict in Values)
    {
        foreach (var setting in valueDict)
        {
            settingsValues.Add(setting.Key, setting.Value);
        }
    }
    return settingsValues;
}

6 Comments

Isn't that going to want curly braces around the contents of "Values", not square brackets?
It's a dictionary, which will be an array of key-value objects, so it would be exactly as this JSON mentioned in the Question.
I was testing with Newtonsoft. How should I test?
This throws {System.InvalidOperationException: Cannot create instance of type 'System.String' because it is missing a public parameterless constructor.
@MayerSpitzer and Ed Plunkett - Got it! Thanks again for the help
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.