1

I have a .Net6 Console application where I need to retrieve an array of objects from AppSettings.json. Currently I am using an 'options' class to retrieve the array.

class ConfigOpts { class subOpts { /* property accessors */ }, public List<subOpts> SubOpts {get;set;}}

and

var builder = new ConfigurationBuilder().SetBasePath(...).AddJsonFile(..);
IConfiguration config = build.build();
ConfigOpts opts = new ConfigOpts();
config.GetSection("ConfigOpts").Bind(opts);

Gives me an opts objects containing a list of subOpts.

One of the sub opt fields needs to be decrypted and encrypted at load/save time. So I would like to use a CustomConfigProvider and do the decrypt in the Load() method, and encrypt in a CreateSave() method.

I have amended my code to add a new class ConfigOptsProvider:ConfigurationProvider,IConfigurationSource and created an extension method AddConfigOptsProvider which is called on the binder above.

This works and I can hit the load() function in the config provider.

My two questions are:-

In the Load Method, how do I read the AppSettings.json file (I've looked for documentation but found examples for reading databases and other files but none for AppSettings.json).

Also, how do I call the CreateSave() function later?

Regards.

Update I noticed as I have the ConfigOpts class that allows me to access the settings in a typed manner, it might be useful to try and use it.

In the load I have tried adding the following to the Load() method.

((IConfiguration)this).GetSection("ConfigOpts").Bind(_configOptions);

This code is what I originally used (in the first example above). Unfortunately one cant cast to IConfiguration.

It would be great if this is all I need to do.

AndyW
  • 191
  • 1
  • 11
  • 1
    First of all will your createsave write back to appsettings.json? – AliK Jul 04 '22 at 23:42
  • 1
    that is the intention – AndyW Jul 05 '22 at 00:53
  • 1
    As an addition if it is useful to a solution. I have added the builder as a parameter to the ConfigOptsProvider and stored as an internal variable. It gives the load() function access to the underlying fileProvider. – AndyW Jul 05 '22 at 00:55
  • 1
    Check this answer https://stackoverflow.com/a/72773955/9247039 – CodingMytra Jul 05 '22 at 04:11
  • thanks for your reply. I'll look at it as an option - it would be great if I did not need to desterilize the whole appsettings though. I have updated my original post to show my current thinking. – AndyW Jul 05 '22 at 19:16
  • @CodingMytra - if you can post a basic answer I can mark it as such. I've posted my answer based on your comment. – AndyW Jul 06 '22 at 00:35

1 Answers1

0

My solution was to use the System.Text.Json.Nodes namespace to read the appsettings files as JSON and them process.

I ended up with this routine in my Load() method which populated an internal custom data class with the required data, I can then access using a Get method. Because of the number of fields in the data Class, it meant I cannot use the provided Data property to return the result.

var fp = _fileProvider.GetFileInfo("appsettings.json")
using (Stream s = fp.CreateReadStream())
{
    var co = JsonDocument.Parse(s)?.Deserialize<Dictionary<String,Object>>?.Where(str => str.Key == "ConfigOpt").FirstOrDefault();

    var subObts = JSonNode.Parse(co.GetValueOrDefault().Value.ToString())["SUbOpts"];
    foreach(JsonNOde opt in subOpts.AsArray())
    {
         var optName = opt["name"]?.AsValue; 
    }

}

I have removed most of the null checks and the filesystem watcher and also there isn't a check for different environments (appsettings files). The structure is ConfigOpt:SubOpts:opt:property where SubOpts is an array of opts.

AndyW
  • 191
  • 1
  • 11