简体   繁体   中英

How to read Configuration value from lowest level value

I am trying to provide some configuration data for my application so that we have simple settings stored in the source control, but our deployment system will replace the Encryption Key in appsettings.json when it deploys.

For development I still want a general key, but for specific users in their secrets I would like to provide a value that they can be sure will be secure.

I have my configuration files setup like this:

appsettings.json

{
  "SystemConfiguration" : {
    "EncryptionKey" :  "weak"
  }
}

appsettings.Development.json

{
  "SystemConfiguration" : {
    "EncryptionKey" :  "devweak"
  }
}

In my user secrets

{
  "SystemConfiguration" : {
    "EncryptionKey" :  "this is a secret"
  }
}

In my controller construction I'm getting the injected IConfiguration configuration .

And then

 public SysConfigController(IConfiguration configuration)
 {
     var result = configuration["SystemConfiguration:EncryptionKey"];
 }

but the value of result is always "weak" unless the higher level settings files don't contain the value at all ( : null ) doesn't work either.

Is there a way that I can retrieve the lowest level value?

Seems your configuration registrations are wrong. The last registration which contains the specific key will be used.

For example in your Program.cs file (assuming you are using ASP.NET Core, otherwise Startup.cs 's constructor for ASP.NET Core 1.x) you can override the registrations (or just add the ones you like when you use the default host builder method):

public static IWebHostBuilder BuildWebHost(string[] args) =>
    new WebHostBuilder()
        .UseKestrel()
        .UseContentRoot(Directory.GetCurrentDirectory())
        .ConfigureAppConfiguration((hostingContext, config) =>
        {
            var env = hostingContext.HostingEnvironment;

            config
                .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
                .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true)
                .AddUserSecrets<Startup>()
                .AddEnvironmentVariables()
                .AddCommandLine(args);
        })
        .UseIISIntegration()
        .UseStartup<Startup>()
        .UseApplicationInsights();

In this example the following have been registered

  • .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true) : Global configuration file
  • .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true) Enviornmentspecific configuration file, ie appsettings.Development.json
  • .AddUserSecrets<Startup>() The user secrets
  • .AddEnvironmentVariables() Environment variables
  • .AddCommandLine(args); Command line parameters

When looking up for a key, the search happens in reverse order. If its defined as command line parameter, it will override all the other keys and values (from environment variable, user secrets, environment specific and global file).

So put the least important file at the beginning and most important (overriding) one at the end.

In this case if its defined in your user secrets, it will override the appsettings.Development.json and appsettings.json provided values.

From the docs

Configuration sources are read in the order that their configuration providers are specified at startup. The configuration providers described in this topic are described in alphabetical order, not in the order that your code may arrange them. Order configuration providers in your code to suit your priorities for the underlying configuration sources.

A typical sequence of configuration providers is:

  • Files (appsettings.json, appsettings..json, where is the app's current hosting environment)
  • User secrets (Secret Manager) (in the Development environment only)
  • Environment variables
  • Command-line arguments

It's a common practice to position the Command-line Configuration Provider last in a series of providers to allow command-line arguments to override configuration set by the other providers.

You can use method ConfigureServices(IServiceCollection services) in Startup.cs.

Describe your setting property in class and bind it. For example:

services.Configure<SystemConfiguration>(options => Configuration.GetSection("SystemConfiguration").Bind(options));

public class SystemConfiguration
{
   public string EncryptionKey{get;set;}
}

Then, you can use DI for geting class

public class SomeClass
{
   private readonly SystemConfiguration _systemConfiguration{get;set;}
   public SomeClass (IOptions<ConfigExternalService> systemConfiguration)
   {
    _systemConfiguration = systemConfiguration;
   }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM