--- sidebar_position: 13 title: Configuration --- Configuration in ASP.NET Core is done using one or more configuration providers. Configuration providers read configuration data from key-value pairs using a variety of configuration sources: * Settings files, such as `appsettings.json` * Environment Variables * Azure Key Vault * Azure App Setup * Command line arguments * Custom, installed or created providers * Directory files * .NET objects in memory :::caution Configuration and settings files in a Blazor WebAssembly app are visible to users. Don't store application secrets, credentials, or other sensitive data in a WebAssembly application's configuration or files. ::: ## Default configuration ASP.NET Core web apps created with dotnet new or Visual Studio generate the following code: ```csharp public static async Task Main(string[] args) { // highlight-next-line var builder = WebApplication.CreateBuilder(args); ... ``` `CreateBuilder` provides the default application configuration in the following order: * `ChainedConfigurationProvider`: adds an existing `IConfiguration` as a source. In the case of default configuration, adds the host configuration and sets it as the first source of the application configuration. * `appsettings.json` using default JSON provider. * appsettings.`Environment`.json using the default JSON provider. For example, appsettings.**Production**.json and appsettings.**Development**.json. * Application secrets when the application is running in the `Development` environment. * Environment variables using the environment variables configuration provider. * Command line arguments using the command line configuration provider. Configuration providers added later override previous key settings. For example, if `MyKey` is defined in both `appsettings.json` and the environment, the environment value is used. Using the default configuration providers, the command-line configuration provider overrides all other providers. ## appsettings.json Consider the following `appsettings.json` file: ```json title="appsettings.json" { "Position": { "Title": "Editor", "Name": "Joe Smith" }, "MyKey": "My appsettings.json Value", "Logging": { "LogLevel": { "Default": "Information", "Microsoft": "Warning", "Microsoft.Hosting.Lifetime": "Information" } }, "AllowedHosts": "*" } ``` The following code displays several of the previous configuration parameters: ```html title="Config.razor" @page "/config"

Config

MyKey: @Configuration["MyKey"]
Position:Title: @Configuration["Position:Title"]
Position:Name: @Configuration["Position:Name"]
Logging:LogLevel:Default: @Configuration["Logging:LogLevel:Default"]
``` ```csharp title="Config.razor.cs" using Microsoft.Extensions.Configuration; public partial class Config { [Inject] public IConfiguration Configuration { get; set; } } ``` The default `JsonConfigurationProvider` configuration loads in the following order: * appsettings.json * appsettings.`Environment`.json: for example, appsettings.**Production**.json and appsettings.**Development**.json. The environment version of the file is loaded from `IHostingEnvironment.EnvironmentName`. Values ​​in appsettings.`Environment`.json override keys in appsettings.json. For example, by default: * In development, the appsettings.**Development**.json file overrides the values ​​found in appsettings.json. * In production, the appsettings.**Production**.json file overrides the values ​​found in appsettings.json. For example, when deploying the application to Azure. If a configuration value must be guaranteed, use `GetValue`. The preceding example only reads strings and does not support a default value. Using the default configuration of appsettings.json and appsettings.`Environment`.json. files are enabled with `reloadOnChange: true`. Changes made to the appsettings.json and appsettings.`Environment`.json files after the application starts are read by the JSON configuration provider. ## Bind hierarchical configuration data using the options model The recommended way to read related configuration values is using the options pattern. For example, to read the following configuration values: ```json title="appsettings.json" "Position": { "Title": "Editor", "Name": "Joe Smith" } ``` Create the following `PositionOptions` class: ```csharp title="PositionOptions.cs" public class PositionOptions { public const string Position = "Position"; public string Title { get; set; } public string Name { get; set; } } ``` An option class: * Must be non-abstract with a public parameterless constructor. * All public read/write properties of the type are bound. * The fields are not linked. In the preceding code, `Position` is not bound. The `Position` property is used so that the "Position" string does not have to be hard-coded into the application when binding the class to a configuration provider. The following code: * Calls `ConfigurationBinder.Bind` to bind the `PositionOptions` class to the `Position` section. * Displays `Position` configuration data. ```html title="Config.razor" @page "/config"

