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
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.