5

I have the following appSettings.json file:

  "SundrySettings": {

    "CookieName": "Cookie",

    "AccessGroup": "Software Development",

    "Terminals" :  {
      "Raucherplatz" : "tablet1.local",
      "Service" :      "tablet2.local",  
      "Technik" :      "tablet3.local",  
      "Technik" :      "tablet4.local",  
      "Container" :    "tablet5.local"
    }
  }
}

That I would like to load into the following structure:


    public class Terminal
    {
        public string Name;
        public string Description;
    }

    public class SundryOptions
    {
        public string CookieName { get; set; } = "dummy";
        public string HRAccessGroup { get; set; } = "dummy";
        public List<Terminal> Terminals;
    }

that I would try to load using the following commands:

ServiceProvider sp = services.BuildServiceProvider();
SundryOptions sundryOptions = sp.GetService<IOptions<SundryOptions>>().Value;

The problem I have is that using Property Initialisers never sets the Terminals List correctly. I do need a list (and not a Dictionary) as the enties could be double i.e. Technik in my example.

I am assuming that I have some error in the Class -> I would be happy for any pointers.

8
  • 3
    Don't use a List. What you posted there is a dictionary, typically represented as an object. It's not a list. You can't parse it as a list Commented Feb 14, 2019 at 14:11
  • I did try sundryOptions.Terminals = Configuration.GetSection("SundrySettings:Terminals").Get<List<Terminal>>(); in ConfigureServices but that did not work unfortunately Commented Feb 14, 2019 at 14:18
  • @PanagiotisKanavos I did try a dictionary as well but still get null for the value of Terminals Commented Feb 14, 2019 at 14:19
  • Using which class? The Terminal class you posted doesn't match the Terminal in the json file. Technik is a setting, not some name in a name/value pair. The path to that setting is SundrySettings::Terminals::Service and its value is tablet2.local. I suspect you're trying to use the Configuration subsystem like a database? Commented Feb 14, 2019 at 14:29
  • That means Technik will throw too, because it's not unique. That's how the Configuration system works - each setting has a specific path and a value. Those settings can be mapped to strongly-typed objects. If the objects match the settings, this is trivial. If not, you'll have to write code to map one to the other Commented Feb 14, 2019 at 14:32

3 Answers 3

9

Do as follows:

var cookieName = Configuration.GetSection("SundrySettings:CookieName").Value;
var accessGroup = Configuration.GetSection("SundrySettings:AccessGroup").Value;
var terminals = Configuration.GetSection("SundrySettings:Terminals").GetChildren();

List<Terminal>  terminalList = new List<Terminal>();

foreach (var keyValuePair in terminals)
{
     Terminal termial = new Terminal()
     {
          Name = keyValuePair.Key,
          Description = keyValuePair.Value
     };

     terminalList.Add(termial);
}

SundryOptions sundryOption = new SundryOptions()
{
            CookieName = cookieName,
            HRAccessGroup = accessGroup,
            Terminals = terminalList
};

I have checked with the exact configuration you provided and it works perfectly.

Sign up to request clarification or add additional context in comments.

Comments

5

Implement processing of configuration as following somewhere approporiate like this:

var cookieName = 
Configuration.GetSection("SundrySettings:CookieName").Value;
var accessGroup = Configuration.GetSection("SundrySettings:AccessGroup").Value;

var terminals = new List<Terminal>()

var terminalSections = this.Configuration.GetSection("Terminals").GetChildren();
foreach (var item in terminalSections)
{
    terminals.Add(new Terminal 
    {
           // perform type mapping here 
    });
}

SundryOptions sundryOption = new SundryOptions()
{
        CookieName = cookieName,
        HRAccessGroup = accessGroup,
        Terminals = terminalList
};

Of course there could be shorter version, but you can start from here.

3 Comments

Brother fully copied my answer :) Okay! no problem. :)
Nope mate. I answered first you just added the boilerplate to that... :) then I filled the boilerplate in. But if you have hard feelings just vote it down.
No no! I don't feel envy to anybody so that I shall down vote. It's ok. Best of luck. By the way there is edit history 😜 your first answer was wrong too. Ok. Keep going.
2

If Terminals is a list, in your appSettings, it should be an array, not an object.

  "Terminals" :  [
  "Raucherplatz" : "tablet1.local",
  "Service" :      "tablet2.local",  
  "Technik" :      "tablet3.local",  
  "Technik" :      "tablet4.local",  
  "Container" :    "tablet5.local"
]

1 Comment

Thank you for the info -> your example is missing curly brackets within the [ ] i.e. like this: [ { ... } ]

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.