Config

@if (positionOptions != null) {
Title: @positionOptions.Title
Name: @positionOptions.Name
} ``` ```csharp title="Config.razor.cs" public partial class Config { [Inject] public IConfiguration Configuration { get; set; } private PositionOptions positionOptions; protected override void OnInitialized() { base.OnInitialized(); positionOptions = new PositionOptions(); Configuration.GetSection(PositionOptions.Position).Bind(positionOptions); } } ``` In the preceding code, by default, changes made to the JSON configuration file after the application starts are read. `ConfigurationBinder.Get` binds and returns the specified type. `ConfigurationBinder.Get` may be more convenient than using `ConfigurationBinder.Bind`. The following code shows how to use `ConfigurationBinder.Get` with the `PositionOptions` class: ```csharp title="Config.razor.cs" public partial class Config { [Inject] public IConfiguration Configuration { get; set; } private PositionOptions positionOptions; protected override void OnInitialized() { base.OnInitialized(); positionOptions = Configuration.GetSection(PositionOptions.Position).Get(); } } ``` Another approach to using the options pattern is to bind the section and add it to the dependency injection service container. In the following code, `PositionOptions` is added to the service container with `Configure` and bound to the configuration: ```csharp title="Program.cs" ... builder.Services.Configure(option => { var positionOptions = builder.Configuration.GetSection(PositionOptions.Position).Get(); option.Name = positionOptions.Name; option.Title = positionOptions.Title; }); ... ``` Using the previous code, the following code reads the position options: ```csharp title="Config.razor.cs" public partial class Config { [Inject] public IConfiguration Configuration { get; set; } [Inject] public IOptions OptionsPositionOptions { get; set; } private PositionOptions positionOptions; protected override void OnInitialized() { base.OnInitialized(); positionOptions = OptionsPositionOptions.Value; } } ``` ## User Security and Secrets Instructions for configuration data: * Never store passwords or other sensitive data in configuration provider code or plain text configuration files. The Secret Manager tool can be used to store secrets in development. * Do not use any production secrets in development or test environments. * Specify secrets outside of the project so they can't be inadvertently committed to a source code repository. By default, the user secrets configuration source is listed after the JSON configuration sources. Therefore, user secrets keys take precedence over keys in appsettings.json and appsettings.`Environment`.json. ## Environment Variables Using the default configuration, the `EnvironmentVariablesConfigurationProvider` loads the configuration from environment variable key-value pairs after reading the `appsettings.json` file, appsettings.`Environment`.json and secrets of the user. Therefore, key values ​​read from the environment override values ​​read from `appsettings.json`, appsettings.`Environment`.json and user secrets. The `:` separator does not work with hierarchical environment variable keys on all platforms. `__`, the double underscore, is: * Supported by all platforms. For example, the `:` separator is not supported by `Bash`, but `__` is. * Automatically replaced by a `:` The following `set` commands: * Set the environment keys and values ​​from the previous example to Windows. * Test the settings during use. The dotnet run command should be run in the project directory. ```shell set MyKey="My key from Environment" set Position__Title=Environment_Editor set Position__Name=Environment_Rick dotnet run ``` Previous environment settings: * Are only defined in processes launched from the command window in which they were defined. * Will not be read by browsers launched with Visual Studio. The following `setx` commands can be used to set environment keys and values on Windows. Unlike `set`, the `setx` parameters are preserved. `/M` sets the variable in the system environment. If the `/M` switch is not used, a user environment variable is set. ```shell setx MyKey "My key from setx Environment" /M setx Position__Title Environment_Editor /M setx Position__Name Environment_Rick /M ``` To verify that the previous commands override `appsettings.json` and appsettings.`Environment`.json: * with Visual Studio: quit and restart Visual Studio. * With CLI interface: start a new command window and enter `dotnet run`. One of the great interest of environment variables and the use of it with Docker.