diff --git a/aspnetcore/fundamentals/configuration/index.md b/aspnetcore/fundamentals/configuration/index.md index 0b5ed31964f8..961db50a82c6 100644 --- a/aspnetcore/fundamentals/configuration/index.md +++ b/aspnetcore/fundamentals/configuration/index.md @@ -1,605 +1,980 @@ --- title: Configuration in ASP.NET Core author: tdykstra -description: Learn how to use the Configuration API to configure AppSettings in an ASP.NET Core app. +description: Learn how to use the Configuration API to configure app settings in an ASP.NET Core app. monikerRange: '>= aspnetcore-3.1' ms.author: tdykstra ms.custom: mvc -ms.date: 06/28/2025 +ms.date: 10/21/2025 uid: fundamentals/configuration/index --- - # Configuration in ASP.NET Core -By [Rick Anderson](https://twitter.com/RickAndMSFT) and [Kirk Larkin](https://twitter.com/serpent5) + -Application configuration in ASP.NET Core is performed using one or more [configuration providers](#cp). Configuration providers read configuration data from key-value pairs using a variety of configuration sources: +[!INCLUDE[](~/includes/not-latest-version.md)] + +App configuration in ASP.NET Core is performed using one or more [configuration providers](#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 +* Environment variables, including Azure App configuration * Azure Key Vault -* Azure App Configuration * Command-line arguments * Custom providers, installed or created -* Directory files * In-memory .NET objects This article provides information on configuration in ASP.NET Core. For information on using configuration in non-ASP.NET Core apps, see [.NET Configuration](/dotnet/core/extensions/configuration). -For Blazor configuration guidance, which adds to or supersedes the guidance in this node, see . +For additional Blazor configuration guidance, which adds to or supersedes the guidance, see . + +This article only pertains to app configuration. Configuration sources not primarily covered by this article include: + +* Launch settings files (`launch.json`/`launchSettings.json`), which are tooling configuration files for the Development environment. For more information, see . Some details on launch settings are covered by this article in the [Launch settings override environment variable settings](#launch-settings-override-environment-variable-settings) section. +* `web.config`, which is a server configuration file for [Internet Information Services (IIS)](https://www.iis.net/). For more information, see and . + +For more information on migrating app configuration from earlier versions of ASP.NET, see . + +[!INCLUDE[](~/includes/managed-identities-conn-strings.md)] + +Examples in this article use *primary constructors*, available in C# 12 (.NET 8) or later. For more information, see [Declare primary constructors for classes and structs (C# documentation tutorial)](/dotnet/csharp/whats-new/tutorials/primary-constructors) and [Primary constructors (C# Guide)](/dotnet/csharp/programming-guide/classes-and-structs/instance-constructors#primary-constructors). + +## Read configuration values + +Configuration is typically read by resolving the service ( namespace) and using the key of configuration key-value pairs to obtain a configuration value. + +The following Razor component code shows how a configuration value, a technical contact email address, is obtained from configuration by the key `TechnicalContactEmail`. -## Application and Host Configuration +```razor +@inject IConfiguration Config -ASP.NET Core apps configure and launch a *host*. The host is responsible for app startup and lifetime management. The ASP.NET Core templates create a which contains the host. While some configuration can be done in both the host and the application configuration providers, generally, only configuration that is necessary for the host should be done in host configuration. +Technical Contact: @Config["TechnicalContactEmail"] +``` + +## App and host configuration -Application configuration is the highest priority and is detailed in the next section. [Host configuration](#host) follows application configuration, and is described in this article. +ASP.NET Core apps configure and launch a *host*. The host is responsible for app startup and lifetime management. Host configuration key-value pairs are included in the app's configuration. Although you can perform some app configuration with host configuration providers, we only recommend performing configuration that's necessary for the host in host configuration. - +App configuration is the highest priority. For more information on how the configuration providers are used when the host is built and how configuration sources affect host configuration, see . -### Default application configuration sources +## Default app configuration sources -ASP.NET Core web apps created with [dotnet new](/dotnet/core/tools/dotnet-new) or Visual Studio generate the following code: +:::moniker range=">= aspnetcore-6.0" + +ASP.NET Core web apps call to initialize a new instance of the class with preconfigured defaults: ```csharp var builder = WebApplication.CreateBuilder(args); ``` - +For more information, see . -[WebApplication.CreateBuilder](xref:Microsoft.AspNetCore.Builder.WebApplication.CreateBuilder%2A) initializes a new instance of the class with preconfigured defaults. The initialized `WebApplicationBuilder` (`builder`) provides default configuration for the app in the following order, from highest to lowest priority: +:::moniker-end -1. Command-line arguments using the [Command-line configuration provider](#command-line). -1. Non-prefixed environment variables using the [Non-prefixed environment variables configuration provider](#evcp). -1. [User secrets](xref:security/app-secrets) when the app runs in the `Development` environment. -1. `appsettings.{Environment}.json` using the [JSON configuration provider](#jcp). For example, `appsettings.Production.json` and `appsettings.Development.json`. -1. [appsettings.json](#appsettingsjson) using the [JSON configuration provider](#jcp). -1. A fallback to the host configuration described in the [next section](#host). +:::moniker range="< aspnetcore-6.0" -Note: `WebApplication.CreateBuilder(args)` should only be called once in apps relying on IIS in-process hosting. +Apps created from an ASP.NET Core web app project template call to initialize a new instance of the class with preconfigured defaults: - +```csharp +Host.CreateDefaultBuilder(args) +``` -### Default host configuration sources +:::moniker-end -The following list contains the default host configuration sources from highest to lowest priority for : +Default app configuration is loaded in the following order, from highest to lowest priority: -1. Command-line arguments using the [Command-line configuration provider](#command-line) -1. `DOTNET_`-prefixed environment variables using the [Environment variables configuration provider](xref:Microsoft.Extensions.Configuration.EnvironmentVariables.EnvironmentVariablesConfigurationProvider). -1. `ASPNETCORE_`-prefixed environment variables using the [Environment variables configuration provider](xref:Microsoft.Extensions.Configuration.EnvironmentVariables.EnvironmentVariablesConfigurationProvider). +1. Command-line arguments using the [Command-line Configuration Provider](#command-line). +1. Environment variables ***not*** prefixed by `ASPNETCORE_` or `DOTNET_` using the [Environment Variables Configuration Provider](#environment-variables-configuration-provider). +1. [User secrets](xref:security/app-secrets) when the app runs in the `Development` environment using the [File Configuration Provider](#file-configuration-provider). +1. [Environmental app settings file configuration](#app-settings-file-configuration-appsettingsjson-appsettingsenvironmentjson) via `appsettings.{ENVIRONMENT}.json`, where the `{ENVIRONMENT}` placeholder is the app's [environment](xref:fundamentals/environments), using the [JSON Configuration Provider](#json-configuration-provider). For example, `appsettings.Production.json` is used in production, and `appsettings.Development.json` is used during development. +1. [General app settings file configuration](#app-settings-file-configuration-appsettingsjson-appsettingsenvironmentjson) via `appsettings.json` using the [JSON Configuration Provider](#json-configuration-provider). +1. Fallback [host configuration](#default-host-configuration-sources). -For the [.NET Generic Host](xref:fundamentals/host/generic-host) and [Web Host](xref:fundamentals/host/web-host), the default host configuration sources from highest to lowest priority is: +:::moniker range=">= aspnetcore-6.0" -1. `ASPNETCORE_`-prefixed environment variables using the [Environment variables configuration provider](xref:Microsoft.Extensions.Configuration.EnvironmentVariables.EnvironmentVariablesConfigurationProvider). -1. Command-line arguments using the [Command-line configuration provider](#command-line) -1. `DOTNET_`-prefixed environment variables using the [Environment variables configuration provider](xref:Microsoft.Extensions.Configuration.EnvironmentVariables.EnvironmentVariablesConfigurationProvider). +> [!NOTE] +> We don't recommend calling more than once solely for the purpose of obtaining configuration values at runtime. We recommend using a (for example: `builder.Configuration`, ) or using a from the appropriate configuration source. -When a configuration value is set in host and application configuration, the application configuration is used. +:::moniker-end -### Host variables +To permit command-line arguments to control settings such as the environment name, which is important for determining which environment-based app settings file to load, the [Command-line Configuration Provider](#command-line) is used twice as a configuration source, at the start and end of configuration. Because the provider is used at the end, it has the highest priority. -The following variables are locked in early when initializing the host builders and can't be influenced by application config: +When a configuration value is set in host and app configuration, the app configuration is used. -* [Application name](xref:fundamentals/minimal-apis#change-the-content-root-application-name-and-environment) -* [Environment name](xref:fundamentals/environments), for example `Development`, `Production`, and `Staging` -* [Content root](xref:fundamentals/index#content-root) -* [Web root](xref:fundamentals/index#web-root) -* Whether to scan for [hosting startup assemblies](xref:fundamentals/configuration/platform-specific-configuration) and which assemblies to scan for. -* Variables read by app and library code from [HostBuilderContext.Configuration](xref:Microsoft.Extensions.Hosting.HostBuilderContext.Configuration) in [IHostBuilder.ConfigureAppConfiguration](xref:Microsoft.Extensions.Hosting.IHostBuilder.ConfigureAppConfiguration%2A) callbacks. +## Default host configuration sources -Every other host setting is read from application config instead of host config. +:::moniker range=">= aspnetcore-6.0" -`URLS` is one of the many common host settings that is not a bootstrap setting. Like every other host setting not in the previous list, `URLS` is read later from application config. Host config is a fallback for application config, so host config can be used to set `URLS`, but it will be overridden by any configuration source in application config like `appsettings.json`. +Default host configuration sources from highest to lowest priority when applied to the web app's configuration (): -For more information, see [Change the content root, app name, and environment](xref:migration/50-to-60-samples#change-the-content-root-app-name-and-environment) and [Change the content root, app name, and environment by environment variables or command line](xref:migration/50-to-60-samples#change-the-content-root-app-name-and-environment-by-environment-variables-or-command-line) +1. Command-line arguments using the [Command-line Configuration Provider](#command-line). +1. `DOTNET_`-prefixed environment variables using the [Environment Variables Configuration Provider](xref:Microsoft.Extensions.Configuration.EnvironmentVariables.EnvironmentVariablesConfigurationProvider). +1. `ASPNETCORE_`-prefixed environment variables using the [Environment Variables Configuration Provider](xref:Microsoft.Extensions.Configuration.EnvironmentVariables.EnvironmentVariablesConfigurationProvider). -The remaining sections in this article refer to application configuration. +Default host configuration sources from highest to lowest priority applied to either the [Generic Host](xref:fundamentals/host/generic-host) or [Web Host](xref:fundamentals/host/web-host): -## Application configuration providers +1. `ASPNETCORE_`-prefixed environment variables using the [Environment Variables Configuration Provider](xref:Microsoft.Extensions.Configuration.EnvironmentVariables.EnvironmentVariablesConfigurationProvider). +1. Command-line arguments using the [Command-line Configuration Provider](#command-line). +1. `DOTNET_`-prefixed environment variables using the [Environment Variables Configuration Provider](xref:Microsoft.Extensions.Configuration.EnvironmentVariables.EnvironmentVariablesConfigurationProvider). -The following code displays the enabled configuration providers in the order they were added: +For more information on host configuration, see the following resources: -[!code-csharp[](~/fundamentals/configuration/index/samples/6.x/ConfigSample/Pages/Index2.cshtml.cs?name=snippet)] +* [Generic Host](xref:fundamentals/host/generic-host): Recommended for ASP.NET Core apps targeting .NET 6 or later that adopt the [minimal hosting model](xref:migration/50-to-60#new-hosting-model). +* [Web Host](xref:fundamentals/host/web-host): Required for ASP.NET Core apps that target releases prior to .NET 6 and only maintained by the framework for backward compatibility in .NET 6 or later. -The preceding [list of highest to lowest priority default configuration sources](#hi2low) shows the providers in the opposite order they are added to template generated application. For example, the [JSON configuration provider](#jcp) is added before the [Command-line configuration provider](#command-line). +:::moniker-end -Configuration providers that are added later have higher priority and override previous key settings. For example, if `MyKey` is set in both `appsettings.json` and the environment, the environment value is used. Using the default configuration providers, the [Command-line configuration provider](#clcp) overrides all other providers. +:::moniker range="< aspnetcore-6.0" -For more information on `CreateBuilder`, see [Default builder settings](xref:fundamentals/host/generic-host#default-builder-settings). +Default host configuration sources from highest to lowest priority for the [Web Host](xref:fundamentals/host/web-host): -### `appsettings.json` +* Host configuration + * Environment variables prefixed with `DOTNET_` (for example, `DOTNET_ENVIRONMENT`) using the [Environment Variables Configuration Provider](xref:Microsoft.Extensions.Configuration.EnvironmentVariables.EnvironmentVariablesConfigurationProvider). The prefix (`DOTNET_`) is stripped when the configuration key-value pairs are loaded. + * Command-line arguments using the [Command-line Configuration Provider](#command-line). +* Web Host default configuration () + * Kestrel is used as the web server and configured using the app's configuration providers. + * Add [Host Filtering Middleware](xref:fundamentals/servers/kestrel/host-filtering). + * Add [Forwarded Headers Middleware](xref:host-and-deploy/proxy-load-balancer#forwarded-headers) if the `ASPNETCORE_FORWARDEDHEADERS_ENABLED` environment variable is set to `true`. + * Enable IIS integration. -Consider the following `appsettings.json` file: +:::moniker-end -[!code-json[](~/fundamentals/configuration/index/samples/6.x/ConfigSample/appsettings.json)] +## Host variables -The following code from the [sample download](https://github.com/dotnet/AspNetCore.Docs/tree/main/aspnetcore/fundamentals/configuration/index/samples/6.x/ConfigSample) displays several of the preceding configurations settings: +The following variables are set early in host builder initialization and can't be influenced by app configuration: -[!code-csharp[](~/fundamentals/configuration/index/samples/6.x/ConfigSample/Pages/Test.cshtml.cs?name=snippet)] +* [Application name](xref:fundamentals/minimal-apis#change-the-content-root-application-name-and-environment). +* [Environment name](xref:fundamentals/environments). +* [Content root](xref:fundamentals/index#content-root). +* [Web root](xref:fundamentals/index#web-root). +* Whether to scan for [hosting startup assemblies](xref:fundamentals/configuration/platform-specific-configuration) and which assemblies to scan for. +* Variables read by app and library code from in callbacks. -The default loads configuration in the following order: +Other host settings are read from app configuration instead of host configuration. -1. `appsettings.json` -1. `appsettings.{Environment}.json` : For example, the `appsettings.Production.json` and `appsettings.Development.json` files. The environment version of the file is loaded based on the . For more information, see . +`URLS` is one of the many common host settings that isn't bootstrapped by host configuration. `URLS` is read later from app configuration. Host configuration is a fallback for app configuration, so host configuration can be used to set `URLS`, but the value is overridden by any configuration source that sets `URLS` in app configuration, such as app settings files (`appsettings.{ENVIRONMENT}.json`, where the `{ENVIRONMENT}` placeholder is the environment name, or `appsettings.json`). -`appsettings.{Environment}.json` values override keys in `appsettings.json`. For example, by default: +For more information, see [Change the content root, app name, and environment](xref:migration/50-to-60-samples#change-the-content-root-app-name-and-environment) and [Change the content root, app name, and environment by environment variables or command line](xref:migration/50-to-60-samples#change-the-content-root-app-name-and-environment-by-environment-variables-or-command-line). -* In development, `appsettings.Development.json` configuration overwrites values found in `appsettings.json`. -* In production, `appsettings.Production.json` configuration overwrites values found in `appsettings.json`. For example, when deploying the app to Azure. +## Security and user secrets -If a configuration value must be guaranteed, see [GetValue](#getvalue). The preceding example only reads strings and doesn’t support a default value. +Configuration data guidelines: -Using the [default](#default) configuration, the `appsettings.json` and `appsettings.{Environment}.json` files are enabled with [reloadOnChange: true](https://github.com/dotnet/extensions/blob/release/3.1/src/Hosting/Hosting/src/Host.cs#L74-L75). Changes made to the `appsettings.json` and `appsettings.{Environment}.json` file ***after*** the app starts are read by the [JSON configuration provider](#jcp). +* Never store passwords or other sensitive data in configuration provider code or in plain text configuration files. The [Secret Manager](xref:security/app-secrets) tool can be used to store secrets in development. +* Don't use production secrets in development or test environments. +* Specify secrets outside of the project so that they can't be accidentally committed to a source code repository. +* Production apps should use the most secure authentication flow available. For more information, see [Secure authentication flows](xref:security/index#secure-authentication-flows). -### Comments in appsettings.json +The User Secrets file configuration source of the [default configuration sources](#default-app-configuration-sources) is registered after the JSON configuration sources for app settings files. Therefore, user secrets keys take precedence over keys in `appsettings.json` and `appsettings.{ENVIRONMENT}.json`. -Comments in `appsettings.json` and `appsettings.{Environment}.json` files are supported using JavaScript or [C# style comments](/dotnet/csharp/language-reference/tokens/comments). +For more information on storing passwords or other sensitive data: -Some integrated development environments (IDE) display errors when editing a JSON file that contains comments. You can generally ignore comment errors and warnings, but you can also usually disable them with a setting in the IDE. In Visual Studio Code, for example, add the following to the `settings.json` file to disable the errors: +* +* : Includes advice on using environment variables to store sensitive data. The Secret Manager tool uses the [File Configuration Provider](#file-configuration-provider) to store user secrets in a JSON file on the local system. +* [Azure Key Vault](https://azure.microsoft.com/services/key-vault/) safely stores app secrets for ASP.NET Core apps. For more information, see . -```json -"files.associations": { - "appsettings*.json": "jsonc" +## Access configuration with Dependency Injection (DI) + +Configuration can be injected into services using [Dependency Injection (DI)](xref:fundamentals/dependency-injection) by resolving the service. In the following example, the configuration value stored for the configuration key represented by the `{KEY}` placeholder is assigned to `value`. If the key isn't found, `null` is assigned to `value`: + +```csharp +public class CustomService(IConfiguration config) +{ + public void CustomMethod() + { + var value = config["{KEY}"]; + } } ``` -For other IDEs, check the tool's documentation and other product support channels to determine how to silence the errors. +## Access configuration in the `Program` file - +The following code accesses configuration in the `Program` file using (`builder.Configuration`): -### Bind hierarchical configuration data using the options pattern +```csharp +var defaultConnectionString = + builder.Configuration.GetValue("ConnectionStrings:DefaultConnection"); +``` -[!INCLUDE[](~/includes/bind6.md)] +After the app is built (after the line `var app = builder.Build();`), use (`app.Configuration`): -Using the [default](#default) configuration, the `appsettings.json` and `appsettings.{Environment}.json` files are enabled with [reloadOnChange: true](https://github.com/dotnet/extensions/blob/release/3.1/src/Hosting/Hosting/src/Host.cs#L74-L75). Changes made to the `appsettings.json` and `appsettings.{Environment}.json` file ***after*** the app starts are read by the [JSON configuration provider](#jcp). +```csharp +var defaultLogLevel = app.Configuration.GetValue("Logging:LogLevel:Default"); +``` -See [JSON configuration provider](#jcp) in this document for information on adding additional JSON configuration files. +## Access configuration in the `Startup` class -## Combining service collection + -[!INCLUDE[](~/includes/combine-di6.md)] +*This section generally applies to ASP.NET Core apps prior to the release of .NET 6.* - +The following code displays configuration data in `Startup` methods: -## Security and user secrets +```csharp +public class Startup +{ + public Startup(IConfiguration config) + { + Config = config; + } -Configuration data guidelines: + public IConfiguration Config { get; } -* Never store passwords or other sensitive data in configuration provider code or in plain text configuration files. The [Secret Manager](xref:security/app-secrets) tool can be used to store secrets in development. -* Don't use production secrets in development or test environments. -* Specify secrets outside of the project so that they can't be accidentally committed to a source code repository. -* Production apps should use the most secure authentication flow available. For more information, see [Secure authentication flows](xref:security/index#secure-authentication-flows). + public void ConfigureServices(IServiceCollection services) + { + var connectionString = Config["ConnectionStrings.DefaultConnection"]}"); -By [default](#default), the user secrets configuration source is registered after the JSON configuration sources. Therefore, user secrets keys take precedence over keys in `appsettings.json` and `appsettings.{Environment}.json`. + ... + } -For more information on storing passwords or other sensitive data: + public void Configure(...) + { + var defaultLogLevel = Config["Logging:LogLevel:Default"]}"); -* -* : Includes advice on using environment variables to store sensitive data. The Secret Manager tool uses the [File configuration provider](#fcp) to store user secrets in a JSON file on the local system. -* [Azure Key Vault](https://azure.microsoft.com/services/key-vault/) safely stores app secrets for ASP.NET Core apps. For more information, see . + ... + } +} +``` - +## Display configuration settings on startup for debugging -## Non-prefixed environment variables +The following code displays the app's configuration key-value pairs at app startup. -Non-prefixed environment variables are environment variables other than those prefixed by `ASPNETCORE_` or `DOTNET_`. For example, the ASP.NET Core web application templates set `"ASPNETCORE_ENVIRONMENT": "Development"` in `launchSettings.json`. For more information on `ASPNETCORE_` and `DOTNET_` environment variables, see: +::: moniker range=">= aspnetcore-6.0" -* [List of highest to lowest priority default configuration sources](#hi2low) including non-prefixed, `ASPNETCORE_`-prefixed and `DOTNETCORE_`-prefixed environment variables. -* [`DOTNET_` environment variables](/dotnet/core/tools/dotnet-environment-variables) used outside of [Microsoft.Extensions.Hosting](xref:Microsoft.Extensions.Hosting). +After the app is built in the `Program` file (after the line `var app = builder.Build();`), place the following code, which includes a compiler directive for the DEBUG configuration: -Using the [default](#default) configuration, the loads configuration from environment variable key-value pairs after reading `appsettings.json`, `appsettings.{Environment}.json`, and [user secrets](xref:security/app-secrets). Therefore, key values read from the environment override values read from `appsettings.json`, `appsettings.{Environment}.json`, and user secrets. +```csharp +#if DEBUG +foreach (var c in app.Configuration.AsEnumerable()) +{ + Console.WriteLine($"CONFIG: Key: {c.Key} Value: {c.Value}"); +} +#endif +``` -[!INCLUDE[](~/includes/environmentVarableColon.md)] +::: moniker-end -The following commands: +::: moniker range="< aspnetcore-6.0" -* Set the environment keys and values of the [preceding example](#appsettingsjson) on Windows. -* Test the settings when using the [sample download](https://github.com/dotnet/AspNetCore.Docs/tree/main/aspnetcore/fundamentals/configuration/index/samples/3.x/ConfigSample). The `dotnet run` command must be run in the project directory. +In the app's `Startup` class constructor, inject , `config` in the following example, to write the configuration key-value pairs to the console. The following example includes a compiler directive for the DEBUG configuration: -```dotnetcli -set MyKey="My key from Environment" -set Position__Title=Environment_Editor -set Position__Name=Environment_Rick -dotnet run +```csharp +#if DEBUG +foreach (var c in config.AsEnumerable()) +{ + Console.WriteLine($"CONFIG: Key: {c.Key} Value: {c.Value}"); +} +#endif ``` -The preceding environment settings: +::: moniker-end -* Are only set in processes launched from the command window they were set in. -* Won't be read by browsers launched with Visual Studio. +## Configuration keys and values -The following [setx](/windows-server/administration/windows-commands/setx) commands can be used to set the environment keys and values on Windows. Unlike `set`, `setx` settings are persisted. `/M` sets the variable in the system environment. If the `/M` switch isn't used, a user environment variable is set. +Configuration keys: -```console -setx MyKey "My key from setx Environment" /M -setx Position__Title Environment_Editor /M -setx Position__Name Environment_Rick /M -``` +* Are case-insensitive. For example, `ConnectionString` and `connectionstring` are treated as equivalent keys. +* If a key and value is set by more than one configuration provider, the value from the last provider added is used. For more information, see [Default configuration](#default-app-configuration-sources). +* Hierarchical keys + * Within the Configuration API, a colon separator (`:`) works on all platforms. + * In environment variables, a colon separator doesn't work on all platforms. A double underscore (`__`) is supported by all platforms and is automatically converted into a colon (`:`) when the configuration is read by the app. + * In Azure Key Vault, hierarchical keys use double dashes (`--`) as a separator. The [Azure Key Vault Configuration Provider](xref:security/key-vault-configuration) automatically replaces the double dashes (`--`) with a colon (`:`) when the secrets are loaded into the app's configuration. +* The supports binding arrays to objects using array indices in configuration keys. Array binding is described in the [Bind an array](#bind-an-array) section. -To test that the preceding commands override `appsettings.json` and `appsettings.{Environment}.json`: +Configuration values are strings. Null values can't be stored in configuration or bound to objects. -* With Visual Studio: Exit and restart Visual Studio. -* With the CLI: Start a new command window and enter `dotnet run`. +## How hierarchical configuration data is organized -Call with a string to specify a prefix for environment variables: +The Configuration API reads hierarchical configuration data by flattening the hierarchical data with the use of a delimiter in the configuration keys, which are usually colons (`:`). Double underscores (`__`) are usually used with environment variable configuration for cross-platform support. -[!code-csharp[](~/fundamentals/configuration/index/samples/6.x/ConfigSample/Program.cs?name=snippet_env&highlight=5)] +> [!NOTE] +> In complex app configuration scenarios, it's best to group and read related hierarchical configuration data using the [options pattern](xref:fundamentals/configuration/options). -In the preceding code: +Consider the following hierarchical configuration data: -* `builder.Configuration.AddEnvironmentVariables(prefix: "MyCustomPrefix_")` is added after the [default configuration providers](#default). For an example of ordering the configuration providers, see [JSON configuration provider](#jcp). -* Environment variables set with the `MyCustomPrefix_` prefix override the [default configuration providers](#default). This includes environment variables without the prefix. +* :::no-loc text="ConnectionStrings"::: + * :::no-loc text="DefaultConnection (Value = ":::no-loc text="Data Source=LocalSqlServer\\MSSQLDev;":::") +* :::no-loc text="Logging"::: + * :::no-loc text="LogLevel"::: + * :::no-loc text="Default"::: (Value = :::no-loc text="Information":::) + * :::no-loc text="Microsoft"::: (Value = :::no-loc text="Warning":::) + * :::no-loc text="Microsoft.Hosting.Lifetime"::: (Value = :::no-loc text="Information":::) +* :::no-loc text="AllowedHosts"::: (Value = *) -The prefix is stripped off when the configuration key-value pairs are read. +The following table displays the keys used to recover the values in the preceding configuration data. The delimiter isn't required for :::no-loc text="AllowedHosts":::. -The following commands test the custom prefix: +Key (colon delimiter) | Key (double-underscore delimiter) +--- | --- +ConnectionStrings:DefaultConnection | ConnectionStrings__DefaultConnection +Logging:LogLevel:Default | Logging__LogLevel__Default +Logging:LogLevel:Microsoft | Logging__LogLevel__Microsoft +Logging:LogLevel:Microsoft.Hosting.Lifetime | Logging__LogLevel__Microsoft.Hosting.Lifetime +AllowedHosts | AllowedHosts -```dotnetcli -set MyCustomPrefix_MyKey="My key with MyCustomPrefix_ Environment" -set MyCustomPrefix_Position__Title=Editor_with_customPrefix -set MyCustomPrefix_Position__Name=Environment_Rick_cp -dotnet run -``` +> [!NOTE] +> In complex app configuration scenarios, we recommend grouping and reading related hierarchical configuration data using the [Options pattern](xref:fundamentals/configuration/options). -The [default configuration](#default) loads environment variables and command line arguments prefixed with `DOTNET_` and `ASPNETCORE_`. The `DOTNET_` and `ASPNETCORE_` prefixes are used by ASP.NET Core for [host and app configuration](xref:fundamentals/host/generic-host#host-configuration), but not for user configuration. For more information on host and app configuration, see [.NET Generic Host](xref:fundamentals/host/generic-host). + and methods are available to isolate sections and children of a section in the configuration data. These methods are described where [`GetSection`, `GetChildren`, and `Exists` are covered](#work-with-sections-get-a-sections-children-and-determine-if-a-section-exists). -On [Azure App Service](https://azure.microsoft.com/services/app-service/), select **New application setting** on the **Settings > Configuration** page. Azure App Service application settings are: +When the element structure includes an array, the array index should be treated as an additional element name in the path. Consider the following hierarchical configuration data as an array. -* Encrypted at rest and transmitted over an encrypted channel. -* Exposed as environment variables. +:::no-loc text="MainObject"::: (an array): -For more information, see [Azure Apps: Override app configuration using the Azure Portal](xref:host-and-deploy/azure-apps/index#override-app-configuration-using-the-azure-portal). +* First item in the array + * :::no-loc text="Object0"::: + * :::no-loc text="Object1"::: + * :::no-loc text="SubObject0"::: + * :::no-loc text="SubObject1"::: +* Second item in the array + * :::no-loc text="Object0"::: + * :::no-loc text="Object1"::: + * :::no-loc text="SubObject0"::: + * :::no-loc text="SubObject1"::: -See [Connection string prefixes](#constr) for information on Azure database connection strings. +Keys with colon separators: -### Naming of environment variables +* :::no-loc text="MainObject:0:Object0"::: +* :::no-loc text="MainObject:0:Object1:SubObject0"::: +* :::no-loc text="MainObject:0:Object1:SubObject1"::: +* :::no-loc text="MainObject:1:Object0"::: +* :::no-loc text="MainObject:1:Object1:SubObject0"::: +* :::no-loc text="MainObject:1:Object1:SubObject1"::: -Environment variable names reflect the structure of an `appsettings.json` file. Each element in the hierarchy is separated by a double underscore (preferable) or a colon. When the element structure includes an array, the array index should be treated as an additional element name in this path. Consider the following `appsettings.json` file and its equivalent values represented as environment variables. +Keys with underscore separators, which is recommended for cross-platform compatibility when configuration is provided by environment variables: -*`appsettings.json`* +* :::no-loc text="MainObject__0__Object0"::: +* :::no-loc text="MainObject__0__Object1:SubObject0"::: +* :::no-loc text="MainObject__0__Object1:SubObject1"::: +* :::no-loc text="MainObject__1__Object0"::: +* :::no-loc text="MainObject__1__Object1:SubObject0"::: +* :::no-loc text="MainObject__1__Object1:SubObject1"::: -```json +Because configuration that comes from arrays is flattened and numbered sequentially for each configuration source that an app uses, values can be unexpectedly overwritten if care isn't taken when structuring and reading the data from multiple sources. Consider the following configuration key-value pairs: + +:::no-loc text="Modules"::: values (an array): + +* :::no-loc text="Module1"::: +* :::no-loc text="Module2"::: +* :::no-loc text="Module3"::: + +The array is flattened and indexed sequentially yielding the configuration key-value pairs in the following table. + +Key | Value +--- | --- +`Modules:0` | `Module1` +`Modules:1` | `Module2` +`Modules:2` | `Module3` + +After the preceding configuration is established, another configuration source loads the following configuration: + +:::no-loc text="Modules"::: values (an array): + +* :::no-loc text="Module4"::: +* :::no-loc text="Module5"::: + +This array is also flattened and indexed sequentially. + +Key | Value +--- | --- +`Modules:0` | `Module4` +`Modules:1` | `Module5` + +Recalling that the last configuration source for a given key sets the value of that key, the final set of configuration key-value pairs are shown in the following table. + +Key | Value +--- | --- +`Modules:0` | `Module4` +`Modules:1` | `Module5` +`Modules:2` | `Module3` + +This isn't a surprising result given how the framework flattens and indexes array data from configuration sources, but it should be kept in mind to avoid unexpected overwrites. + +To avoid such overwrites, structure array indexing to match across various configuration sources that provide the same array data. Alternatively, a workaround approach is to delimit array values in a string value of a single key-value pair, for example using a comma, semicolon, or pipe as the delimiter. Write custom code to split the string and assign the delimited values to your array. + +## Configuration providers + +The following table shows the configuration providers available to ASP.NET Core apps. + +Provider | Provides configuration from… +--- | --- +[Azure Key Vault Configuration Provider](xref:security/key-vault-configuration) | Azure Key Vault +[Azure App Configuration Provider](/azure/azure-app-configuration/quickstart-aspnet-core-app) | Azure App Configuration +[Command-line Configuration Provider](#command-line) | Command-line parameters +[Custom configuration provider](#custom-configuration-provider) | Custom source +[Environment Variables Configuration Provider](#environment-variables-configuration-provider) | Environment variables +[File Configuration Provider](#file-configuration-provider) | INI, JSON, and XML files +[Key-per-file Configuration Provider](#key-per-file-configuration-provider) | Directory files +[Memory Configuration Provider](#memory-configuration-provider) | In-memory collections +[User secrets](xref:security/app-secrets) | File in the user profile directory + +Configuration sources are read in the order that their configuration providers are specified. Order configuration providers in code to suit the priorities for the underlying configuration sources that the app requires. + +A typical sequence of configuration providers is: + +1. General app settings via `appsettings.json`. +1. Environmental app settings via `appsettings.{ENVIRONMENT}.json`, where the `{ENVIRONMENT}` placeholder is the app's environment (examples: `Development`, `Production`). +1. [User secrets](xref:security/app-secrets). +1. Environment variables using the [Environment Variables Configuration Provider](#environment-variables-configuration-provider). +1. Command-line arguments using the [Command-line Configuration Provider](#command-line). + +A common practice is to add the Command-line Configuration Provider last in a series of providers to allow command-line arguments to override configuration set by the other providers. + +The preceding sequence of providers is used in the [default configuration](#default-app-configuration-sources). + +To inspect the app's configuration providers, [inject](xref:fundamentals/dependency-injection) , cast it to , and read the property. + +In the following `ConfigurationProviders` Razor component displays the enabled configuration providers in the order that they're added to the app. + +`Pages/ConfigurationProviders.razor`: + +```razor +@page "/configuration-providers" +@inject IConfiguration Config + +

Configuration Providers

+ +@if (ConfigRoot is not null) { - "SmtpServer": "smtp.example.com", - "Logging": [ - { - "Name": "ToEmail", - "Level": "Critical", - "Args": { - "FromAddress": "MySystem@example.com", - "ToAddress": "SRE@example.com" - } - }, +
    + @foreach (var provider in ConfigRoot.Providers) { - "Name": "ToConsole", - "Level": "Information" +
  • @provider
  • } - ] +
} -``` -**environment variables** +@code { + private IConfigurationRoot? ConfigRoot; -```console -setx SmtpServer smtp.example.com -setx Logging__0__Name ToEmail -setx Logging__0__Level Critical -setx Logging__0__Args__FromAddress MySystem@example.com -setx Logging__0__Args__ToAddress SRE@example.com -setx Logging__1__Name ToConsole -setx Logging__1__Level Information + protected override void OnInitialized() + { + ConfigRoot = (IConfigurationRoot)Config; + } +} ``` -### Environment variables set in generated launchSettings.json +The preceding Razor component produces the following output, where the `{APP NAMESPACE}` placeholder is the app's namespace: -Environment variables set in `launchSettings.json` override those set in the system environment. For example, the ASP.NET Core web templates generate a `launchSettings.json` file that sets the endpoint configuration to: + + +> :::no-loc text="MemoryConfigurationProvider"::: +> :::no-loc text="EnvironmentVariablesConfigurationProvider Prefix: 'ASPNETCORE_'"::: +> :::no-loc text="MemoryConfigurationProvider"::: +> :::no-loc text="EnvironmentVariablesConfigurationProvider Prefix: 'DOTNET_'"::: +> :::no-loc text="JsonConfigurationProvider for 'appsettings.json' (Optional)"::: +> :::no-loc text="JsonConfigurationProvider for 'appsettings.Development.json' (Optional)"::: +> :::no-loc text="JsonConfigurationProvider for '{APP NAMESPACE}.settings.json' (Optional)"::: +> :::no-loc text="JsonConfigurationProvider for '{APP NAMESPACE}.settings.Development.json' (Optional)"::: +> :::no-loc text="EnvironmentVariablesConfigurationProvider"::: +> :::no-loc text="Microsoft.Extensions.Configuration.ChainedConfigurationProvider"::: + +In the [Default app configuration sources](#default-app-configuration-sources) section earlier in this article, configuration sources are listed from highest to lowest priority. The preceding `ConfigurationProviders` component displays the sources *in the order that the app reads them*. For example, the [JSON Configuration Provider](#json-configuration-provider) for the non-environmental app settings file (`appsettings.json`) is earlier in the preceding list because it's added before the provider for the Development environment app settings file (`appsettings.Development.json`). The configuration providers are executed from the top of the list to the bottom of the list. For a matching configuration key between the two app settings JSON Configuration Providers, the last setting takes precedence, which is the value from `appsettings.Development.json`. + +## App settings file configuration (`appsettings.json`, `appsettings.{ENVIRONMENT}.json`) + +Read configuration loaded from app settings files using the [JSON Configuration Provider](#json-configuration-provider). + +Consider the following `appsettings.json` file: ```json -"applicationUrl": "https://localhost:5001;http://localhost:5000" +{ + "ConnectionStrings": { + "DefaultConnection": "Data Source=LocalSqlServer\\MSSQLDev;" + }, + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft": "Warning", + "Microsoft.Hosting.Lifetime": "Information" + } + }, + "AllowedHosts": "*" +} ``` -Configuring the `applicationUrl` sets the `ASPNETCORE_URLS` environment variable and overrides values set in the environment. +[Inject](xref:fundamentals/dependency-injection) an instance of to read configuration values. -### Escape environment variables on Linux +The following `AppSettingsConfiguration` Razor component reads the default database connection string and default logging level configuration. is injected at the top of the component and used to read configuration values. A colon (`:`) separator is used in string-typed configuration keys to locate the appropriate JSON properties. For example, the JSON structure for the default connection string (`DefaultConnection`) object is nested under the connection strings (`ConnectionStrings`) object, so the string notation to access the default connection string uses a colon to separate `DefaultConnection` and `ConnectionStrings` in the order that the objects appear in the app settings file: `ConnectionStrings:DefaultConnection`. -On Linux, the value of URL environment variables must be escaped so `systemd` can parse it. Use the linux tool `systemd-escape` which yields `http:--localhost:5001` - - ```cmd - groot@terminus:~$ systemd-escape http://localhost:5001 - http:--localhost:5001 - ``` +`Pages/AppSettingsConfiguration.razor`: -### Display environment variables +```razor +@page "/app-settings-configuration" +@inject IConfiguration Config -The following code displays the environment variables and values on application startup, which can be helpful when debugging environment settings: +

App Settings Configuration

-```csharp -var builder = WebApplication.CreateBuilder(args); -var app = builder.Build(); +
    +
  • Default Connection String: @Config["ConnectionStrings:DefaultConnection"] +
  • Default Log Level: @Config["Logging:LogLevel:Default"] +
+``` + +The same approach is taken in a Razor Pages page model: + +```cshtml +using Microsoft.Extensions.Configuration; -foreach (var c in builder.Configuration.AsEnumerable()) +... + +public class AppSettingsPageModel(IConfiguration config) : PageModel { - Console.WriteLine(c.Key + " = " + c.Value); + public ContentResult OnGet() + { + var defaultConnectionString = config["ConnectionStrings:DefaultConnection"]; + var defaultLogLevel = config["Logging:LogLevel:Default"]; + + return Content( + $"Default Connection String: {defaultConnectionString}\n" + + $"Default Log Level: {defaultLogLevel}"); + } } ``` - +The default instances load configuration in the following order: -## Command-line +1. `appsettings.json` +1. `appsettings.{ENVIRONMENT}.json`, where the `{ENVIRONMENT}` placeholder is the app's [environment](xref:fundamentals/environments) (examples: `appsettings.Production.json`, `appsettings.Development.json`). The environment version of the file is loaded based on the . -Using the [default](#default) configuration, the loads configuration from command-line argument key-value pairs after the following configuration sources: +`appsettings.{ENVIRONMENT}.json` values override keys in `appsettings.json`. -* `appsettings.json` and `appsettings.{Environment}.json` files. -* [App secrets](xref:security/app-secrets) in the Development environment. -* Environment variables. +By default: -By [default](#default), configuration values set on the command-line override configuration values set with all the other configuration providers. +* In the Development environment, `appsettings.Development.json` configuration overwrites values found in `appsettings.json`. +* In the Production environment, `appsettings.Production.json` configuration overwrites values found in `appsettings.json`. -### Command-line arguments +The preceding example only reads strings and doesn't support a default value. If a configuration value must be guaranteed with a default value, see the [Extract a single value from configuration with type conversion (`GetValue`)](#extract-a-single-value-from-configuration-with-type-conversion-getvalue) section. -The following command sets keys and values using `=`: +Using the [default app configuration sources](#default-app-configuration-sources), the `appsettings.json` and `appsettings.{ENVIRONMENT}.json` files are enabled with [`reloadOnChange` set to `true`](#json-configuration-provider), which means that changes made to either the `appsettings.json` or `appsettings.{ENVIRONMENT}.json` files after the app starts take effect immediately after the file is saved. -```dotnetcli -dotnet run MyKey="Using =" Position:Title=Cmd Position:Name=Cmd_Rick +Comments in `appsettings.json` and `appsettings.{ENVIRONMENT}.json` files are supported using JavaScript or [C# style comments](/dotnet/csharp/language-reference/tokens/comments). Some integrated development environments (IDEs) display errors when editing a JSON file that contains comments because the [official JSON specification (RFC 7159)](https://datatracker.ietf.org/doc/html/rfc7159) makes no allowance for comments in JSON files. You can generally ignore comment errors and warnings, but you can also usually disable warnings or errors with a setting in the IDE. In Visual Studio Code, for example, add the following to the `settings.json` file to disable the errors: + +```json +"files.associations": { + "appsettings*.json": "jsonc" +} ``` -The following command sets keys and values using `/`: +The preceding setting indicates to VS Code that app settings files, including environmental-based files, are associated with the [JSONC ("JSON with Comments") file format](https://jsonc.org/), which supports comments. -```dotnetcli -dotnet run /MyKey "Using /" /Position:Title=Cmd /Position:Name=Cmd_Rick -``` +For other IDEs, check the IDE's documentation and product support channels to determine how to silence errors or warnings about comments in JSON files. -The following command sets keys and values using `--`: +## Environment Variables Configuration Provider -```dotnetcli -dotnet run --MyKey "Using --" --Position:Title=Cmd --Position:Name=Cmd_Rick +The [default Environment Variables Configuration Provider](#default-app-configuration-sources) () loads configuration from environment variables that aren't prefixed with `ASPNETCORE_` or `DOTNET_`. For more information on `ASPNETCORE_` and `DOTNET_` environment variables, see the [Default host configuration sources](#default-host-configuration-sources) section and [`DOTNET_` environment variables (.NET Core documentation)](/dotnet/core/tools/dotnet-environment-variables). + +Using the default Environment Variables Configuration Provider, the app loads configuration from environment variable key-value pairs after reading `appsettings.json`, `appsettings.{ENVIRONMENT}.json`, and [user secrets](xref:security/app-secrets). Therefore, key values read from the environment override values read from `appsettings.json`, `appsettings.{ENVIRONMENT}.json`, and user secrets. + +[!INCLUDE[](~/includes/environmentVarableColon.md)] + +For guidance on setting environment variables in a command shell on Windows or in a cross-platform PowerShell command shell, see the following resources: + +* [set (environment variable)](/windows-server/administration/windows-commands/set_1) +* [setx](/windows-server/administration/windows-commands/setx) +* [about_Environment_Variables (PowerShell documentation)](/powershell/module/microsoft.powershell.core/about/about_environment_variables) + +### Custom prefix for environment variables + +::: moniker range=">= aspnetcore-6.0" + +You can add a configuration provider for custom-prefixed environment variables. In the `Program` file, call with a string to specify a prefix after is called. The provider is added after the [default configuration providers](#default-app-configuration-sources), thus the added provider has a higher priority, including over environment variables of the same name without the prefix. + +In the following example, environment variables are added with the `CustomPrefix_` prefix: + +```csharp +builder.Configuration.AddEnvironmentVariables(prefix: "CustomPrefix_"); ``` -The key value: +::: moniker-end -* Must follow `=`, or the key must have a prefix of `--` or `/` when the value follows a space. -* Isn't required if `=` is used. For example, `MySetting=`. +::: moniker range="< aspnetcore-6.0" -Within the same command, don't mix command-line argument key-value pairs that use `=` with key-value pairs that use a space. +You can add a configuration provider for custom-prefixed environment variables. In the `Program` file, call with a string to specify a prefix on the of . The provider is added after the [default configuration providers](#default-app-configuration-sources), thus the added provider has a higher priority, including over environment variables of the same name without the prefix. -### Switch mappings +In the following example, environment variables are added with the `CustomPrefix_` prefix: + +```csharp +public static IHostBuilder CreateHostBuilder(string[] args) => + Host.CreateDefaultBuilder(args) + .ConfigureWebHostDefaults(webBuilder => + { + webBuilder.UseStartup(); + }) + .ConfigureAppConfiguration(config => + { + config.AddEnvironmentVariables("CustomPrefix_"); + }); +``` -Switch mappings allow **key** name replacement logic. Provide a dictionary of switch replacements to the method. +::: moniker-end -When the switch mappings dictionary is used, the dictionary is checked for a key that matches the key provided by a command-line argument. If the command-line key is found in the dictionary, the dictionary value is passed back to set the key-value pair into the app's configuration. A switch mapping is required for any command-line key prefixed with a single dash (`-`). +The prefix is stripped off when the configuration key-value pairs are read. -Switch mappings dictionary key rules: +### Launch settings override environment variable settings -* Switches must start with `-` or `--`. -* The switch mappings dictionary must not contain duplicate keys. +Environment variables set in `launchSettings.json` override those set in the system environment. For example, the ASP.NET Core web templates generate a `launchSettings.json` file that sets the endpoint configuration to: -To use a switch mappings dictionary, pass it into the call to `AddCommandLine`: +```json +"applicationUrl": "https://localhost:5001;http://localhost:5000" +``` -[!code-csharp[](~/fundamentals/configuration/index/samples/6.x/ConfigSample/Program.cs?name=snippet_sw)] +Configuring the `applicationUrl` sets the `ASPNETCORE_URLS` environment variable and overrides values set in the environment. -Run the following command works to test key replacement: +### Escape environment variables on Linux -```dotnetcli -dotnet run -k1 value1 -k2 value2 --alt3=value2 /alt4=value3 --alt5 value5 /alt6 value6 +On Linux, the value of URL environment variables must be escaped so `systemd` can parse it. In the following example, the Linux tool `systemd-escape` is used to yield `http:--localhost:5001` from `http://localhost:5001`: + +```console +groot@terminus:~$ systemd-escape http://localhost:5001 +http:--localhost:5001 ``` -The following code shows the key values for the replaced keys: +### Azure App Service app settings (environment variables) -[!code-csharp[](~/fundamentals/configuration/index/samples/6.x/ConfigSample/Pages/Test3.cshtml.cs?name=snippet)] +For [Azure App Service](https://azure.microsoft.com/services/app-service/) app settings (environment variable) guidance, see the following resources: -For apps that use switch mappings, the call to `CreateDefaultBuilder` shouldn't pass arguments. The `CreateDefaultBuilder` method's `AddCommandLine` call doesn't include mapped switches, and there's no way to pass the switch-mapping dictionary to `CreateDefaultBuilder`. The solution isn't to pass the arguments to `CreateDefaultBuilder` but instead to allow the `ConfigurationBuilder` method's `AddCommandLine` method to process both the arguments and the switch-mapping dictionary. +* [Configure an App Service app (Azure documentation)](/azure/app-service/configure-common) +* [Azure database connection string prefixes](#connection-string-prefixes) -## Set environment and command-line arguments with Visual Studio +### Connection string prefixes -Environment and command-line arguments can be set in Visual Studio from the launch profiles dialog: +The Configuration API has special processing rules for four connection string environment variables. These connection strings are involved in configuring Azure connection strings for the app environment. Environment variables with the prefixes shown in the following table are loaded into the app with the [default configuration](#default-app-configuration-sources) or when no prefix is supplied to . -* In Solution Explorer, right click the project and select **Properties**. -* Select the **Debug > General** tab and select **Open debug launch profiles UI**. +Connection string prefix | Provider +--- | --- +`CUSTOMCONNSTR_` | Custom provider +`MYSQLCONNSTR_` | [MySQL](https://www.mysql.com/) +`SQLAZURECONNSTR_` | [Azure SQL Database](https://azure.microsoft.com/services/sql-database/) +`SQLCONNSTR_` | [SQL Server](https://www.microsoft.com/sql-server/) -## Hierarchical configuration data +When an environment variable is discovered and loaded into configuration with any of the four prefixes shown in the preceding table: -The Configuration API reads hierarchical configuration data by flattening the hierarchical data with the use of a delimiter in the configuration keys. +* The configuration key is created by removing the environment variable prefix and adding a configuration key section (`ConnectionStrings`). +* A new configuration key-value pair is created that represents the database connection provider, except for `CUSTOMCONNSTR_`, which has no stated provider. -The [sample download](https://github.com/dotnet/AspNetCore.Docs/tree/main/aspnetcore/fundamentals/configuration/index/samples/6.x/ConfigSample) contains the following `appsettings.json` file: +Environment variable key | Converted configuration key | Provider configuration entry + --- | --- | --- +`CUSTOMCONNSTR_{KEY}` | `ConnectionStrings:{KEY}` | Configuration entry not created. +`MYSQLCONNSTR_{KEY}` | `ConnectionStrings:{KEY}` | Key: `ConnectionStrings:{KEY}_ProviderName`:
Value: `MySql.Data.MySqlClient` +`SQLAZURECONNSTR_{KEY}` | `ConnectionStrings:{KEY}` | Key: `ConnectionStrings:{KEY}_ProviderName`:
Value: `System.Data.SqlClient` +`SQLCONNSTR_{KEY}` | `ConnectionStrings:{KEY}` | Key: `ConnectionStrings:{KEY}_ProviderName`:
Value: `System.Data.SqlClient` -[!code-json[](~/fundamentals/configuration/index/samples/6.x/ConfigSample/appsettings.json)] +## Command-line -The following code from the [sample download](https://github.com/dotnet/AspNetCore.Docs/tree/main/aspnetcore/fundamentals/configuration/index/samples/6.x/ConfigSample) displays several of the configurations settings: +Using the [default configuration sources](#default-app-configuration-sources), the loads configuration from command-line argument key-value pairs after the following configuration sources: -[!code-csharp[](~/fundamentals/configuration/index/samples/6.x/ConfigSample/Pages/Test.cshtml.cs?name=snippet)] +* `appsettings.json` and `appsettings.{ENVIRONMENT}.json` files. +* [App secrets](xref:security/app-secrets) in the Development environment. +* Environment variables. -The preferred way to read hierarchical configuration data is using the options pattern. For more information, see [Bind hierarchical configuration data](#optpat) in this document. +By default, configuration values set on the command-line override configuration values set by all of the other configuration providers. - and methods are available to isolate sections and children of a section in the configuration data. These methods are described later in [GetSection, GetChildren, and Exists](#getsection). +### Command-line arguments - +The following [`dotnet run`](/dotnet/core/tools/dotnet-run) command sets keys and values using equals signs (`=`): -## Configuration keys and values +```dotnetcli +dotnet run ConnectionStrings:DefaultConnection="Data Source=LocalSqlServer\\MSSQLDev;" Logging:LogLevel:Default=Information +``` -[!INCLUDE [managed-identities](~/includes/managed-identities-conn-strings.md)] +The following command sets keys and values using forward slashes (`/`): -Configuration keys: +```dotnetcli +dotnet run /ConnectionStrings:DefaultConnection "Data Source=LocalSqlServer\\MSSQLDev;" /Logging:LogLevel:Default Information +``` -* Are case-insensitive. For example, `ConnectionString` and `connectionstring` are treated as equivalent keys. -* If a key and value is set in more than one configuration provider, the value from the last provider added is used. For more information, see [Default configuration](#default). -* Hierarchical keys - * Within the Configuration API, a colon separator (`:`) works on all platforms. - * In environment variables, a colon separator may not work on all platforms. A double underscore, `__`, is supported by all platforms and is automatically converted into a colon `:`. - * In Azure Key Vault, hierarchical keys use `--` as a separator. The [Azure Key Vault configuration provider](xref:security/key-vault-configuration) automatically replaces `--` with a `:` when the secrets are loaded into the app's configuration. -* The supports binding arrays to objects using array indices in configuration keys. Array binding is described in the [Bind an array to a class](#boa) section. +The following command sets keys and values using double dashes (`--`): -Configuration values: +```dotnetcli +dotnet run --ConnectionStrings:DefaultConnection "Data Source=LocalSqlServer\\MSSQLDev;" --Logging:LogLevel:Default Information +``` -* Are strings. -* Null values can't be stored in configuration or bound to objects. +Argument conventions: - +* The key value must follow the equals sign (`=`), or the key must have a prefix of a double dash (`--`) or forward slash (`/`) when the value follows a space. +* Not assigning a value after an equals sign (`=`) results in assigning an empty string for the configuration setting. For example, specifying `ConnectionStrings:DefaultConnection=` is valid and results in assigning an empty string to the default connection string. +* Within the same command, don't mix argument key-value pairs separated by an equals sign (`=`) with key-value pairs separated by a space. -## Configuration providers +### Switch mappings -The following table shows the configuration providers available to ASP.NET Core apps. +Switch mappings allow *key* name replacement logic via a dictionary of switch replacements passed to the method. -| Provider | Provides configuration from | -| -------- | ----------------------------------- | -| [Azure Key Vault configuration provider](xref:security/key-vault-configuration) | Azure Key Vault | -| [Azure App configuration provider](/azure/azure-app-configuration/quickstart-aspnet-core-app) | Azure App Configuration | -| [Command-line configuration provider](#clcp) | Command-line parameters | -| [Custom configuration provider](#custom-configuration-provider) | Custom source | -| [Environment Variables configuration provider](#evcp) | Environment variables | -| [File configuration provider](#file-configuration-provider) | INI, JSON, and XML files | -| [Key-per-file configuration provider](#key-per-file-configuration-provider) | Directory files | -| [Memory configuration provider](#memory-configuration-provider) | In-memory collections | -| [User secrets](xref:security/app-secrets) | File in the user profile directory | +When the switch mappings dictionary is used, the dictionary is checked for a key that matches the key provided by a command-line argument. If the command-line key is found in the dictionary, the dictionary value is passed back to set the key-value pair into the app's configuration. A switch mapping is required for any command-line key prefixed with a single dash (`-`). -Configuration sources are read in the order that their configuration providers are specified. Order configuration providers in code to suit the priorities for the underlying configuration sources that the app requires. +Switch mappings dictionary key rules: -A typical sequence of configuration providers is: +* Switches must start with a single dash (`-`) or double dash (`--`). +* The switch mappings dictionary must not contain duplicate keys. -1. `appsettings.json` -1. `appsettings.{Environment}.json` -1. [User secrets](xref:security/app-secrets) -1. Environment variables using the [Environment Variables configuration provider](#evcp). -1. Command-line arguments using the [Command-line configuration provider](#clcp). +In the following example, a switch mapping dictionary (`switchMappings`) is passed to in the app's `Program` file: -A common practice is to add the Command-line configuration provider last in a series of providers to allow command-line arguments to override configuration set by the other providers. +::: moniker range=">= aspnetcore-6.0" -The preceding sequence of providers is used in the [default configuration](#default). +```csharp +var switchMappings = + new Dictionary(){ { "-k1", "key1" }, { "-k2", "key2" } }; - +builder.Configuration.AddCommandLine(args, switchMappings); +``` -### Connection string prefixes +::: moniker-end -[!INCLUDE [managed-identities](~/includes/managed-identities-conn-strings.md)] +::: moniker range="< aspnetcore-6.0" -The Configuration API has special processing rules for four connection string environment variables. These connection strings are involved in configuring Azure connection strings for the app environment. Environment variables with the prefixes shown in the table are loaded into the app with the [default configuration](#default) or when no prefix is supplied to `AddEnvironmentVariables`. +```csharp +Host.CreateDefaultBuilder(args) + .ConfigureWebHostDefaults(webBuilder => + { + webBuilder.UseStartup(); + }) +.ConfigureAppConfiguration(config => +{ + var switchMappings = + new Dictionary() { { "-k1", "key1" }, { "-k2", "key2" } }; + + config.AddCommandLine(args, switchMappings); +}); +``` -| Connection string prefix | Provider | -| ------------------------ | -------- | -| `CUSTOMCONNSTR_` | Custom provider | -| `MYSQLCONNSTR_` | [MySQL](https://www.mysql.com/) | -| `SQLAZURECONNSTR_` | [Azure SQL Database](https://azure.microsoft.com/services/sql-database/) | -| `SQLCONNSTR_` | [SQL Server](https://www.microsoft.com/sql-server/) | +::: moniker-end -When an environment variable is discovered and loaded into configuration with any of the four prefixes shown in the table: +The following [`dotnet run`](/dotnet/core/tools/dotnet-run) commands demonstrate key replacement (`value1` into `key1` and `value2` into `key2`): -* The configuration key is created by removing the environment variable prefix and adding a configuration key section (`ConnectionStrings`). -* A new configuration key-value pair is created that represents the database connection provider (except for `CUSTOMCONNSTR_`, which has no stated provider). +* `dotnet run -k1 value1 -k2 value2` +* `dotnet run --k1=value1 --k2=value2` +* `dotnet run --k1 value1 --k2 value2` +* `dotnet run /k1=value1 /k2=value2` +* `dotnet run /k1 value1 /k2 value2` + +::: moniker range=">= aspnetcore-6.0" + +For apps that use switch mappings, the call to shouldn't pass arguments. The method's call doesn't include mapped switches, and there's no way to pass the switch-mapping dictionary to . The solution isn't to pass the arguments to but instead to allow the method's method to process both the arguments and the switch-mapping dictionary. + +::: moniker-end + +::: moniker range="< aspnetcore-6.0" -| Environment variable key | Converted configuration key | Provider configuration entry | -|--|--|--| -| `CUSTOMCONNSTR_{KEY}` | `ConnectionStrings:{KEY}` | Configuration entry not created. | -| `MYSQLCONNSTR_{KEY}` | `ConnectionStrings:{KEY}` | Key: `ConnectionStrings:{KEY}_ProviderName`:
Value: `MySql.Data.MySqlClient` | -| `SQLAZURECONNSTR_{KEY}` | `ConnectionStrings:{KEY}` | Key: `ConnectionStrings:{KEY}_ProviderName`:
Value: `System.Data.SqlClient` | -| `SQLCONNSTR_{KEY}` | `ConnectionStrings:{KEY}` | Key: `ConnectionStrings:{KEY}_ProviderName`:
Value: `System.Data.SqlClient` | +For apps that use switch mappings, the call to shouldn't pass arguments. The method's call doesn't include mapped switches, and there's no way to pass the switch-mapping dictionary to . The solution isn't to pass the arguments to but instead to allow the method's method to process both the arguments and the switch-mapping dictionary. - +::: moniker-end + +## Set environment and command-line arguments with Visual Studio + +Environment and command-line arguments can be set in Visual Studio from the launch profiles dialog: + +* In Solution Explorer, right click the project and select **Properties**. +* Select the **Debug > General** tab and select **Open debug launch profiles UI**. -## File configuration provider +## File Configuration Provider is the base class for loading configuration from the file system. The following configuration providers derive from `FileConfigurationProvider`: -* [INI configuration provider](#ini-configuration-provider) -* [JSON configuration provider](#jcp) -* [XML configuration provider](#xml-configuration-provider) +* [INI Configuration Provider](#ini-configuration-provider) +* [JSON Configuration Provider](#json-configuration-provider) +* [XML Configuration Provider](#xml-configuration-provider) -### INI configuration provider +### INI Configuration Provider -The loads configuration from INI file key-value pairs at runtime. +The loads configuration from INI file key-value pairs. The following example demonstrates how to use the provider. Overloads can specify whether the file is optional and if the configuration is reloaded on file changes. -The following code adds several configuration providers: -[!code-csharp[](~/fundamentals/configuration/index/samples/6.x/ConfigSample/Program.cs?name=snippet_ini)] +`IniConfig.ini`: -In the preceding code, settings in the `MyIniConfig.ini` and `MyIniConfig.{Environment}.ini` files are overridden by settings in the: +```ini +[ConnectionStrings] +DefaultConnection="Data Source=LocalSqlServer\\MSSQLDev;" -* [Environment variables configuration provider](#evcp) -* [Command-line configuration provider](#clcp). +[Logging:LogLevel] +Default=Debug +Microsoft=Debug +``` -The [sample download](https://github.com/dotnet/AspNetCore.Docs/tree/main/aspnetcore/fundamentals/configuration/index/samples/6.x/ConfigSample) contains the following `MyIniConfig.ini` file: +`IniConfig.Production.ini`: -[!code-ini[](~/fundamentals/configuration/index/samples/6.x/ConfigSample/MyIniConfig.ini)] +```ini +[ConnectionStrings] +DefaultConnection="Data Source=LocalSqlServer\\MSSQLProd;" -The following code from the [sample download](https://github.com/dotnet/AspNetCore.Docs/tree/main/aspnetcore/fundamentals/configuration/index/samples/6.x/ConfigSample) displays several of the preceding configurations settings: +[Logging:LogLevel] +Default=Information +Microsoft=Warning +``` -[!code-csharp[](~/fundamentals/configuration/index/samples/3.x/ConfigSample/Pages/Test.cshtml.cs?name=snippet)] +Load the configuration by calling . The following example creates a configuration source for each of the preceding files. The non-environmental file reloads configuration if the file is changed (`reloadOnChange` parameter, default: `false`). The environmental version of the file specifies that the file is optional (`optional` parameter, default: `false`). If you want to specify reloading the file on change (`reloadOnChange: true`), then you must also specify whether or not the file is optional (`optional`). - +::: moniker range=">= aspnetcore-6.0" -### JSON configuration provider +```csharp +builder.Configuration + .AddIniFile("IniConfig.ini", optional: false, reloadOnChange: true); + .AddIniFile($"IniConfig.{builder.Environment.EnvironmentName}.ini", optional: true); +``` -The loads configuration from JSON file key-value pairs. +::: moniker-end -Overloads can specify: +::: moniker range="< aspnetcore-6.0" -* Whether the file is optional. -* Whether the configuration is reloaded if the file changes. +```csharp +Host.CreateDefaultBuilder(args) + .ConfigureWebHostDefaults(webBuilder => + { + webBuilder.UseStartup(); + }) +.ConfigureAppConfiguration(config => +{ + config + .AddIniFile("IniConfig.ini", optional:false, reloadOnChange: true) + .AddIniFile("IniConfig.Production.ini", optional: true); +}); +``` -Consider the following code: +::: moniker-end -[!code-csharp[](~/fundamentals/configuration/index/samples/6.x/ConfigSample/Program.cs?name=snippet_json)] +### JSON Configuration Provider -The preceding code: +The loads configuration from JSON file key-value pairs. The following example demonstrates how to use the provider. Overloads can specify whether the file is optional and if the configuration is reloaded on file changes. -* Configures the JSON configuration provider to load the `MyConfig.json` file with the following options: - * `optional: true`: The file is optional. - * `reloadOnChange: true` : The file is reloaded when changes are saved. -* Reads the [default configuration providers](#default) before the `MyConfig.json` file. Settings in the `MyConfig.json` file override setting in the default configuration providers, including the [Environment variables configuration provider](#evcp) and the [Command-line configuration provider](#clcp). +Call with the file path (or file name if the file is at the root of the app). The following makes the file optional (`optional` parameter, default: `false`) and specifies that the configuration is reloaded if the file is changed (`reloadOnChange` parameter, default: `false`). If you want to specify reloading the file on change (`reloadOnChange: true`), then you must also specify whether or not the file is optional (`optional`). -You typically ***don't*** want a custom JSON file overriding values set in the [Environment variables configuration provider](#evcp) and the [Command-line configuration provider](#clcp). - +`XmlFile.xml`: -### XML configuration provider +```xml + + + + Data Source=LocalSqlServer\\MSSQLDev; + + + + Debug + Debug + + + +``` -The loads configuration from XML file key-value pairs at runtime. +`XmlFile.Production.xml`: -The following code adds several configuration providers: +```xml + + + + Data Source=LocalSqlServer\\MSSQLProd; + + + + Information + Warning + + + +``` -[!code-csharp[](~/fundamentals/configuration/index/samples/6.x/ConfigSample/Program.cs?name=snippet_xml)] +Load the configuration by calling . The following example creates a configuration source for each of the preceding files. The non-environmental file reloads configuration if the file is changed (`reloadOnChange` parameter, default: `false`). The environmental version of the file specifies that the file is optional (`optional` parameter, default: `false`). If you want to specify reloading the file on change (`reloadOnChange: true`), then you must also specify whether or not the file is optional (`optional`). -In the preceding code, settings in the `MyXMLFile.xml` and `MyXMLFile.{Environment}.xml` files are overridden by settings in the: +::: moniker range=">= aspnetcore-6.0" -* [Environment variables configuration provider](#evcp) -* [Command-line configuration provider](#clcp). +```csharp +builder.Configuration + .AddXmlFile("XmlFile.xml", optional: false, reloadOnChange: true); + .AddXmlFile($"XmlFile.{builder.Environment.EnvironmentName}.xml", optional: true); +``` -The [sample download](https://github.com/dotnet/AspNetCore.Docs/tree/main/aspnetcore/fundamentals/configuration/index/samples/6.x/ConfigSample) contains the following `MyXMLFile.xml` file: +::: moniker-end -[!code-xml[](~/fundamentals/configuration/index/samples/6.x/ConfigSample/MyXMLFile.xml)] +::: moniker range="< aspnetcore-6.0" -The following code from the [sample download](https://github.com/dotnet/AspNetCore.Docs/tree/main/aspnetcore/fundamentals/configuration/index/samples/6.x/ConfigSample) displays several of the preceding configurations settings: +```csharp +Host.CreateDefaultBuilder(args) + .ConfigureWebHostDefaults(webBuilder => + { + webBuilder.UseStartup(); + }) +.ConfigureAppConfiguration(config => +{ + config + .AddXmlFile("XmlFile.xml", optional:false, reloadOnChange: true) + .AddXmlFile("XmlFile.Production.xml", optional: true); +}); +``` -[!code-csharp[](~/fundamentals/configuration/index/samples/6.x/ConfigSample/Pages/Test.cshtml.cs?name=snippet)] +::: moniker-end Repeating elements that use the same element name work if the `name` attribute is used to distinguish the elements: -[!code-xml[](~/fundamentals/configuration/index/samples/6.x/ConfigSample/MyXMLFile3.xml)] - -The following code reads the previous configuration file and displays the keys and values: +```xml + + +
+ value 00 + value 01 +
+
+ value 10 + value 11 +
+
+``` -[!code-csharp[](~/fundamentals/configuration/index/samples/6.x/ConfigSample/Pages/XML/Index.cshtml.cs?name=snippet)] +```csharp +var value_00 = Config["section:section0:key:key0"]; +var value_01 = Config["section:section0:key:key1"]; +var value_10 = Config["section:section1:key:key0"]; +var value_11 = Config["section:section1:key:key1"]; +``` -Attributes can be used to supply values: +Attributes that supply values are supported: ```xml @@ -611,14 +986,14 @@ Attributes can be used to supply values: ``` -The previous configuration file loads the following keys with `value`: +The previous configuration loads the following keys with `value`: -* key:attribute -* section:key:attribute +* `key:attribute` +* `section:key:attribute` -## Key-per-file configuration provider +## Key-per-file Configuration Provider -The uses a directory's files as configuration key-value pairs. The key is the file name. The value contains the file's contents. The Key-per-file configuration provider is used in Docker hosting scenarios. +The uses a directory's files as configuration key-value pairs. The key is the file name. The value contains the file's contents. The Key-per-file Configuration Provider is used in Docker hosting scenarios. To activate key-per-file configuration, call the extension method on an instance of . The `directoryPath` to the files must be an absolute path. @@ -629,7 +1004,16 @@ Overloads permit specifying: The double-underscore (`__`) is used as a configuration key delimiter in file names. For example, the file name `Logging__LogLevel__System` produces the configuration key `Logging:LogLevel:System`. -Call `ConfigureAppConfiguration` when building the host to specify the app's configuration: +::: moniker range=">= aspnetcore-6.0" + +```csharp +var path = Path.Combine(Directory.GetCurrentDirectory(), "path/to/files"); +builder.Configuration.AddKeyPerFile(directoryPath: path, optional: true); +``` + +::: moniker-end + +::: moniker range="< aspnetcore-6.0" ```csharp .ConfigureAppConfiguration((hostingContext, config) => @@ -640,169 +1024,430 @@ Call `ConfigureAppConfiguration` when building the host to specify the app's con }) ``` - +::: moniker-end -## Memory configuration provider +## Memory Configuration Provider The uses an in-memory collection as configuration key-value pairs. The following code adds a memory collection to the configuration system: -[!code-csharp[](~/fundamentals/configuration/index/samples/6.x/ConfigSample/Program.cs?name=snippet_mem)] +::: moniker range=">= aspnetcore-6.0" + +```csharp +var configSettings = new Dictionary +{ + { "ConnectionStrings:DefaultConnection", "Data Source=LocalSqlServer\\MSSQLDev;" }, + { "Logging:LogLevel:Default", "Information" } +}; + +builder.Configuration.AddInMemoryCollection(configSettings); +``` -The following code from the [sample download](https://github.com/dotnet/AspNetCore.Docs/tree/main/aspnetcore/fundamentals/configuration/index/samples/3.x/ConfigSample) displays the preceding configurations settings: +::: moniker-end -[!code-csharp[](~/fundamentals/configuration/index/samples/3.x/ConfigSample/Pages/Test.cshtml.cs?name=snippet)] +::: moniker range="< aspnetcore-6.0" -In the preceding code, `config.AddInMemoryCollection(Dict)` is added after the [default configuration providers](#default). For an example of ordering the configuration providers, see [JSON configuration provider](#jcp). +```csharp +Host.CreateDefaultBuilder(args) + .ConfigureWebHostDefaults(webBuilder => + { + webBuilder.UseStartup(); + }) + .ConfigureAppConfiguration(config => + { + var configSettings = new Dictionary + { + { "ConnectionStrings:DefaultConnection", "Data Source=LocalSqlServer\\MSSQLDev;" }, + { "Logging:LogLevel:Default", "Information" } + }; -See [Bind an array](#boa) for another example using `MemoryConfigurationProvider`. + config.AddInMemoryCollection(configSettings); + }); +``` + +::: moniker-end - +For an additional example that uses a , see the [Bind an array](#bind-an-array) section. ## Kestrel endpoint configuration -Kestrel specific endpoint configuration overrides all [cross-server](xref:fundamentals/servers/index) endpoint configurations. Cross-server endpoint configurations include: +Kestrel-specific endpoint configuration overrides all [cross-server](xref:fundamentals/servers/index) endpoint configurations. Cross-server endpoint configurations include: -* [UseUrls](xref:fundamentals/host/web-host#server-urls) -* `--urls` on the [command line](xref:fundamentals/configuration/index#command-line) -* The [environment variable](xref:fundamentals/configuration/index#environment-variables) `ASPNETCORE_URLS` +* [`UseUrls`](xref:fundamentals/host/web-host#server-urls). +* `--urls` on the [command line](xref:fundamentals/configuration/index#command-line). +* The `ASPNETCORE_URLS` [environment variable](xref:fundamentals/configuration/index#environment-variables). -Consider the following `appsettings.json` file used in an ASP.NET Core web app: +Consider the following Kestrel configuration section in an `appsettings.json` file: -[!code-json[](~/fundamentals/configuration/index/samples_snippets/5.x/appsettings.json?highlight=2-8)] +```json +"Kestrel": { + "Endpoints": { + "Https": { + "Url": "https://localhost:9999" + } + } +}, +``` -When the preceding highlighted markup is used in an ASP.NET Core web app ***and*** the app is launched on the command line with the following cross-server endpoint configuration: +The app is launched on the command line with [`dotnet run`](/dotnet/core/tools/dotnet-run) and the following cross-server endpoint configuration: -`dotnet run --urls="https://localhost:7777"` +```dotnetcli +dotnet run --urls="https://localhost:7777" +``` -Kestrel binds to the endpoint configured specifically for Kestrel in the `appsettings.json` file (`https://localhost:9999`) and not `https://localhost:7777`. +Kestrel binds to the endpoint configured specifically for Kestrel in the `appsettings.json` file (`https://localhost:9999`) and not the cross-server endpoint configuration passed to the `dotnet run` command (`https://localhost:7777`). -Consider the Kestrel specific endpoint configured as an environment variable: +However, consider the Kestrel-specific endpoint configured as an environment variable: -`set Kestrel__Endpoints__Https__Url=https://localhost:8888` +* Key: `Kestrel__Endpoints__Https__Url` +* Value: `https://localhost:8888` -In the preceding environment variable, `Https` is the name of the Kestrel specific endpoint. The preceding `appsettings.json` file also defines a Kestrel specific endpoint named `Https`. By [default](#default-host-configuration), environment variables using the [Environment Variables configuration provider](#evcp) are read after `appsettings.{Environment}.json`, therefore, the preceding environment variable is used for the `Https` endpoint. +In the preceding environment variable, "`Https`" is the name of the Kestrel-specific endpoint. The preceding app settings configuration also defines a Kestrel-specific endpoint named `Https`. Per the [default host configuration providers](#default-host-configuration-sources), environment variables read by the [Environment Variables Configuration Provider](#environment-variables-configuration-provider) are read after `appsettings.{ENVIRONMENT}.json`. Therefore, the preceding environment variable (`Kestrel__Endpoints__Https__Url`) is used for the `Https` endpoint. -## GetValue +## Extract a single value from configuration with type conversion (`GetValue`) extracts a single value from configuration with a specified key and converts it to the specified type: -[!code-csharp[](~/fundamentals/configuration/index/samples/6.x/ConfigSample/Pages/TestNum.cshtml.cs?name=snippet)] +```csharp +var number = Config.GetValue("NumberKey", 99); +``` -In the preceding code, if `NumberKey` isn't found in the configuration, the default value of `99` is used. +In the preceding code: -## GetSection, GetChildren, and Exists +* `Config` is an injected . +* If `NumberKey` isn't found in the configuration, the default value of `99` is used. -For the examples that follow, consider the following `MySubsection.json` file: +## Work with sections, get a section's children, and determine if a section exists -[!code-json[](~/fundamentals/configuration/index/samples/6.x/ConfigSample/MySubsection.json)] +For the examples that follow, consider the following `subsection.json` file: -The following code adds `MySubsection.json` to the configuration providers: +```json +{ + "section0": { + "key0": "value00", + "key1": "value01" + }, + "section1": { + "key0": "value10", + "key1": "value11" + }, + "section2": { + "subsection0": { + "key0": "value200", + "key1": "value201" + }, + "subsection1": { + "key0": "value210", + "key1": "value211" + } + } +} +``` -[!code-csharp[](~/fundamentals/configuration/index/samples/6.x/ConfigSample/Program.cs?name=snippet_sub)] +A configuration provider is added for `subsection.json` by calling [`AddJsonFile`](#json-configuration-provider). -### GetSection +### `GetSection` returns a configuration subsection with the specified subsection key. -The following code returns values for `section1`: +The following code returns values for `section1`, where `Config` is an injected : -[!code-csharp[](~/fundamentals/configuration/index/samples/6.x/ConfigSample/Pages/TestSection.cshtml.cs?name=snippet)] +```csharp +var subsection = Config.GetSection("section1"); +var value1 = subsection["key0"]; +var value2 = subsection["key1"]; +``` + +The following code returns values for `section2:subsection0`, where `Config` is an injected : -The following code returns values for `section2:subsection0`: +```csharp +var subsection = Config.GetSection("section2:subsection0"); +var value1 = subsection["key0"]; +var value2 = subsection["key1"]; +``` -[!code-csharp[](~/fundamentals/configuration/index/samples/6.x/ConfigSample/Pages/TestSection2.cshtml.cs?name=snippet)] + never returns `null`. If a matching section isn't found, an empty is returned. -`GetSection` never returns `null`. If a matching section isn't found, an empty `IConfigurationSection` is returned. +When returns a matching section, isn't populated. A and are returned when the section exists. -When `GetSection` returns a matching section, isn't populated. A and are returned when the section exists. +### `GetChildren` and `Exists` -### GetChildren and Exists +The following code calls: -The following code calls and returns values for `section2:subsection0`: +* to verify that `section2` exists. +* and returns values for the subsections of `section2`. -[!code-csharp[](~/fundamentals/configuration/index/samples/6.x/ConfigSample/Pages/TestSection4.cshtml.cs?name=snippet)] +```csharp +var section = Config.GetSection("section2"); -The preceding code calls to verify the section exists: +if (!section.Exists()) +{ + throw new Exception("section2 doesn't exist!"); +} - +var children = section.GetChildren(); + +foreach (var subSection in children) +{ + int i = 0; + var key1 = subSection.Key + ":key" + i++.ToString(); + var key2 = subSection.Key + ":key" + i.ToString(); + Console.WriteLine($"{key1} value: {section[key1]}"); + Console.WriteLine($"{key2} value: {section[key2]}"); +} +``` + +Output: + + + +> no-loc text="subsection0:key0 value: value200"::: +> no-loc text="subsection0:key1 value: value201"::: +> no-loc text="subsection1:key0 value: value210"::: +> no-loc text="subsection1:key1 value: value211"::: ## Bind an array The supports binding arrays to objects using array indices in configuration keys. Any array format that exposes a numeric key segment is capable of array binding to a [POCO](https://wikipedia.org/wiki/Plain_Old_CLR_Object) class array. -Consider `MyArray.json` from the [sample download](https://github.com/dotnet/AspNetCore.Docs/tree/main/aspnetcore/fundamentals/configuration/index/samples/6.x/ConfigSample): +`array.json`: -[!code-json[](~/fundamentals/configuration/index/samples/6.x/ConfigSample/MyArray.json)] +```json +{ + "array": { + "entries": { + "0": "value00", + "1": "value10", + "2": "value20", + "4": "value40", + "5": "value50" + } + } +} +``` -The following code adds `MyArray.json` to the configuration providers: +A configuration provider is added for `array.json` by calling [`AddJsonFile`](#json-configuration-provider). -[!code-csharp[](~/fundamentals/configuration/index/samples/6.x/ConfigSample/Program.cs?name=snippet_ba)] +The following code reads the configuration values: -The following code reads the configuration and displays the values: +`ArrayExample.cs`: -[!code-csharp[](~/fundamentals/configuration/index/samples/6.x/ConfigSample/Pages/Array.cshtml.cs?name=snippet)] +```csharp +public class ArrayExample +{ + public string[]? Entries { get; set; } +} +``` -[!code-csharp[](~/fundamentals/configuration/index/samples/6.x/ConfigSample/Options/ArrayExample.cs?name=snippet)] +```csharp +var array = Config.GetSection("array").Get(); -The preceding code returns the following output: +if (array is null) +{ + throw new ArgumentNullException(nameof(array)); +} -```text -Index: 0 Value: value00 -Index: 1 Value: value10 -Index: 2 Value: value20 -Index: 3 Value: value40 -Index: 4 Value: value50 +string output = String.Empty; + +for (int j = 0; j < array.Entries?.Length; j++) +{ + Console.WriteLine($"Index: {j} Value: {array.Entries[j]}"); +} +``` + +Output: + +```console +Index: 0 Value: value00 +Index: 1 Value: value10 +Index: 2 Value: value20 +Index: 3 Value: value40 +Index: 4 Value: value50 ``` -In the preceding output, Index 3 has value `value40`, corresponding to `"4": "value40",` in `MyArray.json`. The bound array indices are continuous and not bound to the configuration key index. The configuration binder isn't capable of binding null values or creating null entries in bound objects. - + +The following code loads the `array:entries` configuration with the extension method: + +```csharp +public class Program +{ + public static void Main(string[] args) + { + CreateHostBuilder(args).Build().Run(); + } + + public static IHostBuilder CreateHostBuilder(string[] args) + { + var arrayDict = new Dictionary + { + {"array:entries:0", "value0"}, + {"array:entries:1", "value1"}, + {"array:entries:2", "value2"}, + // 3 Skipped + {"array:entries:4", "value4"}, + {"array:entries:5", "value5"} + }; + + return Host.CreateDefaultBuilder(args) + .ConfigureAppConfiguration((hostingContext, config) => + { + config.AddInMemoryCollection(arrayDict); + }) + .ConfigureWebHostDefaults(webBuilder => + { + webBuilder.UseStartup(); + }); + } +} +``` The following code reads the configuration in the `arrayDict` `Dictionary` and displays the values: -[!code-csharp[](~/fundamentals/configuration/index/samples/3.x/ConfigSample/Pages/Array.cshtml.cs?name=snippet)] +```csharp +public class ArrayModel : PageModel +{ + private readonly IConfiguration Config; + public ArrayExample _array { get; private set; } + + public ArrayModel(IConfiguration config) + { + Config = config; + } + + public ContentResult OnGet() + { + _array = Config.GetSection("array").Get(); + string s = null; + + for (int j = 0; j < _array.Entries.Length; j++) + { + s += $"Index: {j} Value: {_array.Entries[j]} \n"; + } + + return Content(s); + } +} +``` The preceding code returns the following output: ```text -Index: 0 Value: value0 -Index: 1 Value: value1 -Index: 2 Value: value2 -Index: 3 Value: value4 -Index: 4 Value: value5 +Index: 0 Value: value0 +Index: 1 Value: value1 +Index: 2 Value: value2 +Index: 3 Value: value4 +Index: 4 Value: value5 ``` Index #3 in the bound object holds the configuration data for the `array:4` configuration key and its value of `value4`. When configuration data containing an array is bound, the array indices in the configuration keys are used to iterate the configuration data when creating the object. A null value can't be retained in configuration data, and a null-valued entry isn't created in a bound object when an array in configuration keys skip one or more indices. The missing configuration item for index #3 can be supplied before binding to the `ArrayExample` instance by any configuration provider that reads the index #3 key/value pair. Consider the following `Value3.json` file from the sample download: -[!code-json[](~/fundamentals/configuration/index/samples/3.x/ConfigSample/Value3.json)] +```json +{ + "array:entries:3": "value3" +} +``` The following code includes configuration for `Value3.json` and the `arrayDict` `Dictionary`: -[!code-csharp[](~/fundamentals/configuration/index/samples/3.x/ConfigSample/ProgramArray.cs?name=snippet2)] +```csharp +public class Program +{ + public static void Main(string[] args) + { + CreateHostBuilder(args).Build().Run(); + } + + public static IHostBuilder CreateHostBuilder(string[] args) + { + var arrayDict = new Dictionary + { + {"array:entries:0", "value0"}, + {"array:entries:1", "value1"}, + {"array:entries:2", "value2"}, + // 3 Skipped + {"array:entries:4", "value4"}, + {"array:entries:5", "value5"} + }; + + return Host.CreateDefaultBuilder(args) + .ConfigureAppConfiguration((hostingContext, config) => + { + config.AddInMemoryCollection(arrayDict); + config.AddJsonFile("Value3.json", + optional: false, reloadOnChange: false); + }) + .ConfigureWebHostDefaults(webBuilder => + { + webBuilder.UseStartup(); + }); + } +} +``` The following code reads the preceding configuration and displays the values: -[!code-csharp[](~/fundamentals/configuration/index/samples/3.x/ConfigSample/Pages/Array.cshtml.cs?name=snippet)] +```csharp +public class ArrayModel : PageModel +{ + private readonly IConfiguration Config; + public ArrayExample _array { get; private set; } + + public ArrayModel(IConfiguration config) + { + Config = config; + } + + public ContentResult OnGet() + { + _array = Config.GetSection("array").Get(); + string s = null; + + for (int j = 0; j < _array.Entries.Length; j++) + { + s += $"Index: {j} Value: {_array.Entries[j]} \n"; + } + + return Content(s); + } +} +``` The preceding code returns the following output: ```text -Index: 0 Value: value0 -Index: 1 Value: value1 -Index: 2 Value: value2 -Index: 3 Value: value3 -Index: 4 Value: value4 -Index: 5 Value: value5 +Index: 0 Value: value0 +Index: 1 Value: value1 +Index: 2 Value: value2 +Index: 3 Value: value3 +Index: 4 Value: value4 +Index: 5 Value: value5 ``` Custom configuration providers aren't required to implement array binding. ---> + +:::moniker-end ## Custom configuration provider @@ -810,7 +1455,7 @@ The sample app demonstrates how to create a basic configuration provider that re The provider has the following characteristics: -* The EF in-memory database is used for demonstration purposes. To use a database that requires a connection string, implement a secondary `ConfigurationBuilder` to supply the connection string from another configuration provider. +* The EF in-memory database is used for demonstration purposes. To use a database that requires a connection string, implement a secondary to supply the connection string from another configuration provider. * The provider reads a database table into configuration at startup. The provider doesn't query the database on a per-key basis. * Reload-on-change isn't implemented, so updating the database after the app starts has no effect on the app's configuration. @@ -818,165 +1463,286 @@ Define an `EFConfigurationValue` entity for storing configuration values in the `Models/EFConfigurationValue.cs`: -[!code-csharp[](~/fundamentals/configuration/index/samples/6.x/EfconfigSample/Models/EFConfigurationValue.cs?name=snippet1)] +```csharp +public class EFConfigurationValue +{ + public string Id { get; set; } = string.Empty; + public string Value { get; set; } = string.Empty; +} +``` Add an `EFConfigurationContext` to store and access the configured values. `EFConfigurationProvider/EFConfigurationContext.cs`: -[!code-csharp[](~/fundamentals/configuration/index/samples/6.x/EfconfigSample/EFConfigurationProvider/EFConfigurationContext.cs?name=snippet1)] +::: moniker range=">= aspnetcore-6.0" -Create a class that implements . +```csharp +public class EFConfigurationContext : DbContext +{ + public EFConfigurationContext( + DbContextOptions options) : base(options) + { + } -`EFConfigurationProvider/EFConfigurationSource.cs`: + public DbSet Values => Set(); +} +``` -[!code-csharp[](~/fundamentals/configuration/index/samples/6.x/EfconfigSample/EFConfigurationProvider/EFConfigurationSource.cs?name=snippet1)] +::: moniker-end -Create the custom configuration provider by inheriting from . The configuration provider initializes the database when it's empty. Since configuration keys are case-insensitive, the dictionary used to initialize the database is created with the case-insensitive comparer ([StringComparer.OrdinalIgnoreCase](xref:System.StringComparer.OrdinalIgnoreCase)). +::: moniker range="< aspnetcore-6.0" -`EFConfigurationProvider/EFConfigurationProvider.cs`: +```csharp +// using Microsoft.EntityFrameworkCore; + +public class EFConfigurationContext : DbContext +{ + public EFConfigurationContext(DbContextOptions options) : base(options) + { + } -[!code-csharp[](~/fundamentals/configuration/index/samples/6.x/EfconfigSample/EFConfigurationProvider/EFConfigurationProvider.cs?name=snippet1)] + public DbSet Values { get; set; } +} +``` -An `AddEFConfiguration` extension method permits adding the configuration source to a `ConfigurationBuilder`. +::: moniker-end -`Extensions/EntityFrameworkExtensions.cs`: +Create a class that implements . -[!code-csharp[](~/fundamentals/configuration/index/samples/6.x/EfconfigSample/Extensions/EntityFrameworkExtensions.cs?name=snippet1)] +`EFConfigurationProvider/EFConfigurationSource.cs`: -The following code shows how to use the custom `EFConfigurationProvider` in `Program.cs`: +::: moniker range="< aspnetcore-6.0" -[!code-csharp[](~/fundamentals/configuration/index/samples_snippets/6.x/EfconfigSample/Program.cs?highlight=5-6)] +> [!NOTE] +> The example requires the following `using` statements: +> +> ```csharp +> using Microsoft.EntityFrameworkCore; +> using Microsoft.Extensions.Configuration; +> ``` -## Access configuration with Dependency Injection (DI) +::: moniker-end -Configuration can be injected into services using [Dependency Injection (DI)](xref:fundamentals/dependency-injection) by resolving the service: +```csharp +public class EFConfigurationSource : IConfigurationSource +{ + private readonly Action _optionsAction; -[!code-csharp[](~/fundamentals/configuration/index/samples/6.x/ConfigSample/Service.cs?name=snippet_Class&highlight=5-6)] + public EFConfigurationSource(Action optionsAction) => + _optionsAction = optionsAction; -For information on how to access values using `IConfiguration`, see [GetValue](#getvalue) and [GetSection, GetChildren, and Exists](#getsection-getchildren-and-exists) in this article. + public IConfigurationProvider Build(IConfigurationBuilder builder) => + new EFConfigurationProvider(_optionsAction); +} +``` -## Access configuration in Razor Pages +Create the custom configuration provider by inheriting from . The configuration provider initializes the database when it's empty. Since configuration keys are case-insensitive, the dictionary used to initialize the database is created with the case-insensitive comparer, . -The following code displays configuration data in a Razor Page: +`EFConfigurationProvider/EFConfigurationProvider.cs`: -[!code-cshtml[](~/fundamentals/configuration/index/samples/6.x/ConfigSample/Pages/Test5.cshtml)] +::: moniker range=">= aspnetcore-6.0" -In the following code, `MyOptions` is added to the service container with and bound to configuration: +```csharp +public class EFConfigurationProvider : ConfigurationProvider +{ + public EFConfigurationProvider(Action optionsAction) + { + OptionsAction = optionsAction; + } -[!code-csharp[](~/fundamentals/configuration/options/samples/6.x/OptionsSample/Program.cs?name=snippet)] + Action OptionsAction { get; } -The following markup uses the [`@inject`](xref:mvc/views/razor#inject) Razor directive to resolve and display the options values: + public override void Load() + { + var builder = new DbContextOptionsBuilder(); -[!code-cshtml[](~/fundamentals/configuration/options/samples/6.x/OptionsSample/Pages/Test3.cshtml)] + OptionsAction(builder); -## Access configuration in a MVC view file + using (var dbContext = new EFConfigurationContext(builder.Options)) + { + if (dbContext == null || dbContext.Values == null) + { + throw new Exception("Null DB context"); + } + dbContext.Database.EnsureCreated(); -The following code displays configuration data in a MVC view: + Data = !dbContext.Values.Any() + ? CreateAndSaveDefaultValues(dbContext) + : dbContext.Values.ToDictionary(c => c.Id, c => c.Value); + } + } + + private static IDictionary CreateAndSaveDefaultValues( + EFConfigurationContext dbContext) + { + // Quotes (c)2005 Universal Pictures: Serenity + // https://www.uphe.com/movies/serenity-2005 + var configValues = + new Dictionary(StringComparer.OrdinalIgnoreCase) + { + { "quote1", "I aim to misbehave." }, + { "quote2", "I swallowed a bug." }, + { "quote3", "You can't stop the signal, Mal." } + }; + + if (dbContext == null || dbContext.Values == null) + { + throw new Exception("Null DB context"); + } -[!code-cshtml[](~/fundamentals/configuration/index/samples/3.x/ConfigSample/Views/Home2/Index.cshtml)] + dbContext.Values.AddRange(configValues + .Select(kvp => new EFConfigurationValue + { + Id = kvp.Key, + Value = kvp.Value + }) + .ToArray()); -## Access configuration in `Program.cs` + dbContext.SaveChanges(); -The following code accesses configuration in the `Program.cs` file. + return configValues; + } +} +``` -```csharp -var builder = WebApplication.CreateBuilder(args); +::: moniker-end -var key1 = builder.Configuration.GetValue("KeyOne"); +::: moniker range="< aspnetcore-6.0" -var app = builder.Build(); +```csharp +// using Microsoft.EntityFrameworkCore; +// using Microsoft.Extensions.Configuration; -app.MapGet("/", () => "Hello World!"); +public class EFConfigurationProvider : ConfigurationProvider +{ + public EFConfigurationProvider(Action optionsAction) + { + OptionsAction = optionsAction; + } -var key2 = app.Configuration.GetValue("KeyTwo"); -var key3 = app.Configuration.GetValue("KeyThree"); + Action OptionsAction { get; } -app.Logger.LogInformation("KeyOne: {KeyOne}", key1); -app.Logger.LogInformation("KeyTwo: {KeyTwo}", key2); -app.Logger.LogInformation("KeyThree: {KeyThree}", key3); + public override void Load() + { + var builder = new DbContextOptionsBuilder(); -app.Run(); -``` + OptionsAction(builder); -In `appsettings.json` for the preceding example: + using (var dbContext = new EFConfigurationContext(builder.Options)) + { + dbContext.Database.EnsureCreated(); -```json -{ - ... - "KeyOne": "Key One Value", - "KeyTwo": 1999, - "KeyThree": true + Data = !dbContext.Values.Any() + ? CreateAndSaveDefaultValues(dbContext) + : dbContext.Values.ToDictionary(c => c.Id, c => c.Value); + } + } + + private static IDictionary CreateAndSaveDefaultValues( + EFConfigurationContext dbContext) + { + // Quotes (c)2005 Universal Pictures: Serenity + // https://www.uphe.com/movies/serenity-2005 + var configValues = + new Dictionary(StringComparer.OrdinalIgnoreCase) + { + { "quote1", "I aim to misbehave." }, + { "quote2", "I swallowed a bug." }, + { "quote3", "You can't stop the signal, Mal." } + }; + + dbContext.Values.AddRange(configValues + .Select(kvp => new EFConfigurationValue + { + Id = kvp.Key, + Value = kvp.Value + }) + .ToArray()); + + dbContext.SaveChanges(); + + return configValues; + } } ``` -## Configure options with a delegate - -Options configured in a delegate override values set in the configuration providers. - -In the following code, an service is added to the service container. It uses a delegate to configure values for `MyOptions`: - -[!code-csharp[](~/fundamentals/configuration/options/samples/6.x/OptionsSample/Program.cs?name=snippet_del)] +::: moniker-end -The following code displays the options values: +An `AddEFConfiguration` extension method permits adding the configuration source to a . -[!code-csharp[](~/fundamentals/configuration/options/samples/6.x/OptionsSample/Pages/Test2.cshtml.cs?name=snippet)] - -In the preceding example, the values of `Option1` and `Option2` are specified in `appsettings.json` and then overridden by the configured delegate. +`Extensions/EntityFrameworkExtensions.cs`: - +::: moniker range="< aspnetcore-6.0" -## Host versus app configuration +> [!NOTE] +> The example requires the following `using` statements: +> +> ```csharp +> using Microsoft.EntityFrameworkCore; +> using Microsoft.Extensions.Configuration; +> ``` -Before the app is configured and started, a *host* is configured and launched. The host is responsible for app startup and lifetime management. Both the app and the host are configured using the configuration providers described in this topic. Host configuration key-value pairs are also included in the app's configuration. For more information on how the configuration providers are used when the host is built and how configuration sources affect host configuration, see . +::: moniker-end - +```csharp +public static class EntityFrameworkExtensions +{ + public static IConfigurationBuilder AddEFConfiguration( + this IConfigurationBuilder builder, + Action optionsAction) + { + return builder.Add(new EFConfigurationSource(optionsAction)); + } +} +``` -## Default host configuration +The following code shows how to use the custom `EFConfigurationProvider` in the app's `Program` file: -For details on the default configuration when using the [Web Host](xref:fundamentals/host/web-host), see the [ASP.NET Core 2.2 version of this topic](?view=aspnetcore-2.2&preserve-view=true). +::: moniker range=">= aspnetcore-6.0" -* Host configuration is provided from: - * Environment variables prefixed with `DOTNET_` (for example, `DOTNET_ENVIRONMENT`) using the [Environment Variables configuration provider](#evcp). The prefix (`DOTNET_`) is stripped when the configuration key-value pairs are loaded. - * Command-line arguments using the [Command-line configuration provider](#clcp). -* Web Host default configuration is established (`ConfigureWebHostDefaults`): - * Kestrel is used as the web server and configured using the app's configuration providers. - * Add Host Filtering Middleware. - * Add Forwarded Headers Middleware if the `ASPNETCORE_FORWARDEDHEADERS_ENABLED` environment variable is set to `true`. - * Enable IIS integration. +```csharp +builder.Configuration.AddEFConfiguration( + opt => opt.UseInMemoryDatabase("InMemoryDb")); +``` -## Other configuration +::: moniker-end -This topic only pertains to *app configuration*. Other aspects of running and hosting ASP.NET Core apps are configured using configuration files not covered in this topic: +::: moniker range="< aspnetcore-6.0" -* `launch.json`/`launchSettings.json` are tooling configuration files for the Development environment, described: - * In . - * Across the documentation set where the files are used to configure ASP.NET Core apps for Development scenarios. -* `web.config` is a server configuration file, described in the following topics: - * - * +```csharp +public static IHostBuilder CreateHostBuilder(string[] args) => + Host.CreateDefaultBuilder(args) + .ConfigureAppConfiguration((hostingContext, config) => + { + config.AddEFConfiguration( + options => options.UseInMemoryDatabase("InMemoryDb")); + }) + .ConfigureWebHostDefaults(webBuilder => + { + webBuilder.UseStartup(); + }); +``` -Environment variables set in `launchSettings.json` override those set in the system environment. +::: moniker-end -For more information on migrating app configuration from earlier versions of ASP.NET, see . +For an example of accessing configuration using startup convenience methods, see [App startup: Convenience methods](xref:fundamentals/startup#convenience-methods). ## Add configuration from an external assembly An implementation allows adding enhancements to an app at startup from an external assembly outside of the app's `Startup` class. For more information, see . +:::moniker range=">= aspnetcore-8.0" + ## Configuration-binding source generator The [Configuration-binding source generator](/dotnet/core/whats-new/dotnet-8/runtime#configuration-binding-source-generator) provides AOT and trim-friendly configuration. For more information, see [Configuration-binding source generator](/dotnet/core/whats-new/dotnet-8/runtime#configuration-binding-source-generator). +:::moniker-end + ## Additional resources +* * [Configuration source code](https://github.com/dotnet/runtime/tree/main/src/libraries/Microsoft.Extensions.Configuration) -* [View or download sample code](https://github.com/dotnet/AspNetCore.Docs/tree/main/aspnetcore/fundamentals/configuration/index/samples) ([how to download](xref:fundamentals/index#how-to-download-a-sample)) +* [View or download sample code](https://github.com/dotnet/AspNetCore.Docs.Samples/tree/main/fundamentals/configuration) ([how to download](xref:fundamentals/index#how-to-download-a-sample)) * -* - -:::moniker-end - -[!INCLUDE[](~/fundamentals/configuration/index/includes/index7.md)] -[!INCLUDE[](~/fundamentals/configuration/index/includes/index6.md)] -[!INCLUDE[](~/fundamentals/configuration/index/includes/index3-5.md)] diff --git a/aspnetcore/fundamentals/configuration/index/includes/index3-5.md b/aspnetcore/fundamentals/configuration/index/includes/index3-5.md deleted file mode 100644 index 9de0e3db874d..000000000000 --- a/aspnetcore/fundamentals/configuration/index/includes/index3-5.md +++ /dev/null @@ -1,288 +0,0 @@ -:::moniker range=">= aspnetcore-5.0 < aspnetcore-6.0" - - - -## Kestrel endpoint configuration - -Kestrel specific endpoint configuration overrides all [cross-server](xref:fundamentals/servers/index) endpoint configurations. Cross-server endpoint configurations include: - -* [UseUrls](xref:fundamentals/host/web-host#server-urls) -* `--urls` on the [command line](xref:fundamentals/configuration/index#command-line) -* The [environment variable](xref:fundamentals/configuration/index#environment-variables) `ASPNETCORE_URLS` - -Consider the following `appsettings.json` file used in an ASP.NET Core web app: - -[!code-json[](~/fundamentals/configuration/index/samples_snippets/5.x/appsettings.json?highlight=2-8)] - -When the preceding highlighted markup is used in an ASP.NET Core web app ***and*** the app is launched on the command line with the following cross-server endpoint configuration: - -`dotnet run --urls="https://localhost:7777"` - -Kestrel binds to the endpoint configured specifically for Kestrel in the `appsettings.json` file (`https://localhost:9999`) and not `https://localhost:7777`. - -Consider the Kestrel specific endpoint configured as an environment variable: - -`set Kestrel__Endpoints__Https__Url=https://localhost:8888` - -In the preceding environment variable, `Https` is the name of the Kestrel specific endpoint. The preceding `appsettings.json` file also defines a Kestrel specific endpoint named `Https`. By [default](#default-host-configuration), environment variables using the [Environment Variables configuration provider](#evcp) are read after `appsettings.{Environment}.json`, therefore, the preceding environment variable is used for the `Https` endpoint. - -:::moniker-end - -:::moniker range=">= aspnetcore-3.0 < aspnetcore-6.0" - -## GetValue - - extracts a single value from configuration with a specified key and converts it to the specified type. This method is an extension method for : - -[!code-csharp[](~/fundamentals/configuration/index/samples/3.x/ConfigSample/Pages/TestNum.cshtml.cs?name=snippet)] - -In the preceding code, if `NumberKey` isn't found in the configuration, the default value of `99` is used. - -## GetSection, GetChildren, and Exists - -For the examples that follow, consider the following `MySubsection.json` file: - -[!code-json[](~/fundamentals/configuration/index/samples/3.x/ConfigSample/MySubsection.json)] - -The following code adds `MySubsection.json` to the configuration providers: - -[!code-csharp[](~/fundamentals/configuration/index/samples/3.x/ConfigSample/ProgramJSONsection.cs?name=snippet)] - -### GetSection - - returns a configuration subsection with the specified subsection key. - -The following code returns values for `section1`: - -[!code-csharp[](~/fundamentals/configuration/index/samples/3.x/ConfigSample/Pages/TestSection.cshtml.cs?name=snippet)] - -The following code returns values for `section2:subsection0`: - -[!code-csharp[](~/fundamentals/configuration/index/samples/3.x/ConfigSample/Pages/TestSection2.cshtml.cs?name=snippet)] - -`GetSection` never returns `null`. If a matching section isn't found, an empty `IConfigurationSection` is returned. - -When `GetSection` returns a matching section, isn't populated. A and are returned when the section exists. - -### GetChildren and Exists - -The following code calls and returns values for `section2:subsection0`: - -[!code-csharp[](~/fundamentals/configuration/index/samples/3.x/ConfigSample/Pages/TestSection4.cshtml.cs?name=snippet)] - -The preceding code calls to verify the section exists: - - - -## Bind an array - -The supports binding arrays to objects using array indices in configuration keys. Any array format that exposes a numeric key segment is capable of array binding to a [POCO](https://wikipedia.org/wiki/Plain_Old_CLR_Object) class array. - -Consider `MyArray.json` from the [sample download](https://github.com/dotnet/AspNetCore.Docs/tree/main/aspnetcore/fundamentals/configuration/index/samples/3.x/ConfigSample): - -[!code-json[](~/fundamentals/configuration/index/samples/3.x/ConfigSample/MyArray.json)] - -The following code adds `MyArray.json` to the configuration providers: - -[!code-csharp[](~/fundamentals/configuration/index/samples/3.x/ConfigSample/ProgramJSONarray.cs?name=snippet)] - -The following code reads the configuration and displays the values: - -[!code-csharp[](~/fundamentals/configuration/index/samples/3.x/ConfigSample/Pages/Array.cshtml.cs?name=snippet)] - -The preceding code returns the following output: - -```text -Index: 0 Value: value00 -Index: 1 Value: value10 -Index: 2 Value: value20 -Index: 3 Value: value40 -Index: 4 Value: value50 -``` - -In the preceding output, Index 3 has value `value40`, corresponding to `"4": "value40",` in `MyArray.json`. The bound array indices are continuous and not bound to the configuration key index. The configuration binder isn't capable of binding null values or creating null entries in bound objects - -The following code loads the `array:entries` configuration with the extension method: - -[!code-csharp[](~/fundamentals/configuration/index/samples/3.x/ConfigSample/ProgramArray.cs?name=snippet)] - -The following code reads the configuration in the `arrayDict` `Dictionary` and displays the values: - -[!code-csharp[](~/fundamentals/configuration/index/samples/3.x/ConfigSample/Pages/Array.cshtml.cs?name=snippet)] - -The preceding code returns the following output: - -```text -Index: 0 Value: value0 -Index: 1 Value: value1 -Index: 2 Value: value2 -Index: 3 Value: value4 -Index: 4 Value: value5 -``` - -Index #3 in the bound object holds the configuration data for the `array:4` configuration key and its value of `value4`. When configuration data containing an array is bound, the array indices in the configuration keys are used to iterate the configuration data when creating the object. A null value can't be retained in configuration data, and a null-valued entry isn't created in a bound object when an array in configuration keys skip one or more indices. - -The missing configuration item for index #3 can be supplied before binding to the `ArrayExample` instance by any configuration provider that reads the index #3 key/value pair. Consider the following `Value3.json` file from the sample download: - -[!code-json[](~/fundamentals/configuration/index/samples/3.x/ConfigSample/Value3.json)] - -The following code includes configuration for `Value3.json` and the `arrayDict` `Dictionary`: - -[!code-csharp[](~/fundamentals/configuration/index/samples/3.x/ConfigSample/ProgramArray.cs?name=snippet2)] - -The following code reads the preceding configuration and displays the values: - -[!code-csharp[](~/fundamentals/configuration/index/samples/3.x/ConfigSample/Pages/Array.cshtml.cs?name=snippet)] - -The preceding code returns the following output: - -```text -Index: 0 Value: value0 -Index: 1 Value: value1 -Index: 2 Value: value2 -Index: 3 Value: value3 -Index: 4 Value: value4 -Index: 5 Value: value5 -``` - -Custom configuration providers aren't required to implement array binding. - -## Custom configuration provider - -[!INCLUDE [managed-identities](~/includes/managed-identities-conn-strings.md)] - -The sample app demonstrates how to create a basic configuration provider that reads configuration key-value pairs from a database using [Entity Framework (EF)](/ef/core/). - -The provider has the following characteristics: - -* The EF in-memory database is used for demonstration purposes. To use a database that requires a connection string, implement a secondary `ConfigurationBuilder` to supply the connection string from another configuration provider. -* The provider reads a database table into configuration at startup. The provider doesn't query the database on a per-key basis. -* Reload-on-change isn't implemented, so updating the database after the app starts has no effect on the app's configuration. - -Define an `EFConfigurationValue` entity for storing configuration values in the database. - -`Models/EFConfigurationValue.cs`: - -[!code-csharp[](~/fundamentals/configuration/index/samples/3.x/ConfigurationSample/Models/EFConfigurationValue.cs?name=snippet1)] - -Add an `EFConfigurationContext` to store and access the configured values. - -`EFConfigurationProvider/EFConfigurationContext.cs`: - -[!code-csharp[](~/fundamentals/configuration/index/samples/3.x/ConfigurationSample/EFConfigurationProvider/EFConfigurationContext.cs?name=snippet1)] - -Create a class that implements . - -`EFConfigurationProvider/EFConfigurationSource.cs`: - -[!code-csharp[](~/fundamentals/configuration/index/samples/3.x/ConfigurationSample/EFConfigurationProvider/EFConfigurationSource.cs?name=snippet1)] - -Create the custom configuration provider by inheriting from . The configuration provider initializes the database when it's empty. Since configuration keys are case-insensitive, the dictionary used to initialize the database is created with the case-insensitive comparer ([StringComparer.OrdinalIgnoreCase](xref:System.StringComparer.OrdinalIgnoreCase)). - -`EFConfigurationProvider/EFConfigurationProvider.cs`: - -[!code-csharp[](~/fundamentals/configuration/index/samples/3.x/ConfigurationSample/EFConfigurationProvider/EFConfigurationProvider.cs?name=snippet1)] - -An `AddEFConfiguration` extension method permits adding the configuration source to a `ConfigurationBuilder`. - -`Extensions/EntityFrameworkExtensions.cs`: - -[!code-csharp[](~/fundamentals/configuration/index/samples/3.x/ConfigurationSample/Extensions/EntityFrameworkExtensions.cs?name=snippet1)] - -The following code shows how to use the custom `EFConfigurationProvider` in `Program.cs`: - -[!code-csharp[](~/fundamentals/configuration/index/samples_snippets/3.x/ConfigurationSample/Program.cs?highlight=7-8)] - - - -## Access configuration in Startup - -The following code displays configuration data in `Startup` methods: - -[!code-csharp[](~/fundamentals/configuration/index/samples/3.x/ConfigSample/StartupKey.cs?name=snippet&highlight=13,18)] - -For an example of accessing configuration using startup convenience methods, see [App startup: Convenience methods](xref:fundamentals/startup#convenience-methods). - -## Access configuration in Razor Pages - -The following code displays configuration data in a Razor Page: - -[!code-cshtml[](~/fundamentals/configuration/index/samples/3.x/ConfigSample/Pages/Test5.cshtml)] - -In the following code, `MyOptions` is added to the service container with and bound to configuration: - -[!code-csharp[](~/fundamentals/configuration/options/samples/3.x/OptionsSample/Startup3.cs?name=snippet_Example2)] - -The following markup uses the [`@inject`](xref:mvc/views/razor#inject) Razor directive to resolve and display the options values: - -[!code-cshtml[](~/fundamentals/configuration/options/samples/3.x/OptionsSample/Pages/Test3.cshtml)] - -## Access configuration in a MVC view file - -The following code displays configuration data in a MVC view: - -[!code-cshtml[](~/fundamentals/configuration/index/samples/3.x/ConfigSample/Views/Home2/Index.cshtml)] - -## Configure options with a delegate - -Options configured in a delegate override values set in the configuration providers. - -Configuring options with a delegate is demonstrated as Example 2 in the sample app. - -In the following code, an service is added to the service container. It uses a delegate to configure values for `MyOptions`: - -[!code-csharp[](~/fundamentals/configuration/options/samples/3.x/OptionsSample/Startup2.cs?name=snippet_Example2)] - -The following code displays the options values: - -[!code-csharp[](~/fundamentals/configuration/options/samples/3.x/OptionsSample/Pages/Test2.cshtml.cs?name=snippet)] - -In the preceding example, the values of `Option1` and `Option2` are specified in `appsettings.json` and then overridden by the configured delegate. - - - -## Host versus app configuration - -Before the app is configured and started, a *host* is configured and launched. The host is responsible for app startup and lifetime management. Both the app and the host are configured using the configuration providers described in this topic. Host configuration key-value pairs are also included in the app's configuration. For more information on how the configuration providers are used when the host is built and how configuration sources affect host configuration, see . - - - -## Default host configuration - -For details on the default configuration when using the [Web Host](xref:fundamentals/host/web-host), see the [ASP.NET Core 2.2 version of this topic](?view=aspnetcore-2.2&preserve-view=true). - -* Host configuration is provided from: - * Environment variables prefixed with `DOTNET_` (for example, `DOTNET_ENVIRONMENT`) using the [Environment Variables configuration provider](#evcp). The prefix (`DOTNET_`) is stripped when the configuration key-value pairs are loaded. - * Command-line arguments using the Command-line configuration provider. -* Web Host default configuration is established (`ConfigureWebHostDefaults`): - * Kestrel is used as the web server and configured using the app's configuration providers. - * Add Host Filtering Middleware. - * Add Forwarded Headers Middleware if the `ASPNETCORE_FORWARDEDHEADERS_ENABLED` environment variable is set to `true`. - * Enable IIS integration. - -## Other configuration - -This topic only pertains to *app configuration*. Other aspects of running and hosting ASP.NET Core apps are configured using configuration files not covered in this topic: - -* `launch.json`/`launchSettings.json` are tooling configuration files for the Development environment, described: - * In . - * Across the documentation set where the files are used to configure ASP.NET Core apps for Development scenarios. -* `web.config` is a server configuration file, described in the following topics: - * - * - -Environment variables set in `launchSettings.json` override those set in the system environment. - -For more information on migrating app configuration from earlier versions of ASP.NET, see . - -## Add configuration from an external assembly - -An implementation allows adding enhancements to an app at startup from an external assembly outside of the app's `Startup` class. For more information, see . - -## Additional resources - -* [Configuration source code](https://github.com/dotnet/runtime/tree/main/src/libraries/Microsoft.Extensions.Configuration) -* -* - -:::moniker-end diff --git a/aspnetcore/fundamentals/configuration/index/includes/index6.md b/aspnetcore/fundamentals/configuration/index/includes/index6.md deleted file mode 100644 index 0c5f3d7e94e5..000000000000 --- a/aspnetcore/fundamentals/configuration/index/includes/index6.md +++ /dev/null @@ -1,939 +0,0 @@ -:::moniker range="= aspnetcore-6.0" - -Application configuration in ASP.NET Core is performed using one or more [configuration providers](#cp). 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 Configuration -* Command-line arguments -* Custom providers, installed or created -* Directory files -* In-memory .NET objects - -This article provides information on configuration in ASP.NET Core. For information on using configuration in console apps, see [.NET Configuration](/dotnet/core/extensions/configuration). - -## Application and Host Configuration - -ASP.NET Core apps configure and launch a *host*. The host is responsible for app startup and lifetime management. The ASP.NET Core templates create a which contains the host. While some configuration can be done in both the host and the application configuration providers, generally, only configuration that is necessary for the host should be done in host configuration. - -Application configuration is the highest priority and is detailed in the next section. [Host configuration](#host) follows application configuration, and is described in this article. - - - -### Default application configuration sources - -ASP.NET Core web apps created with [dotnet new](/dotnet/core/tools/dotnet-new) or Visual Studio generate the following code: - -```csharp -var builder = WebApplication.CreateBuilder(args); -``` - - - -[WebApplication.CreateBuilder](xref:Microsoft.AspNetCore.Builder.WebApplication.CreateBuilder%2A) initializes a new instance of the class with preconfigured defaults. The initialized `WebApplicationBuilder` (`builder`) provides default configuration for the app in the following order, from highest to lowest priority: - -1. Command-line arguments using the [Command-line configuration provider](#command-line). -1. Non-prefixed environment variables using the [Non-prefixed environment variables configuration provider](#evcp). -1. [User secrets](xref:security/app-secrets) when the app runs in the `Development` environment. -1. `appsettings.{Environment}.json` using the [JSON configuration provider](#file-configuration-provider). For example, `appsettings.Production.json` and `appsettings.Development.json`. -1. [appsettings.json](#appsettingsjson) using the [JSON configuration provider](#file-configuration-provider). -1. A fallback to the host configuration described in the [next section](#host). - - - -### Default host configuration sources - -The following list contains the default host configuration sources from highest to lowest priority: - -1. `ASPNETCORE_`-prefixed environment variables using the [Environment variables configuration provider](xref:Microsoft.Extensions.Configuration.EnvironmentVariables.EnvironmentVariablesConfigurationProvider). -1. Command-line arguments using the [Command-line configuration provider](#command-line) -1. `DOTNET_`-prefixed environment variables using the [Environment variables configuration provider](xref:Microsoft.Extensions.Configuration.EnvironmentVariables.EnvironmentVariablesConfigurationProvider). - -When a configuration value is set in host and application configuration, the application configuration is used. - - -See [**Explanation** in this GitHub comment](https://github.com/dotnet/AspNetCore.Docs/issues/25626#issuecomment-1098616664) for an explanation of why in host configuration, `ASPNETCORE_` prefixed environment variables have higher priority than command-line arguments. - -### Host variables - -The following variables are locked in early when initializing the host builders and can't be influenced by application config: - -* [Application name](xref:fundamentals/minimal-apis#change-the-content-root-application-name-and-environment) -* [Environment name](xref:fundamentals/environments), for example `Development`, `Production`, and `Staging` -* [Content root](xref:fundamentals/index#content-root) -* [Web root](xref:fundamentals/index#web-root) -* Whether to scan for [hosting startup assemblies](xref:fundamentals/configuration/platform-specific-configuration) and which assemblies to scan for. -* Variables read by app and library code from [HostBuilderContext.Configuration](xref:Microsoft.Extensions.Hosting.HostBuilderContext.Configuration) in [IHostBuilder.ConfigureAppConfiguration](xref:Microsoft.Extensions.Hosting.IHostBuilder.ConfigureAppConfiguration%2A) callbacks. - -Every other host setting is read from application config instead of host config. - -`URLS` is one of the many common host settings that is not a bootstrap setting. Like every other host setting not in the previous list, `URLS` is read later from application config. Host config is a fallback for application config, so host config can be used to set `URLS`, but it will be overridden by any configuration source in application config like `appsettings.json`. - -For more information, see [Change the content root, app name, and environment](xref:migration/50-to-60-samples#change-the-content-root-app-name-and-environment) and [Change the content root, app name, and environment by environment variables or command line](xref:migration/50-to-60-samples#change-the-content-root-app-name-and-environment-by-environment-variables-or-command-line) - -The remaining sections in this article refer to application configuration. - -## Application configuration providers - -The following code displays the enabled configuration providers in the order they were added: - -[!code-csharp[](~/fundamentals/configuration/index/samples/6.x/ConfigSample/Pages/Index2.cshtml.cs?name=snippet)] - -The preceding [list of highest to lowest priority default configuration sources](#hi2low) shows the providers in the opposite order they are added to template generated application. For example, the [JSON configuration provider](#file-configuration-provider) is added before the [Command-line configuration provider](#command-line). - -Configuration providers that are added later have higher priority and override previous key settings. For example, if `MyKey` is set in both `appsettings.json` and the environment, the environment value is used. Using the default configuration providers, the [Command-line configuration provider](#clcp) overrides all other providers. - -For more information on `CreateBuilder`, see [Default builder settings](xref:fundamentals/host/generic-host#default-builder-settings). - -### `appsettings.json` - -Consider the following `appsettings.json` file: - -[!code-json[](~/fundamentals/configuration/index/samples/6.x/ConfigSample/appsettings.json)] - -The following code from the [sample download](https://github.com/dotnet/AspNetCore.Docs/tree/main/aspnetcore/fundamentals/configuration/index/samples/6.x/ConfigSample) displays several of the preceding configurations settings: - -[!code-csharp[](~/fundamentals/configuration/index/samples/6.x/ConfigSample/Pages/Test.cshtml.cs?name=snippet)] - -The default loads configuration in the following order: - -1. `appsettings.json` -1. `appsettings.{Environment}.json` : For example, the `appsettings.Production.json` and `appsettings.Development.json` files. The environment version of the file is loaded based on the . For more information, see . - -`appsettings.{Environment}.json` values override keys in `appsettings.json`. For example, by default: - -* In development, `appsettings.Development.json` configuration overwrites values found in `appsettings.json`. -* In production, `appsettings.Production.json` configuration overwrites values found in `appsettings.json`. For example, when deploying the app to Azure. - -If a configuration value must be guaranteed, see [GetValue](#getvalue). The preceding example only reads strings and doesn’t support a default value. - -Using the [default](#default) configuration, the `appsettings.json` and `appsettings.{Environment}.json` files are enabled with [reloadOnChange: true](https://github.com/dotnet/extensions/blob/release/3.1/src/Hosting/Hosting/src/Host.cs#L74-L75). Changes made to the `appsettings.json` and `appsettings.{Environment}.json` file ***after*** the app starts are read by the [JSON configuration provider](#jcp). - - - -### Bind hierarchical configuration data using the options pattern - -[!INCLUDE[](~/includes/bind6.md)] - -Using the [default](#default) configuration, the `appsettings.json` and `appsettings.{Environment}.json` files are enabled with [reloadOnChange: true](https://github.com/dotnet/extensions/blob/release/3.1/src/Hosting/Hosting/src/Host.cs#L74-L75). Changes made to the `appsettings.json` and `appsettings.{Environment}.json` file ***after*** the app starts are read by the [JSON configuration provider](#jcp). - -See [JSON configuration provider](#jcp) in this document for information on adding additional JSON configuration files. - -## Combining service collection - -[!INCLUDE[](~/includes/combine-di6.md)] - - - -## Security and user secrets - -Configuration data guidelines: - -* Never store passwords or other sensitive data in configuration provider code or in plain text configuration files. The [Secret Manager](xref:security/app-secrets) tool can be used to store secrets in development. -* Don't use production secrets in development or test environments. -* Specify secrets outside of the project so that they can't be accidentally committed to a source code repository. -* Production apps should use the most secure authentication flow available. For more information, see [Secure authentication flows](xref:security/index#secure-authentication-flows). - -By [default](#default), the user secrets configuration source is registered after the JSON configuration sources. Therefore, user secrets keys take precedence over keys in `appsettings.json` and `appsettings.{Environment}.json`. - -For more information on storing passwords or other sensitive data: - -* -* : Includes advice on using environment variables to store sensitive data. The Secret Manager tool uses the [File configuration provider](#fcp) to store user secrets in a JSON file on the local system. - -[Azure Key Vault](https://azure.microsoft.com/services/key-vault/) safely stores app secrets for ASP.NET Core apps. For more information, see . - - - -## Non-prefixed environment variables - -Non-prefixed environment variables are environment variables other than those prefixed by `ASPNETCORE_` or `DOTNET_`. For example, the ASP.NET Core web application templates set `"ASPNETCORE_ENVIRONMENT": "Development"` in `launchSettings.json`. For more information on `ASPNETCORE_` and `DOTNET_` environment variables, see: - -* [List of highest to lowest priority default configuration sources](#hi2low) including non-prefixed, `ASPNETCORE_`-prefixed and `DOTNETCORE_`-prefixed environment variables. -* [`DOTNET_` environment variables](/dotnet/core/tools/dotnet-environment-variables) used outside of [Microsoft.Extensions.Hosting](xref:Microsoft.Extensions.Hosting). - -Using the [default](#default) configuration, the loads configuration from environment variable key-value pairs after reading `appsettings.json`, `appsettings.{Environment}.json`, and [user secrets](xref:security/app-secrets). Therefore, key values read from the environment override values read from `appsettings.json`, `appsettings.{Environment}.json`, and user secrets. - -[!INCLUDE[](~/includes/environmentVarableColon.md)] - -The following `set` commands: - -* Set the environment keys and values of the [preceding example](#appsettingsjson) on Windows. -* Test the settings when using the [sample download](https://github.com/dotnet/AspNetCore.Docs/tree/main/aspnetcore/fundamentals/configuration/index/samples/3.x/ConfigSample). The `dotnet run` command must be run in the project directory. - -```dotnetcli -set MyKey="My key from Environment" -set Position__Title=Environment_Editor -set Position__Name=Environment_Rick -dotnet run -``` - -The preceding environment settings: - -* Are only set in processes launched from the command window they were set in. -* Won't be read by browsers launched with Visual Studio. - -The following [setx](/windows-server/administration/windows-commands/setx) commands can be used to set the environment keys and values on Windows. Unlike `set`, `setx` settings are persisted. `/M` sets the variable in the system environment. If the `/M` switch isn't used, a user environment variable is set. - -```console -setx MyKey "My key from setx Environment" /M -setx Position__Title Environment_Editor /M -setx Position__Name Environment_Rick /M -``` - -To test that the preceding commands override `appsettings.json` and `appsettings.{Environment}.json`: - -* With Visual Studio: Exit and restart Visual Studio. -* With the CLI: Start a new command window and enter `dotnet run`. - -Call with a string to specify a prefix for environment variables: - -[!code-csharp[](~/fundamentals/configuration/index/samples/6.x/ConfigSample/Program.cs?name=snippet_env&highlight=5)] - -In the preceding code: - -* `builder.Configuration.AddEnvironmentVariables(prefix: "MyCustomPrefix_")` is added after the [default configuration providers](#default). For an example of ordering the configuration providers, see [JSON configuration provider](#jcp). -* Environment variables set with the `MyCustomPrefix_` prefix override the [default configuration providers](#default). This includes environment variables without the prefix. - -The prefix is stripped off when the configuration key-value pairs are read. - -The following commands test the custom prefix: - -```dotnetcli -set MyCustomPrefix_MyKey="My key with MyCustomPrefix_ Environment" -set MyCustomPrefix_Position__Title=Editor_with_customPrefix -set MyCustomPrefix_Position__Name=Environment_Rick_cp -dotnet run -``` - -The [default configuration](#default) loads environment variables and command line arguments prefixed with `DOTNET_` and `ASPNETCORE_`. The `DOTNET_` and `ASPNETCORE_` prefixes are used by ASP.NET Core for [host and app configuration](xref:fundamentals/host/generic-host#host-configuration), but not for user configuration. For more information on host and app configuration, see [.NET Generic Host](xref:fundamentals/host/generic-host). - -On [Azure App Service](https://azure.microsoft.com/services/app-service/), select **New application setting** on the **Settings > Configuration** page. Azure App Service application settings are: - -* Encrypted at rest and transmitted over an encrypted channel. -* Exposed as environment variables. - -For more information, see [Azure Apps: Override app configuration using the Azure Portal](xref:host-and-deploy/azure-apps/index#override-app-configuration-using-the-azure-portal). - -See [Connection string prefixes](#constr) for information on Azure database connection strings. - -### Naming of environment variables - -Environment variable names reflect the structure of an `appsettings.json` file. Each element in the hierarchy is separated by a double underscore (preferable) or a colon. When the element structure includes an array, the array index should be treated as an additional element name in this path. Consider the following `appsettings.json` file and its equivalent values represented as environment variables. - -*`appsettings.json`* - -```json -{ - "SmtpServer": "smtp.example.com", - "Logging": [ - { - "Name": "ToEmail", - "Level": "Critical", - "Args": { - "FromAddress": "MySystem@example.com", - "ToAddress": "SRE@example.com" - } - }, - { - "Name": "ToConsole", - "Level": "Information" - } - ] -} -``` - -**environment variables** - -```console -setx SmtpServer smtp.example.com -setx Logging__0__Name ToEmail -setx Logging__0__Level Critical -setx Logging__0__Args__FromAddress MySystem@example.com -setx Logging__0__Args__ToAddress SRE@example.com -setx Logging__1__Name ToConsole -setx Logging__1__Level Information -``` - -### Environment variables set in generated launchSettings.json - -Environment variables set in `launchSettings.json` override those set in the system environment. For example, the ASP.NET Core web templates generate a `launchSettings.json` file that sets the endpoint configuration to: - -```json -"applicationUrl": "https://localhost:5001;http://localhost:5000" -``` - -Configuring the `applicationUrl` sets the `ASPNETCORE_URLS` environment variable and overrides values set in the environment. - -### Escape environment variables on Linux - -On Linux, the value of URL environment variables must be escaped so `systemd` can parse it. Use the linux tool `systemd-escape` which yields `http:--localhost:5001` - - ```cmd - groot@terminus:~$ systemd-escape http://localhost:5001 - http:--localhost:5001 - ``` - -### Display environment variables - -The following code displays the environment variables and values on application startup, which can be helpful when debugging environment settings: - -```csharp -var builder = WebApplication.CreateBuilder(args); -var app = builder.Build(); - -foreach (var c in builder.Configuration.AsEnumerable()) -{ - Console.WriteLine(c.Key + " = " + c.Value); -} -``` - - - -## Command-line - -Using the [default](#default) configuration, the loads configuration from command-line argument key-value pairs after the following configuration sources: - -* `appsettings.json` and `appsettings.{Environment}.json` files. -* [App secrets](xref:security/app-secrets) in the Development environment. -* Environment variables. - -By [default](#default), configuration values set on the command-line override configuration values set with all the other configuration providers. - -### Command-line arguments - -The following command sets keys and values using `=`: - -```dotnetcli -dotnet run MyKey="Using =" Position:Title=Cmd Position:Name=Cmd_Rick -``` - -The following command sets keys and values using `/`: - -```dotnetcli -dotnet run /MyKey "Using /" /Position:Title=Cmd /Position:Name=Cmd_Rick -``` - -The following command sets keys and values using `--`: - -```dotnetcli -dotnet run --MyKey "Using --" --Position:Title=Cmd --Position:Name=Cmd_Rick -``` - -The key value: - -* Must follow `=`, or the key must have a prefix of `--` or `/` when the value follows a space. -* Isn't required if `=` is used. For example, `MySetting=`. - -Within the same command, don't mix command-line argument key-value pairs that use `=` with key-value pairs that use a space. - -### Switch mappings - -Switch mappings allow **key** name replacement logic. Provide a dictionary of switch replacements to the method. - -When the switch mappings dictionary is used, the dictionary is checked for a key that matches the key provided by a command-line argument. If the command-line key is found in the dictionary, the dictionary value is passed back to set the key-value pair into the app's configuration. A switch mapping is required for any command-line key prefixed with a single dash (`-`). - -Switch mappings dictionary key rules: - -* Switches must start with `-` or `--`. -* The switch mappings dictionary must not contain duplicate keys. - -To use a switch mappings dictionary, pass it into the call to `AddCommandLine`: - -[!code-csharp[](~/fundamentals/configuration/index/samples/6.x/ConfigSample/Program.cs?name=snippet_sw)] - -Run the following command works to test key replacement: - -```dotnetcli -dotnet run -k1 value1 -k2 value2 --alt3=value2 /alt4=value3 --alt5 value5 /alt6 value6 -``` - -The following code shows the key values for the replaced keys: - -[!code-csharp[](~/fundamentals/configuration/index/samples/6.x/ConfigSample/Pages/Test3.cshtml.cs?name=snippet)] - -For apps that use switch mappings, the call to `CreateDefaultBuilder` shouldn't pass arguments. The `CreateDefaultBuilder` method's `AddCommandLine` call doesn't include mapped switches, and there's no way to pass the switch-mapping dictionary to `CreateDefaultBuilder`. The solution isn't to pass the arguments to `CreateDefaultBuilder` but instead to allow the `ConfigurationBuilder` method's `AddCommandLine` method to process both the arguments and the switch-mapping dictionary. - -## Set environment and command-line arguments with Visual Studio - -Environment and command-line arguments can be set in Visual Studio from the launch profiles dialog: - -* In Solution Explorer, right click the project and select **Properties**. -* Select the **Debug > General** tab and select **Open debug launch profiles UI**. - -## Hierarchical configuration data - -The Configuration API reads hierarchical configuration data by flattening the hierarchical data with the use of a delimiter in the configuration keys. - -The [sample download](https://github.com/dotnet/AspNetCore.Docs/tree/main/aspnetcore/fundamentals/configuration/index/samples/6.x/ConfigSample) contains the following `appsettings.json` file: - -[!code-json[](~/fundamentals/configuration/index/samples/6.x/ConfigSample/appsettings.json)] - -The following code from the [sample download](https://github.com/dotnet/AspNetCore.Docs/tree/main/aspnetcore/fundamentals/configuration/index/samples/6.x/ConfigSample) displays several of the configurations settings: - -[!code-csharp[](~/fundamentals/configuration/index/samples/6.x/ConfigSample/Pages/Test.cshtml.cs?name=snippet)] - -The preferred way to read hierarchical configuration data is using the options pattern. For more information, see [Bind hierarchical configuration data](#optpat) in this document. - - and methods are available to isolate sections and children of a section in the configuration data. These methods are described later in [GetSection, GetChildren, and Exists](#getsection). - - - -## Configuration keys and values - -[!INCLUDE [managed-identities](~/includes/managed-identities-conn-strings.md)] - -Configuration keys: - -* Are case-insensitive. For example, `ConnectionString` and `connectionstring` are treated as equivalent keys. -* If a key and value is set in more than one configuration providers, the value from the last provider added is used. For more information, see [Default configuration](#default). -* Hierarchical keys - * Within the Configuration API, a colon separator (`:`) works on all platforms. - * In environment variables, a colon separator may not work on all platforms. A double underscore, `__`, is supported by all platforms and is automatically converted into a colon `:`. - * In Azure Key Vault, hierarchical keys use `--` as a separator. The [Azure Key Vault configuration provider](xref:security/key-vault-configuration) automatically replaces `--` with a `:` when the secrets are loaded into the app's configuration. -* The supports binding arrays to objects using array indices in configuration keys. Array binding is described in the [Bind an array to a class](#boa) section. - -Configuration values: - -* Are strings. -* Null values can't be stored in configuration or bound to objects. - - - -## Configuration providers - -The following table shows the configuration providers available to ASP.NET Core apps. - -| Provider | Provides configuration from | -| -------- | ----------------------------------- | -| [Azure Key Vault configuration provider](xref:security/key-vault-configuration) | Azure Key Vault | -| [Azure App configuration provider](/azure/azure-app-configuration/quickstart-aspnet-core-app) | Azure App Configuration | -| [Command-line configuration provider](#clcp) | Command-line parameters | -| [Custom configuration provider](#custom-configuration-provider) | Custom source | -| [Environment Variables configuration provider](#evcp) | Environment variables | -| [File configuration provider](#file-configuration-provider) | INI, JSON, and XML files | -| [Key-per-file configuration provider](#key-per-file-configuration-provider) | Directory files | -| [Memory configuration provider](#memory-configuration-provider) | In-memory collections | -| [User secrets](xref:security/app-secrets) | File in the user profile directory | - -Configuration sources are read in the order that their configuration providers are specified. Order configuration providers in code to suit the priorities for the underlying configuration sources that the app requires. - -A typical sequence of configuration providers is: - -1. `appsettings.json` -1. `appsettings.{Environment}.json` -1. [User secrets](xref:security/app-secrets) -1. Environment variables using the [Environment Variables configuration provider](#evcp). -1. Command-line arguments using the [Command-line configuration provider](#clcp). - -A common practice is to add the Command-line configuration provider last in a series of providers to allow command-line arguments to override configuration set by the other providers. - -The preceding sequence of providers is used in the [default configuration](#default). - - - -### Connection string prefixes - -[!INCLUDE [managed-identities](~/includes/managed-identities-conn-strings.md)] - -The Configuration API has special processing rules for four connection string environment variables. These connection strings are involved in configuring Azure connection strings for the app environment. Environment variables with the prefixes shown in the table are loaded into the app with the [default configuration](#default) or when no prefix is supplied to `AddEnvironmentVariables`. - -| Connection string prefix | Provider | -| ------------------------ | -------- | -| `CUSTOMCONNSTR_` | Custom provider | -| `MYSQLCONNSTR_` | [MySQL](https://www.mysql.com/) | -| `SQLAZURECONNSTR_` | [Azure SQL Database](https://azure.microsoft.com/services/sql-database/) | -| `SQLCONNSTR_` | [SQL Server](https://www.microsoft.com/sql-server/) | - -When an environment variable is discovered and loaded into configuration with any of the four prefixes shown in the table: - -* The configuration key is created by removing the environment variable prefix and adding a configuration key section (`ConnectionStrings`). -* A new configuration key-value pair is created that represents the database connection provider (except for `CUSTOMCONNSTR_`, which has no stated provider). - -| Environment variable key | Converted configuration key | Provider configuration entry | -|--|--|--| -| `CUSTOMCONNSTR_{KEY}` | `ConnectionStrings:{KEY}` | Configuration entry not created. | -| `MYSQLCONNSTR_{KEY}` | `ConnectionStrings:{KEY}` | Key: `ConnectionStrings:{KEY}_ProviderName`:
Value: `MySql.Data.MySqlClient` | -| `SQLAZURECONNSTR_{KEY}` | `ConnectionStrings:{KEY}` | Key: `ConnectionStrings:{KEY}_ProviderName`:
Value: `System.Data.SqlClient` | -| `SQLCONNSTR_{KEY}` | `ConnectionStrings:{KEY}` | Key: `ConnectionStrings:{KEY}_ProviderName`:
Value: `System.Data.SqlClient` | - - - -## File configuration provider - - is the base class for loading configuration from the file system. The following configuration providers derive from `FileConfigurationProvider`: - -* [INI configuration provider](#ini-configuration-provider) -* [JSON configuration provider](#jcp) -* [XML configuration provider](#xml-configuration-provider) - -### INI configuration provider - -The loads configuration from INI file key-value pairs at runtime. - -The following code adds several configuration providers: -[!code-csharp[](~/fundamentals/configuration/index/samples/6.x/ConfigSample/Program.cs?name=snippet_ini)] - -In the preceding code, settings in the `MyIniConfig.ini` and `MyIniConfig.{Environment}.ini` files are overridden by settings in the: - -* [Environment variables configuration provider](#evcp) -* [Command-line configuration provider](#clcp). - -The [sample download](https://github.com/dotnet/AspNetCore.Docs/tree/main/aspnetcore/fundamentals/configuration/index/samples/6.x/ConfigSample) contains the following `MyIniConfig.ini` file: - -[!code-ini[](~/fundamentals/configuration/index/samples/6.x/ConfigSample/MyIniConfig.ini)] - -The following code from the [sample download](https://github.com/dotnet/AspNetCore.Docs/tree/main/aspnetcore/fundamentals/configuration/index/samples/6.x/ConfigSample) displays several of the preceding configurations settings: - -[!code-csharp[](~/fundamentals/configuration/index/samples/3.x/ConfigSample/Pages/Test.cshtml.cs?name=snippet)] - - - -### JSON configuration provider - -The loads configuration from JSON file key-value pairs. - -Overloads can specify: - -* Whether the file is optional. -* Whether the configuration is reloaded if the file changes. - -Consider the following code: - -[!code-csharp[](~/fundamentals/configuration/index/samples/6.x/ConfigSample/Program.cs?name=snippet_json)] - -The preceding code: - -* Configures the JSON configuration provider to load the `MyConfig.json` file with the following options: - * `optional: true`: The file is optional. - * `reloadOnChange: true` : The file is reloaded when changes are saved. -* Reads the [default configuration providers](#default) before the `MyConfig.json` file. Settings in the `MyConfig.json` file override setting in the default configuration providers, including the [Environment variables configuration provider](#evcp) and the [Command-line configuration provider](#clcp). - -You typically ***don't*** want a custom JSON file overriding values set in the [Environment variables configuration provider](#evcp) and the [Command-line configuration provider](#clcp). - - -### XML configuration provider - -The loads configuration from XML file key-value pairs at runtime. - -The following code adds several configuration providers: - -[!code-csharp[](~/fundamentals/configuration/index/samples/6.x/ConfigSample/Program.cs?name=snippet_xml)] - -In the preceding code, settings in the `MyXMLFile.xml` and `MyXMLFile.{Environment}.xml` files are overridden by settings in the: - -* [Environment variables configuration provider](#evcp) -* [Command-line configuration provider](#clcp). - -The [sample download](https://github.com/dotnet/AspNetCore.Docs/tree/main/aspnetcore/fundamentals/configuration/index/samples/6.x/ConfigSample) contains the following `MyXMLFile.xml` file: - -[!code-xml[](~/fundamentals/configuration/index/samples/6.x/ConfigSample/MyXMLFile.xml)] - -The following code from the [sample download](https://github.com/dotnet/AspNetCore.Docs/tree/main/aspnetcore/fundamentals/configuration/index/samples/6.x/ConfigSample) displays several of the preceding configurations settings: - -[!code-csharp[](~/fundamentals/configuration/index/samples/6.x/ConfigSample/Pages/Test.cshtml.cs?name=snippet)] - -Repeating elements that use the same element name work if the `name` attribute is used to distinguish the elements: - -[!code-xml[](~/fundamentals/configuration/index/samples/6.x/ConfigSample/MyXMLFile3.xml)] - -The following code reads the previous configuration file and displays the keys and values: - -[!code-csharp[](~/fundamentals/configuration/index/samples/6.x/ConfigSample/Pages/XML/Index.cshtml.cs?name=snippet)] - -Attributes can be used to supply values: - -```xml - - - -
- -
-
-``` - -The previous configuration file loads the following keys with `value`: - -* key:attribute -* section:key:attribute - -## Key-per-file configuration provider - -The uses a directory's files as configuration key-value pairs. The key is the file name. The value contains the file's contents. The Key-per-file configuration provider is used in Docker hosting scenarios. - -To activate key-per-file configuration, call the extension method on an instance of . The `directoryPath` to the files must be an absolute path. - -Overloads permit specifying: - -* An `Action` delegate that configures the source. -* Whether the directory is optional and the path to the directory. - -The double-underscore (`__`) is used as a configuration key delimiter in file names. For example, the file name `Logging__LogLevel__System` produces the configuration key `Logging:LogLevel:System`. - -Call `ConfigureAppConfiguration` when building the host to specify the app's configuration: - -```csharp -.ConfigureAppConfiguration((hostingContext, config) => -{ - var path = Path.Combine( - Directory.GetCurrentDirectory(), "path/to/files"); - config.AddKeyPerFile(directoryPath: path, optional: true); -}) -``` - - - -## Memory configuration provider - -The uses an in-memory collection as configuration key-value pairs. - -The following code adds a memory collection to the configuration system: - -[!code-csharp[](~/fundamentals/configuration/index/samples/6.x/ConfigSample/Program.cs?name=snippet_mem)] - -The following code from the [sample download](https://github.com/dotnet/AspNetCore.Docs/tree/main/aspnetcore/fundamentals/configuration/index/samples/3.x/ConfigSample) displays the preceding configurations settings: - -[!code-csharp[](~/fundamentals/configuration/index/samples/3.x/ConfigSample/Pages/Test.cshtml.cs?name=snippet)] - -In the preceding code, `config.AddInMemoryCollection(Dict)` is added after the [default configuration providers](#default). For an example of ordering the configuration providers, see [JSON configuration provider](#jcp). - -See [Bind an array](#boa) for another example using `MemoryConfigurationProvider`. - - - -## Kestrel endpoint configuration - -Kestrel specific endpoint configuration overrides all [cross-server](xref:fundamentals/servers/index) endpoint configurations. Cross-server endpoint configurations include: - -* [UseUrls](xref:fundamentals/host/web-host#server-urls) -* `--urls` on the [command line](xref:fundamentals/configuration/index#command-line) -* The [environment variable](xref:fundamentals/configuration/index#environment-variables) `ASPNETCORE_URLS` - -Consider the following `appsettings.json` file used in an ASP.NET Core web app: - -[!code-json[](~/fundamentals/configuration/index/samples_snippets/5.x/appsettings.json?highlight=2-8)] - -When the preceding highlighted markup is used in an ASP.NET Core web app ***and*** the app is launched on the command line with the following cross-server endpoint configuration: - -`dotnet run --urls="https://localhost:7777"` - -Kestrel binds to the endpoint configured specifically for Kestrel in the `appsettings.json` file (`https://localhost:9999`) and not `https://localhost:7777`. - -Consider the Kestrel specific endpoint configured as an environment variable: - -`set Kestrel__Endpoints__Https__Url=https://localhost:8888` - -In the preceding environment variable, `Https` is the name of the Kestrel specific endpoint. The preceding `appsettings.json` file also defines a Kestrel specific endpoint named `Https`. By [default](#default-host-configuration), environment variables using the [Environment Variables configuration provider](#evcp) are read after `appsettings.{Environment}.json`, therefore, the preceding environment variable is used for the `Https` endpoint. - -## GetValue - - extracts a single value from configuration with a specified key and converts it to the specified type: - -[!code-csharp[](~/fundamentals/configuration/index/samples/6.x/ConfigSample/Pages/TestNum.cshtml.cs?name=snippet)] - -In the preceding code, if `NumberKey` isn't found in the configuration, the default value of `99` is used. - -## GetSection, GetChildren, and Exists - -For the examples that follow, consider the following `MySubsection.json` file: - -[!code-json[](~/fundamentals/configuration/index/samples/6.x/ConfigSample/MySubsection.json)] - -The following code adds `MySubsection.json` to the configuration providers: - -[!code-csharp[](~/fundamentals/configuration/index/samples/6.x/ConfigSample/Program.cs?name=snippet_sub)] - -### GetSection - - returns a configuration subsection with the specified subsection key. - -The following code returns values for `section1`: - -[!code-csharp[](~/fundamentals/configuration/index/samples/6.x/ConfigSample/Pages/TestSection.cshtml.cs?name=snippet)] - -The following code returns values for `section2:subsection0`: - -[!code-csharp[](~/fundamentals/configuration/index/samples/6.x/ConfigSample/Pages/TestSection2.cshtml.cs?name=snippet)] - -`GetSection` never returns `null`. If a matching section isn't found, an empty `IConfigurationSection` is returned. - -When `GetSection` returns a matching section, isn't populated. A and are returned when the section exists. - -### GetChildren and Exists - -The following code calls and returns values for `section2:subsection0`: - -[!code-csharp[](~/fundamentals/configuration/index/samples/6.x/ConfigSample/Pages/TestSection4.cshtml.cs?name=snippet)] - -The preceding code calls to verify the section exists: - - - -## Bind an array - -The supports binding arrays to objects using array indices in configuration keys. Any array format that exposes a numeric key segment is capable of array binding to a [POCO](https://wikipedia.org/wiki/Plain_Old_CLR_Object) class array. - -Consider `MyArray.json` from the [sample download](https://github.com/dotnet/AspNetCore.Docs/tree/main/aspnetcore/fundamentals/configuration/index/samples/6.x/ConfigSample): - -[!code-json[](~/fundamentals/configuration/index/samples/6.x/ConfigSample/MyArray.json)] - -The following code adds `MyArray.json` to the configuration providers: - -[!code-csharp[](~/fundamentals/configuration/index/samples/6.x/ConfigSample/Program.cs?name=snippet_ba)] - -The following code reads the configuration and displays the values: - -[!code-csharp[](~/fundamentals/configuration/index/samples/6.x/ConfigSample/Pages/Array.cshtml.cs?name=snippet)] - -[!code-csharp[](~/fundamentals/configuration/index/samples/6.x/ConfigSample/Options/ArrayExample.cs?name=snippet)] - -The preceding code returns the following output: - -```text -Index: 0 Value: value00 -Index: 1 Value: value10 -Index: 2 Value: value20 -Index: 3 Value: value40 -Index: 4 Value: value50 -``` - -In the preceding output, Index 3 has value `value40`, corresponding to `"4": "value40",` in `MyArray.json`. The bound array indices are continuous and not bound to the configuration key index. The configuration binder isn't capable of binding null values or creating null entries in bound objects. - - -## Custom configuration provider - -The sample app demonstrates how to create a basic configuration provider that reads configuration key-value pairs from a database using [Entity Framework (EF)](/ef/core/). - -The provider has the following characteristics: - -* The EF in-memory database is used for demonstration purposes. To use a database that requires a connection string, implement a secondary `ConfigurationBuilder` to supply the connection string from another configuration provider. -* The provider reads a database table into configuration at startup. The provider doesn't query the database on a per-key basis. -* Reload-on-change isn't implemented, so updating the database after the app starts has no effect on the app's configuration. - -Define an `EFConfigurationValue` entity for storing configuration values in the database. - -`Models/EFConfigurationValue.cs`: - -[!code-csharp[](~/fundamentals/configuration/index/samples/6.x/EfconfigSample/Models/EFConfigurationValue.cs?name=snippet1)] - -Add an `EFConfigurationContext` to store and access the configured values. - -`EFConfigurationProvider/EFConfigurationContext.cs`: - -[!code-csharp[](~/fundamentals/configuration/index/samples/6.x/EfconfigSample/EFConfigurationProvider/EFConfigurationContext.cs?name=snippet1)] - -Create a class that implements . - -`EFConfigurationProvider/EFConfigurationSource.cs`: - -[!code-csharp[](~/fundamentals/configuration/index/samples/6.x/EfconfigSample/EFConfigurationProvider/EFConfigurationSource.cs?name=snippet1)] - -Create the custom configuration provider by inheriting from . The configuration provider initializes the database when it's empty. Since configuration keys are case-insensitive, the dictionary used to initialize the database is created with the case-insensitive comparer ([StringComparer.OrdinalIgnoreCase](xref:System.StringComparer.OrdinalIgnoreCase)). - -`EFConfigurationProvider/EFConfigurationProvider.cs`: - -[!code-csharp[](~/fundamentals/configuration/index/samples/6.x/EfconfigSample/EFConfigurationProvider/EFConfigurationProvider.cs?name=snippet1)] - -An `AddEFConfiguration` extension method permits adding the configuration source to a `ConfigurationBuilder`. - -`Extensions/EntityFrameworkExtensions.cs`: - -[!code-csharp[](~/fundamentals/configuration/index/samples/6.x/EfconfigSample/Extensions/EntityFrameworkExtensions.cs?name=snippet1)] - -The following code shows how to use the custom `EFConfigurationProvider` in `Program.cs`: - -[!code-csharp[](~/fundamentals/configuration/index/samples_snippets/6.x/EfconfigSample/Program.cs?highlight=5-6)] - -## Access configuration with Dependency Injection (DI) - -Configuration can be injected into services using [Dependency Injection (DI)](xref:fundamentals/dependency-injection) by resolving the service: - -[!code-csharp[](~/fundamentals/configuration/index/samples/6.x/ConfigSample/Service.cs?name=snippet_Class&highlight=5-6)] - -For information on how to access values using `IConfiguration`, see [GetValue](#getvalue) and [GetSection, GetChildren, and Exists](#getsection-getchildren-and-exists) in this article. - -## Access configuration in Razor Pages - -The following code displays configuration data in a Razor Page: - -[!code-cshtml[](~/fundamentals/configuration/index/samples/6.x/ConfigSample/Pages/Test5.cshtml)] - -In the following code, `MyOptions` is added to the service container with and bound to configuration: - -[!code-csharp[](~/fundamentals/configuration/options/samples/6.x/OptionsSample/Program.cs?name=snippet)] - -The following markup uses the [`@inject`](xref:mvc/views/razor#inject) Razor directive to resolve and display the options values: - -[!code-cshtml[](~/fundamentals/configuration/options/samples/6.x/OptionsSample/Pages/Test3.cshtml)] - -## Access configuration in a MVC view file - -The following code displays configuration data in a MVC view: - -[!code-cshtml[](~/fundamentals/configuration/index/samples/3.x/ConfigSample/Views/Home2/Index.cshtml)] - -## Access configuration in `Program.cs` - -The following code accesses configuration in the `Program.cs` file. - -```csharp -var builder = WebApplication.CreateBuilder(args); - -var key1 = builder.Configuration.GetValue("KeyOne"); - -var app = builder.Build(); - -app.MapGet("/", () => "Hello World!"); - -var key2 = app.Configuration.GetValue("KeyTwo"); -var key3 = app.Configuration.GetValue("KeyThree"); - -app.Logger.LogInformation("KeyOne: {KeyOne}", key1); -app.Logger.LogInformation("KeyTwo: {KeyTwo}", key2); -app.Logger.LogInformation("KeyThree: {KeyThree}", key3); - -app.Run(); -``` - -In `appsettings.json` for the preceding example: - -```json -{ - ... - "KeyOne": "Key One Value", - "KeyTwo": 1999, - "KeyThree": true -} -``` - -## Configure options with a delegate - -Options configured in a delegate override values set in the configuration providers. - -In the following code, an service is added to the service container. It uses a delegate to configure values for `MyOptions`: - -[!code-csharp[](~/fundamentals/configuration/options/samples/6.x/OptionsSample/Program.cs?name=snippet_del)] - -The following code displays the options values: - -[!code-csharp[](~/fundamentals/configuration/options/samples/6.x/OptionsSample/Pages/Test2.cshtml.cs?name=snippet)] - -In the preceding example, the values of `Option1` and `Option2` are specified in `appsettings.json` and then overridden by the configured delegate. - - - -## Host versus app configuration - -Before the app is configured and started, a *host* is configured and launched. The host is responsible for app startup and lifetime management. Both the app and the host are configured using the configuration providers described in this topic. Host configuration key-value pairs are also included in the app's configuration. For more information on how the configuration providers are used when the host is built and how configuration sources affect host configuration, see . - - - -## Default host configuration - -For details on the default configuration when using the [Web Host](xref:fundamentals/host/web-host), see the [ASP.NET Core 2.2 version of this topic](?view=aspnetcore-2.2&preserve-view=true). - -* Host configuration is provided from: - * Environment variables prefixed with `DOTNET_` (for example, `DOTNET_ENVIRONMENT`) using the [Environment Variables configuration provider](#evcp). The prefix (`DOTNET_`) is stripped when the configuration key-value pairs are loaded. - * Command-line arguments using the [Command-line configuration provider](#clcp). -* Web Host default configuration is established (`ConfigureWebHostDefaults`): - * Kestrel is used as the web server and configured using the app's configuration providers. - * Add Host Filtering Middleware. - * Add Forwarded Headers Middleware if the `ASPNETCORE_FORWARDEDHEADERS_ENABLED` environment variable is set to `true`. - * Enable IIS integration. - -## Other configuration - -This topic only pertains to *app configuration*. Other aspects of running and hosting ASP.NET Core apps are configured using configuration files not covered in this topic: - -* `launch.json`/`launchSettings.json` are tooling configuration files for the Development environment, described: - * In . - * Across the documentation set where the files are used to configure ASP.NET Core apps for Development scenarios. -* `web.config` is a server configuration file, described in the following topics: - * - * - -Environment variables set in `launchSettings.json` override those set in the system environment. - -For more information on migrating app configuration from earlier versions of ASP.NET, see . - -## Add configuration from an external assembly - -An implementation allows adding enhancements to an app at startup from an external assembly outside of the app's `Startup` class. For more information, see . - -## Additional resources - -* [Configuration source code](https://github.com/dotnet/runtime/tree/main/src/libraries/Microsoft.Extensions.Configuration) -* [View or download sample code](https://github.com/dotnet/AspNetCore.Docs/tree/main/aspnetcore/fundamentals/configuration/index/samples) ([how to download](xref:fundamentals/index#how-to-download-a-sample)) -* -* - -:::moniker-end diff --git a/aspnetcore/fundamentals/configuration/index/includes/index7.md b/aspnetcore/fundamentals/configuration/index/includes/index7.md deleted file mode 100644 index 61b295901d10..000000000000 --- a/aspnetcore/fundamentals/configuration/index/includes/index7.md +++ /dev/null @@ -1,944 +0,0 @@ -:::moniker range="= aspnetcore-7.0" - -Application configuration in ASP.NET Core is performed using one or more [configuration providers](#cp). 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 Configuration -* Command-line arguments -* Custom providers, installed or created -* Directory files -* In-memory .NET objects - -This article provides information on configuration in ASP.NET Core. For information on using configuration in console apps, see [.NET Configuration](/dotnet/core/extensions/configuration). - -## Application and Host Configuration - -ASP.NET Core apps configure and launch a *host*. The host is responsible for app startup and lifetime management. The ASP.NET Core templates create a which contains the host. While some configuration can be done in both the host and the application configuration providers, generally, only configuration that is necessary for the host should be done in host configuration. - -Application configuration is the highest priority and is detailed in the next section. [Host configuration](#host) follows application configuration, and is described in this article. - - - -### Default application configuration sources - -ASP.NET Core web apps created with [dotnet new](/dotnet/core/tools/dotnet-new) or Visual Studio generate the following code: - -```csharp -var builder = WebApplication.CreateBuilder(args); -``` - - - -[WebApplication.CreateBuilder](xref:Microsoft.AspNetCore.Builder.WebApplication.CreateBuilder%2A) initializes a new instance of the class with preconfigured defaults. The initialized `WebApplicationBuilder` (`builder`) provides default configuration for the app in the following order, from highest to lowest priority: - -1. Command-line arguments using the [Command-line configuration provider](#command-line). -1. Non-prefixed environment variables using the [Non-prefixed environment variables configuration provider](#evcp). -1. [User secrets](xref:security/app-secrets) when the app runs in the `Development` environment. -1. `appsettings.{Environment}.json` using the [JSON configuration provider](#jcp). For example, `appsettings.Production.json` and `appsettings.Development.json`. -1. [appsettings.json](#appsettingsjson) using the [JSON configuration provider](#jcp). -1. A fallback to the host configuration described in the [next section](#host). - - - -### Default host configuration sources - -The following list contains the default host configuration sources from highest to lowest priority for : - -1. Command-line arguments using the [Command-line configuration provider](#command-line) -1. `DOTNET_`-prefixed environment variables using the [Environment variables configuration provider](xref:Microsoft.Extensions.Configuration.EnvironmentVariables.EnvironmentVariablesConfigurationProvider). -1. `ASPNETCORE_`-prefixed environment variables using the [Environment variables configuration provider](xref:Microsoft.Extensions.Configuration.EnvironmentVariables.EnvironmentVariablesConfigurationProvider). - -For the [.NET Generic Host](xref:fundamentals/host/generic-host) and [Web Host](xref:fundamentals/host/web-host), the default host configuration sources from highest to lowest priority is: - -1. `ASPNETCORE_`-prefixed environment variables using the [Environment variables configuration provider](xref:Microsoft.Extensions.Configuration.EnvironmentVariables.EnvironmentVariablesConfigurationProvider). -1. Command-line arguments using the [Command-line configuration provider](#command-line) -1. `DOTNET_`-prefixed environment variables using the [Environment variables configuration provider](xref:Microsoft.Extensions.Configuration.EnvironmentVariables.EnvironmentVariablesConfigurationProvider). - -When a configuration value is set in host and application configuration, the application configuration is used. - -### Host variables - -The following variables are locked in early when initializing the host builders and can't be influenced by application config: - -* [Application name](xref:fundamentals/minimal-apis#change-the-content-root-application-name-and-environment) -* [Environment name](xref:fundamentals/environments), for example `Development`, `Production`, and `Staging` -* [Content root](xref:fundamentals/index#content-root) -* [Web root](xref:fundamentals/index#web-root) -* Whether to scan for [hosting startup assemblies](xref:fundamentals/configuration/platform-specific-configuration) and which assemblies to scan for. -* Variables read by app and library code from [HostBuilderContext.Configuration](xref:Microsoft.Extensions.Hosting.HostBuilderContext.Configuration) in [IHostBuilder.ConfigureAppConfiguration](xref:Microsoft.Extensions.Hosting.IHostBuilder.ConfigureAppConfiguration%2A) callbacks. - -Every other host setting is read from application config instead of host config. - -`URLS` is one of the many common host settings that is not a bootstrap setting. Like every other host setting not in the previous list, `URLS` is read later from application config. Host config is a fallback for application config, so host config can be used to set `URLS`, but it will be overridden by any configuration source in application config like `appsettings.json`. - -For more information, see [Change the content root, app name, and environment](xref:migration/50-to-60-samples#change-the-content-root-app-name-and-environment) and [Change the content root, app name, and environment by environment variables or command line](xref:migration/50-to-60-samples#change-the-content-root-app-name-and-environment-by-environment-variables-or-command-line) - -The remaining sections in this article refer to application configuration. - -## Application configuration providers - -The following code displays the enabled configuration providers in the order they were added: - -[!code-csharp[](~/fundamentals/configuration/index/samples/6.x/ConfigSample/Pages/Index2.cshtml.cs?name=snippet)] - -The preceding [list of highest to lowest priority default configuration sources](#hi2low) shows the providers in the opposite order they are added to template generated application. For example, the [JSON configuration provider](#jcp) is added before the [Command-line configuration provider](#command-line). - -Configuration providers that are added later have higher priority and override previous key settings. For example, if `MyKey` is set in both `appsettings.json` and the environment, the environment value is used. Using the default configuration providers, the [Command-line configuration provider](#clcp) overrides all other providers. - -For more information on `CreateBuilder`, see [Default builder settings](xref:fundamentals/host/generic-host#default-builder-settings). - -### `appsettings.json` - -Consider the following `appsettings.json` file: - -[!code-json[](~/fundamentals/configuration/index/samples/6.x/ConfigSample/appsettings.json)] - -The following code from the [sample download](https://github.com/dotnet/AspNetCore.Docs/tree/main/aspnetcore/fundamentals/configuration/index/samples/6.x/ConfigSample) displays several of the preceding configurations settings: - -[!code-csharp[](~/fundamentals/configuration/index/samples/6.x/ConfigSample/Pages/Test.cshtml.cs?name=snippet)] - -The default loads configuration in the following order: - -1. `appsettings.json` -1. `appsettings.{Environment}.json` : For example, the `appsettings.Production.json` and `appsettings.Development.json` files. The environment version of the file is loaded based on the . For more information, see . - -`appsettings.{Environment}.json` values override keys in `appsettings.json`. For example, by default: - -* In development, `appsettings.Development.json` configuration overwrites values found in `appsettings.json`. -* In production, `appsettings.Production.json` configuration overwrites values found in `appsettings.json`. For example, when deploying the app to Azure. - -If a configuration value must be guaranteed, see [GetValue](#getvalue). The preceding example only reads strings and doesn’t support a default value. - -Using the [default](#default) configuration, the `appsettings.json` and `appsettings.{Environment}.json` files are enabled with [reloadOnChange: true](https://github.com/dotnet/extensions/blob/release/3.1/src/Hosting/Hosting/src/Host.cs#L74-L75). Changes made to the `appsettings.json` and `appsettings.{Environment}.json` file ***after*** the app starts are read by the [JSON configuration provider](#jcp). - -### Comments in appsettings.json - -Comments in `appsettings.json` and `appsettings.{Environment}.json`files are supported using JavaScript or [C# style comments](/dotnet/csharp/language-reference/tokens/comments). - - - -### Bind hierarchical configuration data using the options pattern - -[!INCLUDE[](~/includes/bind6.md)] - -Using the [default](#default) configuration, the `appsettings.json` and `appsettings.{Environment}.json` files are enabled with [reloadOnChange: true](https://github.com/dotnet/extensions/blob/release/3.1/src/Hosting/Hosting/src/Host.cs#L74-L75). Changes made to the `appsettings.json` and `appsettings.{Environment}.json` file ***after*** the app starts are read by the [JSON configuration provider](#jcp). - -See [JSON configuration provider](#jcp) in this document for information on adding additional JSON configuration files. - -## Combining service collection - -[!INCLUDE[](~/includes/combine-di6.md)] - - - -## Security and user secrets - -Configuration data guidelines: - -* Never store passwords or other sensitive data in configuration provider code or in plain text configuration files. The [Secret Manager](xref:security/app-secrets) tool can be used to store secrets in development. -* Don't use production secrets in development or test environments. -* Specify secrets outside of the project so that they can't be accidentally committed to a source code repository. -* Production apps should use the most secure authentication flow available. For more information, see [Secure authentication flows](xref:security/index#secure-authentication-flows). - -By [default](#default), the user secrets configuration source is registered after the JSON configuration sources. Therefore, user secrets keys take precedence over keys in `appsettings.json` and `appsettings.{Environment}.json`. - -For more information on storing passwords or other sensitive data: - -* -* : Includes advice on using environment variables to store sensitive data. The Secret Manager tool uses the [File configuration provider](#fcp) to store user secrets in a JSON file on the local system. - -[Azure Key Vault](https://azure.microsoft.com/services/key-vault/) safely stores app secrets for ASP.NET Core apps. For more information, see . - - - -## Non-prefixed environment variables - -Non-prefixed environment variables are environment variables other than those prefixed by `ASPNETCORE_` or `DOTNET_`. For example, the ASP.NET Core web application templates set `"ASPNETCORE_ENVIRONMENT": "Development"` in `launchSettings.json`. For more information on `ASPNETCORE_` and `DOTNET_` environment variables, see: - -* [List of highest to lowest priority default configuration sources](#hi2low) including non-prefixed, `ASPNETCORE_`-prefixed and `DOTNETCORE_`-prefixed environment variables. -* [`DOTNET_` environment variables](/dotnet/core/tools/dotnet-environment-variables) used outside of [Microsoft.Extensions.Hosting](xref:Microsoft.Extensions.Hosting). - -Using the [default](#default) configuration, the loads configuration from environment variable key-value pairs after reading `appsettings.json`, `appsettings.{Environment}.json`, and [user secrets](xref:security/app-secrets). Therefore, key values read from the environment override values read from `appsettings.json`, `appsettings.{Environment}.json`, and user secrets. - -[!INCLUDE[](~/includes/environmentVarableColon.md)] - -The following `set` commands: - -* Set the environment keys and values of the [preceding example](#appsettingsjson) on Windows. -* Test the settings when using the [sample download](https://github.com/dotnet/AspNetCore.Docs/tree/main/aspnetcore/fundamentals/configuration/index/samples/3.x/ConfigSample). The `dotnet run` command must be run in the project directory. - -```dotnetcli -set MyKey="My key from Environment" -set Position__Title=Environment_Editor -set Position__Name=Environment_Rick -dotnet run -``` - -The preceding environment settings: - -* Are only set in processes launched from the command window they were set in. -* Won't be read by browsers launched with Visual Studio. - -The following [setx](/windows-server/administration/windows-commands/setx) commands can be used to set the environment keys and values on Windows. Unlike `set`, `setx` settings are persisted. `/M` sets the variable in the system environment. If the `/M` switch isn't used, a user environment variable is set. - -```console -setx MyKey "My key from setx Environment" /M -setx Position__Title Environment_Editor /M -setx Position__Name Environment_Rick /M -``` - -To test that the preceding commands override `appsettings.json` and `appsettings.{Environment}.json`: - -* With Visual Studio: Exit and restart Visual Studio. -* With the CLI: Start a new command window and enter `dotnet run`. - -Call with a string to specify a prefix for environment variables: - -[!code-csharp[](~/fundamentals/configuration/index/samples/6.x/ConfigSample/Program.cs?name=snippet_env&highlight=5)] - -In the preceding code: - -* `builder.Configuration.AddEnvironmentVariables(prefix: "MyCustomPrefix_")` is added after the [default configuration providers](#default). For an example of ordering the configuration providers, see [JSON configuration provider](#jcp). -* Environment variables set with the `MyCustomPrefix_` prefix override the [default configuration providers](#default). This includes environment variables without the prefix. - -The prefix is stripped off when the configuration key-value pairs are read. - -The following commands test the custom prefix: - -```dotnetcli -set MyCustomPrefix_MyKey="My key with MyCustomPrefix_ Environment" -set MyCustomPrefix_Position__Title=Editor_with_customPrefix -set MyCustomPrefix_Position__Name=Environment_Rick_cp -dotnet run -``` - -The [default configuration](#default) loads environment variables and command line arguments prefixed with `DOTNET_` and `ASPNETCORE_`. The `DOTNET_` and `ASPNETCORE_` prefixes are used by ASP.NET Core for [host and app configuration](xref:fundamentals/host/generic-host#host-configuration), but not for user configuration. For more information on host and app configuration, see [.NET Generic Host](xref:fundamentals/host/generic-host). - -On [Azure App Service](https://azure.microsoft.com/services/app-service/), select **New application setting** on the **Settings > Configuration** page. Azure App Service application settings are: - -* Encrypted at rest and transmitted over an encrypted channel. -* Exposed as environment variables. - -For more information, see [Azure Apps: Override app configuration using the Azure Portal](xref:host-and-deploy/azure-apps/index#override-app-configuration-using-the-azure-portal). - -See [Connection string prefixes](#constr) for information on Azure database connection strings. - -### Naming of environment variables - -Environment variable names reflect the structure of an `appsettings.json` file. Each element in the hierarchy is separated by a double underscore (preferable) or a colon. When the element structure includes an array, the array index should be treated as an additional element name in this path. Consider the following `appsettings.json` file and its equivalent values represented as environment variables. - -*`appsettings.json`* - -```json -{ - "SmtpServer": "smtp.example.com", - "Logging": [ - { - "Name": "ToEmail", - "Level": "Critical", - "Args": { - "FromAddress": "MySystem@example.com", - "ToAddress": "SRE@example.com" - } - }, - { - "Name": "ToConsole", - "Level": "Information" - } - ] -} -``` - -**environment variables** - -```console -setx SmtpServer smtp.example.com -setx Logging__0__Name ToEmail -setx Logging__0__Level Critical -setx Logging__0__Args__FromAddress MySystem@example.com -setx Logging__0__Args__ToAddress SRE@example.com -setx Logging__1__Name ToConsole -setx Logging__1__Level Information -``` - -### Environment variables set in generated launchSettings.json - -Environment variables set in `launchSettings.json` override those set in the system environment. For example, the ASP.NET Core web templates generate a `launchSettings.json` file that sets the endpoint configuration to: - -```json -"applicationUrl": "https://localhost:5001;http://localhost:5000" -``` - -Configuring the `applicationUrl` sets the `ASPNETCORE_URLS` environment variable and overrides values set in the environment. - -### Escape environment variables on Linux - -On Linux, the value of URL environment variables must be escaped so `systemd` can parse it. Use the linux tool `systemd-escape` which yields `http:--localhost:5001` - - ```cmd - groot@terminus:~$ systemd-escape http://localhost:5001 - http:--localhost:5001 - ``` - -### Display environment variables - -The following code displays the environment variables and values on application startup, which can be helpful when debugging environment settings: - -```csharp -var builder = WebApplication.CreateBuilder(args); -var app = builder.Build(); - -foreach (var c in builder.Configuration.AsEnumerable()) -{ - Console.WriteLine(c.Key + " = " + c.Value); -} -``` - - - -## Command-line - -Using the [default](#default) configuration, the loads configuration from command-line argument key-value pairs after the following configuration sources: - -* `appsettings.json` and `appsettings.{Environment}.json` files. -* [App secrets](xref:security/app-secrets) in the Development environment. -* Environment variables. - -By [default](#default), configuration values set on the command-line override configuration values set with all the other configuration providers. - -### Command-line arguments - -The following command sets keys and values using `=`: - -```dotnetcli -dotnet run MyKey="Using =" Position:Title=Cmd Position:Name=Cmd_Rick -``` - -The following command sets keys and values using `/`: - -```dotnetcli -dotnet run /MyKey "Using /" /Position:Title=Cmd /Position:Name=Cmd_Rick -``` - -The following command sets keys and values using `--`: - -```dotnetcli -dotnet run --MyKey "Using --" --Position:Title=Cmd --Position:Name=Cmd_Rick -``` - -The key value: - -* Must follow `=`, or the key must have a prefix of `--` or `/` when the value follows a space. -* Isn't required if `=` is used. For example, `MySetting=`. - -Within the same command, don't mix command-line argument key-value pairs that use `=` with key-value pairs that use a space. - -### Switch mappings - -Switch mappings allow **key** name replacement logic. Provide a dictionary of switch replacements to the method. - -When the switch mappings dictionary is used, the dictionary is checked for a key that matches the key provided by a command-line argument. If the command-line key is found in the dictionary, the dictionary value is passed back to set the key-value pair into the app's configuration. A switch mapping is required for any command-line key prefixed with a single dash (`-`). - -Switch mappings dictionary key rules: - -* Switches must start with `-` or `--`. -* The switch mappings dictionary must not contain duplicate keys. - -To use a switch mappings dictionary, pass it into the call to `AddCommandLine`: - -[!code-csharp[](~/fundamentals/configuration/index/samples/6.x/ConfigSample/Program.cs?name=snippet_sw)] - -Run the following command works to test key replacement: - -```dotnetcli -dotnet run -k1 value1 -k2 value2 --alt3=value2 /alt4=value3 --alt5 value5 /alt6 value6 -``` - -The following code shows the key values for the replaced keys: - -[!code-csharp[](~/fundamentals/configuration/index/samples/6.x/ConfigSample/Pages/Test3.cshtml.cs?name=snippet)] - -For apps that use switch mappings, the call to `CreateDefaultBuilder` shouldn't pass arguments. The `CreateDefaultBuilder` method's `AddCommandLine` call doesn't include mapped switches, and there's no way to pass the switch-mapping dictionary to `CreateDefaultBuilder`. The solution isn't to pass the arguments to `CreateDefaultBuilder` but instead to allow the `ConfigurationBuilder` method's `AddCommandLine` method to process both the arguments and the switch-mapping dictionary. - -## Set environment and command-line arguments with Visual Studio - -Environment and command-line arguments can be set in Visual Studio from the launch profiles dialog: - -* In Solution Explorer, right click the project and select **Properties**. -* Select the **Debug > General** tab and select **Open debug launch profiles UI**. - -## Hierarchical configuration data - -The Configuration API reads hierarchical configuration data by flattening the hierarchical data with the use of a delimiter in the configuration keys. - -The [sample download](https://github.com/dotnet/AspNetCore.Docs/tree/main/aspnetcore/fundamentals/configuration/index/samples/6.x/ConfigSample) contains the following `appsettings.json` file: - -[!code-json[](~/fundamentals/configuration/index/samples/6.x/ConfigSample/appsettings.json)] - -The following code from the [sample download](https://github.com/dotnet/AspNetCore.Docs/tree/main/aspnetcore/fundamentals/configuration/index/samples/6.x/ConfigSample) displays several of the configurations settings: - -[!code-csharp[](~/fundamentals/configuration/index/samples/6.x/ConfigSample/Pages/Test.cshtml.cs?name=snippet)] - -The preferred way to read hierarchical configuration data is using the options pattern. For more information, see [Bind hierarchical configuration data](#optpat) in this document. - - and methods are available to isolate sections and children of a section in the configuration data. These methods are described later in [GetSection, GetChildren, and Exists](#getsection). - - - -## Configuration keys and values - -[!INCLUDE [managed-identities](~/includes/managed-identities-conn-strings.md)] - -Configuration keys: - -* Are case-insensitive. For example, `ConnectionString` and `connectionstring` are treated as equivalent keys. -* If a key and value is set in more than one configuration provider, the value from the last provider added is used. For more information, see [Default configuration](#default). -* Hierarchical keys - * Within the Configuration API, a colon separator (`:`) works on all platforms. - * In environment variables, a colon separator may not work on all platforms. A double underscore, `__`, is supported by all platforms and is automatically converted into a colon `:`. - * In Azure Key Vault, hierarchical keys use `--` as a separator. The [Azure Key Vault configuration provider](xref:security/key-vault-configuration) automatically replaces `--` with a `:` when the secrets are loaded into the app's configuration. -* The supports binding arrays to objects using array indices in configuration keys. Array binding is described in the [Bind an array to a class](#boa) section. - -Configuration values: - -* Are strings. -* Null values can't be stored in configuration or bound to objects. - - - -## Configuration providers - -The following table shows the configuration providers available to ASP.NET Core apps. - -| Provider | Provides configuration from | -| -------- | ----------------------------------- | -| [Azure Key Vault configuration provider](xref:security/key-vault-configuration) | Azure Key Vault | -| [Azure App configuration provider](/azure/azure-app-configuration/quickstart-aspnet-core-app) | Azure App Configuration | -| [Command-line configuration provider](#clcp) | Command-line parameters | -| [Custom configuration provider](#custom-configuration-provider) | Custom source | -| [Environment Variables configuration provider](#evcp) | Environment variables | -| [File configuration provider](#file-configuration-provider) | INI, JSON, and XML files | -| [Key-per-file configuration provider](#key-per-file-configuration-provider) | Directory files | -| [Memory configuration provider](#memory-configuration-provider) | In-memory collections | -| [User secrets](xref:security/app-secrets) | File in the user profile directory | - -Configuration sources are read in the order that their configuration providers are specified. Order configuration providers in code to suit the priorities for the underlying configuration sources that the app requires. - -A typical sequence of configuration providers is: - -1. `appsettings.json` -1. `appsettings.{Environment}.json` -1. [User secrets](xref:security/app-secrets) -1. Environment variables using the [Environment Variables configuration provider](#evcp). -1. Command-line arguments using the [Command-line configuration provider](#clcp). - -A common practice is to add the Command-line configuration provider last in a series of providers to allow command-line arguments to override configuration set by the other providers. - -The preceding sequence of providers is used in the [default configuration](#default). - - - -### Connection string prefixes - -[!INCLUDE [managed-identities](~/includes/managed-identities-conn-strings.md)] - -The Configuration API has special processing rules for four connection string environment variables. These connection strings are involved in configuring Azure connection strings for the app environment. Environment variables with the prefixes shown in the table are loaded into the app with the [default configuration](#default) or when no prefix is supplied to `AddEnvironmentVariables`. - -| Connection string prefix | Provider | -| ------------------------ | -------- | -| `CUSTOMCONNSTR_` | Custom provider | -| `MYSQLCONNSTR_` | [MySQL](https://www.mysql.com/) | -| `SQLAZURECONNSTR_` | [Azure SQL Database](https://azure.microsoft.com/services/sql-database/) | -| `SQLCONNSTR_` | [SQL Server](https://www.microsoft.com/sql-server/) | - -When an environment variable is discovered and loaded into configuration with any of the four prefixes shown in the table: - -* The configuration key is created by removing the environment variable prefix and adding a configuration key section (`ConnectionStrings`). -* A new configuration key-value pair is created that represents the database connection provider (except for `CUSTOMCONNSTR_`, which has no stated provider). - -| Environment variable key | Converted configuration key | Provider configuration entry | -|--|--|--| -| `CUSTOMCONNSTR_{KEY}` | `ConnectionStrings:{KEY}` | Configuration entry not created. | -| `MYSQLCONNSTR_{KEY}` | `ConnectionStrings:{KEY}` | Key: `ConnectionStrings:{KEY}_ProviderName`:
Value: `MySql.Data.MySqlClient` | -| `SQLAZURECONNSTR_{KEY}` | `ConnectionStrings:{KEY}` | Key: `ConnectionStrings:{KEY}_ProviderName`:
Value: `System.Data.SqlClient` | -| `SQLCONNSTR_{KEY}` | `ConnectionStrings:{KEY}` | Key: `ConnectionStrings:{KEY}_ProviderName`:
Value: `System.Data.SqlClient` | - - - -## File configuration provider - - is the base class for loading configuration from the file system. The following configuration providers derive from `FileConfigurationProvider`: - -* [INI configuration provider](#ini-configuration-provider) -* [JSON configuration provider](#jcp) -* [XML configuration provider](#xml-configuration-provider) - -### INI configuration provider - -The loads configuration from INI file key-value pairs at runtime. - -The following code adds several configuration providers: -[!code-csharp[](~/fundamentals/configuration/index/samples/6.x/ConfigSample/Program.cs?name=snippet_ini)] - -In the preceding code, settings in the `MyIniConfig.ini` and `MyIniConfig.{Environment}.ini` files are overridden by settings in the: - -* [Environment variables configuration provider](#evcp) -* [Command-line configuration provider](#clcp). - -The [sample download](https://github.com/dotnet/AspNetCore.Docs/tree/main/aspnetcore/fundamentals/configuration/index/samples/6.x/ConfigSample) contains the following `MyIniConfig.ini` file: - -[!code-ini[](~/fundamentals/configuration/index/samples/6.x/ConfigSample/MyIniConfig.ini)] - -The following code from the [sample download](https://github.com/dotnet/AspNetCore.Docs/tree/main/aspnetcore/fundamentals/configuration/index/samples/6.x/ConfigSample) displays several of the preceding configurations settings: - -[!code-csharp[](~/fundamentals/configuration/index/samples/3.x/ConfigSample/Pages/Test.cshtml.cs?name=snippet)] - - - -### JSON configuration provider - -The loads configuration from JSON file key-value pairs. - -Overloads can specify: - -* Whether the file is optional. -* Whether the configuration is reloaded if the file changes. - -Consider the following code: - -[!code-csharp[](~/fundamentals/configuration/index/samples/6.x/ConfigSample/Program.cs?name=snippet_json)] - -The preceding code: - -* Configures the JSON configuration provider to load the `MyConfig.json` file with the following options: - * `optional: true`: The file is optional. - * `reloadOnChange: true` : The file is reloaded when changes are saved. -* Reads the [default configuration providers](#default) before the `MyConfig.json` file. Settings in the `MyConfig.json` file override setting in the default configuration providers, including the [Environment variables configuration provider](#evcp) and the [Command-line configuration provider](#clcp). - -You typically ***don't*** want a custom JSON file overriding values set in the [Environment variables configuration provider](#evcp) and the [Command-line configuration provider](#clcp). - - -### XML configuration provider - -The loads configuration from XML file key-value pairs at runtime. - -The following code adds several configuration providers: - -[!code-csharp[](~/fundamentals/configuration/index/samples/6.x/ConfigSample/Program.cs?name=snippet_xml)] - -In the preceding code, settings in the `MyXMLFile.xml` and `MyXMLFile.{Environment}.xml` files are overridden by settings in the: - -* [Environment variables configuration provider](#evcp) -* [Command-line configuration provider](#clcp). - -The [sample download](https://github.com/dotnet/AspNetCore.Docs/tree/main/aspnetcore/fundamentals/configuration/index/samples/6.x/ConfigSample) contains the following `MyXMLFile.xml` file: - -[!code-xml[](~/fundamentals/configuration/index/samples/6.x/ConfigSample/MyXMLFile.xml)] - -The following code from the [sample download](https://github.com/dotnet/AspNetCore.Docs/tree/main/aspnetcore/fundamentals/configuration/index/samples/6.x/ConfigSample) displays several of the preceding configurations settings: - -[!code-csharp[](~/fundamentals/configuration/index/samples/6.x/ConfigSample/Pages/Test.cshtml.cs?name=snippet)] - -Repeating elements that use the same element name work if the `name` attribute is used to distinguish the elements: - -[!code-xml[](~/fundamentals/configuration/index/samples/6.x/ConfigSample/MyXMLFile3.xml)] - -The following code reads the previous configuration file and displays the keys and values: - -[!code-csharp[](~/fundamentals/configuration/index/samples/6.x/ConfigSample/Pages/XML/Index.cshtml.cs?name=snippet)] - -Attributes can be used to supply values: - -```xml - - - -
- -
-
-``` - -The previous configuration file loads the following keys with `value`: - -* key:attribute -* section:key:attribute - -## Key-per-file configuration provider - -The uses a directory's files as configuration key-value pairs. The key is the file name. The value contains the file's contents. The Key-per-file configuration provider is used in Docker hosting scenarios. - -To activate key-per-file configuration, call the extension method on an instance of . The `directoryPath` to the files must be an absolute path. - -Overloads permit specifying: - -* An `Action` delegate that configures the source. -* Whether the directory is optional and the path to the directory. - -The double-underscore (`__`) is used as a configuration key delimiter in file names. For example, the file name `Logging__LogLevel__System` produces the configuration key `Logging:LogLevel:System`. - -Call `ConfigureAppConfiguration` when building the host to specify the app's configuration: - -```csharp -.ConfigureAppConfiguration((hostingContext, config) => -{ - var path = Path.Combine( - Directory.GetCurrentDirectory(), "path/to/files"); - config.AddKeyPerFile(directoryPath: path, optional: true); -}) -``` - - - -## Memory configuration provider - -The uses an in-memory collection as configuration key-value pairs. - -The following code adds a memory collection to the configuration system: - -[!code-csharp[](~/fundamentals/configuration/index/samples/6.x/ConfigSample/Program.cs?name=snippet_mem)] - -The following code from the [sample download](https://github.com/dotnet/AspNetCore.Docs/tree/main/aspnetcore/fundamentals/configuration/index/samples/3.x/ConfigSample) displays the preceding configurations settings: - -[!code-csharp[](~/fundamentals/configuration/index/samples/3.x/ConfigSample/Pages/Test.cshtml.cs?name=snippet)] - -In the preceding code, `config.AddInMemoryCollection(Dict)` is added after the [default configuration providers](#default). For an example of ordering the configuration providers, see [JSON configuration provider](#jcp). - -See [Bind an array](#boa) for another example using `MemoryConfigurationProvider`. - - - -## Kestrel endpoint configuration - -Kestrel specific endpoint configuration overrides all [cross-server](xref:fundamentals/servers/index) endpoint configurations. Cross-server endpoint configurations include: - -* [UseUrls](xref:fundamentals/host/web-host#server-urls) -* `--urls` on the [command line](xref:fundamentals/configuration/index#command-line) -* The [environment variable](xref:fundamentals/configuration/index#environment-variables) `ASPNETCORE_URLS` - -Consider the following `appsettings.json` file used in an ASP.NET Core web app: - -[!code-json[](~/fundamentals/configuration/index/samples_snippets/5.x/appsettings.json?highlight=2-8)] - -When the preceding highlighted markup is used in an ASP.NET Core web app ***and*** the app is launched on the command line with the following cross-server endpoint configuration: - -`dotnet run --urls="https://localhost:7777"` - -Kestrel binds to the endpoint configured specifically for Kestrel in the `appsettings.json` file (`https://localhost:9999`) and not `https://localhost:7777`. - -Consider the Kestrel specific endpoint configured as an environment variable: - -`set Kestrel__Endpoints__Https__Url=https://localhost:8888` - -In the preceding environment variable, `Https` is the name of the Kestrel specific endpoint. The preceding `appsettings.json` file also defines a Kestrel specific endpoint named `Https`. By [default](#default-host-configuration), environment variables using the [Environment Variables configuration provider](#evcp) are read after `appsettings.{Environment}.json`, therefore, the preceding environment variable is used for the `Https` endpoint. - -## GetValue - - extracts a single value from configuration with a specified key and converts it to the specified type: - -[!code-csharp[](~/fundamentals/configuration/index/samples/6.x/ConfigSample/Pages/TestNum.cshtml.cs?name=snippet)] - -In the preceding code, if `NumberKey` isn't found in the configuration, the default value of `99` is used. - -## GetSection, GetChildren, and Exists - -For the examples that follow, consider the following `MySubsection.json` file: - -[!code-json[](~/fundamentals/configuration/index/samples/6.x/ConfigSample/MySubsection.json)] - -The following code adds `MySubsection.json` to the configuration providers: - -[!code-csharp[](~/fundamentals/configuration/index/samples/6.x/ConfigSample/Program.cs?name=snippet_sub)] - -### GetSection - - returns a configuration subsection with the specified subsection key. - -The following code returns values for `section1`: - -[!code-csharp[](~/fundamentals/configuration/index/samples/6.x/ConfigSample/Pages/TestSection.cshtml.cs?name=snippet)] - -The following code returns values for `section2:subsection0`: - -[!code-csharp[](~/fundamentals/configuration/index/samples/6.x/ConfigSample/Pages/TestSection2.cshtml.cs?name=snippet)] - -`GetSection` never returns `null`. If a matching section isn't found, an empty `IConfigurationSection` is returned. - -When `GetSection` returns a matching section, isn't populated. A and are returned when the section exists. - -### GetChildren and Exists - -The following code calls and returns values for `section2:subsection0`: - -[!code-csharp[](~/fundamentals/configuration/index/samples/6.x/ConfigSample/Pages/TestSection4.cshtml.cs?name=snippet)] - -The preceding code calls to verify the section exists: - - - -## Bind an array - -The supports binding arrays to objects using array indices in configuration keys. Any array format that exposes a numeric key segment is capable of array binding to a [POCO](https://wikipedia.org/wiki/Plain_Old_CLR_Object) class array. - -Consider `MyArray.json` from the [sample download](https://github.com/dotnet/AspNetCore.Docs/tree/main/aspnetcore/fundamentals/configuration/index/samples/6.x/ConfigSample): - -[!code-json[](~/fundamentals/configuration/index/samples/6.x/ConfigSample/MyArray.json)] - -The following code adds `MyArray.json` to the configuration providers: - -[!code-csharp[](~/fundamentals/configuration/index/samples/6.x/ConfigSample/Program.cs?name=snippet_ba)] - -The following code reads the configuration and displays the values: - -[!code-csharp[](~/fundamentals/configuration/index/samples/6.x/ConfigSample/Pages/Array.cshtml.cs?name=snippet)] - -[!code-csharp[](~/fundamentals/configuration/index/samples/6.x/ConfigSample/Options/ArrayExample.cs?name=snippet)] - -The preceding code returns the following output: - -```text -Index: 0 Value: value00 -Index: 1 Value: value10 -Index: 2 Value: value20 -Index: 3 Value: value40 -Index: 4 Value: value50 -``` - -In the preceding output, Index 3 has value `value40`, corresponding to `"4": "value40",` in `MyArray.json`. The bound array indices are continuous and not bound to the configuration key index. The configuration binder isn't capable of binding null values or creating null entries in bound objects. - - -## Custom configuration provider - -The sample app demonstrates how to create a basic configuration provider that reads configuration key-value pairs from a database using [Entity Framework (EF)](/ef/core/). - -The provider has the following characteristics: - -* The EF in-memory database is used for demonstration purposes. To use a database that requires a connection string, implement a secondary `ConfigurationBuilder` to supply the connection string from another configuration provider. -* The provider reads a database table into configuration at startup. The provider doesn't query the database on a per-key basis. -* Reload-on-change isn't implemented, so updating the database after the app starts has no effect on the app's configuration. - -Define an `EFConfigurationValue` entity for storing configuration values in the database. - -`Models/EFConfigurationValue.cs`: - -[!code-csharp[](~/fundamentals/configuration/index/samples/6.x/EfconfigSample/Models/EFConfigurationValue.cs?name=snippet1)] - -Add an `EFConfigurationContext` to store and access the configured values. - -`EFConfigurationProvider/EFConfigurationContext.cs`: - -[!code-csharp[](~/fundamentals/configuration/index/samples/6.x/EfconfigSample/EFConfigurationProvider/EFConfigurationContext.cs?name=snippet1)] - -Create a class that implements . - -`EFConfigurationProvider/EFConfigurationSource.cs`: - -[!code-csharp[](~/fundamentals/configuration/index/samples/6.x/EfconfigSample/EFConfigurationProvider/EFConfigurationSource.cs?name=snippet1)] - -Create the custom configuration provider by inheriting from . The configuration provider initializes the database when it's empty. Since configuration keys are case-insensitive, the dictionary used to initialize the database is created with the case-insensitive comparer ([StringComparer.OrdinalIgnoreCase](xref:System.StringComparer.OrdinalIgnoreCase)). - -`EFConfigurationProvider/EFConfigurationProvider.cs`: - -[!code-csharp[](~/fundamentals/configuration/index/samples/6.x/EfconfigSample/EFConfigurationProvider/EFConfigurationProvider.cs?name=snippet1)] - -An `AddEFConfiguration` extension method permits adding the configuration source to a `ConfigurationBuilder`. - -`Extensions/EntityFrameworkExtensions.cs`: - -[!code-csharp[](~/fundamentals/configuration/index/samples/6.x/EfconfigSample/Extensions/EntityFrameworkExtensions.cs?name=snippet1)] - -The following code shows how to use the custom `EFConfigurationProvider` in `Program.cs`: - -[!code-csharp[](~/fundamentals/configuration/index/samples_snippets/6.x/EfconfigSample/Program.cs?highlight=5-6)] - -## Access configuration with Dependency Injection (DI) - -Configuration can be injected into services using [Dependency Injection (DI)](xref:fundamentals/dependency-injection) by resolving the service: - -[!code-csharp[](~/fundamentals/configuration/index/samples/6.x/ConfigSample/Service.cs?name=snippet_Class&highlight=5-6)] - -For information on how to access values using `IConfiguration`, see [GetValue](#getvalue) and [GetSection, GetChildren, and Exists](#getsection-getchildren-and-exists) in this article. - -## Access configuration in Razor Pages - -The following code displays configuration data in a Razor Page: - -[!code-cshtml[](~/fundamentals/configuration/index/samples/6.x/ConfigSample/Pages/Test5.cshtml)] - -In the following code, `MyOptions` is added to the service container with and bound to configuration: - -[!code-csharp[](~/fundamentals/configuration/options/samples/6.x/OptionsSample/Program.cs?name=snippet)] - -The following markup uses the [`@inject`](xref:mvc/views/razor#inject) Razor directive to resolve and display the options values: - -[!code-cshtml[](~/fundamentals/configuration/options/samples/6.x/OptionsSample/Pages/Test3.cshtml)] - -## Access configuration in a MVC view file - -The following code displays configuration data in a MVC view: - -[!code-cshtml[](~/fundamentals/configuration/index/samples/3.x/ConfigSample/Views/Home2/Index.cshtml)] - -## Access configuration in `Program.cs` - -The following code accesses configuration in the `Program.cs` file. - -```csharp -var builder = WebApplication.CreateBuilder(args); - -var key1 = builder.Configuration.GetValue("KeyOne"); - -var app = builder.Build(); - -app.MapGet("/", () => "Hello World!"); - -var key2 = app.Configuration.GetValue("KeyTwo"); -var key3 = app.Configuration.GetValue("KeyThree"); - -app.Logger.LogInformation("KeyOne: {KeyOne}", key1); -app.Logger.LogInformation("KeyTwo: {KeyTwo}", key2); -app.Logger.LogInformation("KeyThree: {KeyThree}", key3); - -app.Run(); -``` - -In `appsettings.json` for the preceding example: - -```json -{ - ... - "KeyOne": "Key One Value", - "KeyTwo": 1999, - "KeyThree": true -} -``` - -## Configure options with a delegate - -Options configured in a delegate override values set in the configuration providers. - -In the following code, an service is added to the service container. It uses a delegate to configure values for `MyOptions`: - -[!code-csharp[](~/fundamentals/configuration/options/samples/6.x/OptionsSample/Program.cs?name=snippet_del)] - -The following code displays the options values: - -[!code-csharp[](~/fundamentals/configuration/options/samples/6.x/OptionsSample/Pages/Test2.cshtml.cs?name=snippet)] - -In the preceding example, the values of `Option1` and `Option2` are specified in `appsettings.json` and then overridden by the configured delegate. - - - -## Host versus app configuration - -Before the app is configured and started, a *host* is configured and launched. The host is responsible for app startup and lifetime management. Both the app and the host are configured using the configuration providers described in this topic. Host configuration key-value pairs are also included in the app's configuration. For more information on how the configuration providers are used when the host is built and how configuration sources affect host configuration, see . - - - -## Default host configuration - -For details on the default configuration when using the [Web Host](xref:fundamentals/host/web-host), see the [ASP.NET Core 2.2 version of this topic](?view=aspnetcore-2.2&preserve-view=true). - -* Host configuration is provided from: - * Environment variables prefixed with `DOTNET_` (for example, `DOTNET_ENVIRONMENT`) using the [Environment Variables configuration provider](#evcp). The prefix (`DOTNET_`) is stripped when the configuration key-value pairs are loaded. - * Command-line arguments using the [Command-line configuration provider](#clcp). -* Web Host default configuration is established (`ConfigureWebHostDefaults`): - * Kestrel is used as the web server and configured using the app's configuration providers. - * Add Host Filtering Middleware. - * Add Forwarded Headers Middleware if the `ASPNETCORE_FORWARDEDHEADERS_ENABLED` environment variable is set to `true`. - * Enable IIS integration. - -## Other configuration - -This topic only pertains to *app configuration*. Other aspects of running and hosting ASP.NET Core apps are configured using configuration files not covered in this topic: - -* `launch.json`/`launchSettings.json` are tooling configuration files for the Development environment, described: - * In . - * Across the documentation set where the files are used to configure ASP.NET Core apps for Development scenarios. -* `web.config` is a server configuration file, described in the following topics: - * - * - -Environment variables set in `launchSettings.json` override those set in the system environment. - -For more information on migrating app configuration from earlier versions of ASP.NET, see . - -## Add configuration from an external assembly - -An implementation allows adding enhancements to an app at startup from an external assembly outside of the app's `Startup` class. For more information, see . - -## Additional resources - -* [Configuration source code](https://github.com/dotnet/runtime/tree/main/src/libraries/Microsoft.Extensions.Configuration) -* [View or download sample code](https://github.com/dotnet/AspNetCore.Docs/tree/main/aspnetcore/fundamentals/configuration/index/samples) ([how to download](xref:fundamentals/index#how-to-download-a-sample)) -* -* - -:::moniker-end diff --git a/aspnetcore/fundamentals/configuration/options.md b/aspnetcore/fundamentals/configuration/options.md index 9e10fb6f703f..4b17cfee172a 100644 --- a/aspnetcore/fundamentals/configuration/options.md +++ b/aspnetcore/fundamentals/configuration/options.md @@ -5,20 +5,15 @@ description: Discover how to use the options pattern to represent groups of rela monikerRange: '>= aspnetcore-3.1' ms.author: tdykstra ms.custom: mvc -ms.date: 04/20/2025 +ms.date: 10/15/2025 uid: fundamentals/configuration/options --- # Options pattern in ASP.NET Core [!INCLUDE[](~/includes/not-latest-version.md)] - - :::moniker range=">= aspnetcore-7.0" -By [Rick Anderson](https://twitter.com/RickAndMSFT). - The options pattern uses classes to provide strongly typed access to groups of related settings. When [configuration settings](xref:fundamentals/configuration/index) are isolated by scenario into separate classes, the app adheres to two important software engineering principles: * [Encapsulation](/dotnet/standard/modern-web-apps-azure-architecture/architectural-principles#encapsulation): @@ -34,7 +29,65 @@ This article provides information on the options pattern in ASP.NET Core. For in ## Bind hierarchical configuration -[!INCLUDE[](~/includes/bind7.md)] +The preferred way to read related configuration values is using the [options pattern](xref:fundamentals/configuration/options). For example, to read the following configuration values: + +```json + "Position": { + "Title": "Editor", + "Name": "Joe Smith" + } +``` + +Create the following `PositionOptions` class: + +[!code-csharp[](~/fundamentals/configuration/index/samples/6.x/ConfigSample/Options/PositionOptions.cs?name=snippet)] + +An options class: + +* Must be non-abstract. +* Has public read-write properties of the type that have corresponding items in config are bound. +* Has its read-write properties bound to matching entries in configuration. +* Does ***not*** have its fields bound. In the preceding code, `Position` is not bound. The `Position` field is used so the string `"Position"` doesn't need to be hard coded in the app when binding the class to a configuration provider. + +The following code: + +* Calls [ConfigurationBinder.Bind](xref:Microsoft.Extensions.Configuration.ConfigurationBinder.Bind*) to bind the `PositionOptions` class to the `Position` section. +* Displays the `Position` configuration data. + +[!code-csharp[](~/fundamentals/configuration/index/samples/6.x/ConfigSample/Pages/Test22.cshtml.cs?name=snippet)] + +In the preceding code, by default, changes to the JSON configuration file after the app has started are read. + +[`ConfigurationBinder.Get`](xref:Microsoft.Extensions.Configuration.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: + +[!code-csharp[](~/fundamentals/configuration/index/samples/6.x/ConfigSample/Pages/Test21.cshtml.cs?name=snippet)] + +In the preceding code, by default, changes to the JSON configuration file after the app has started are read. + +Bind also allows the concretion of an abstract class. Consider the following code which uses the abstract class `SomethingWithAName`: + +[!code-csharp[](~/fundamentals/configuration/index/samples/8.x/ConfigSample/Options/NameTitleOptions.cs)] + +The following code displays the `NameTitleOptions` configuration values: + +[!code-csharp[](~/fundamentals/configuration/index/samples/8.x/ConfigSample/Pages/Test33.cshtml.cs?name=snippet)] + +Calls to `Bind` are less strict than calls to `Get<>`: + +* `Bind` allows the concretion of an abstract. +* `Get<>` has to create an instance itself. + +## The Options Pattern + +An alternative approach when using the ***options pattern*** is to bind the `Position` section and add it to the [dependency injection service container](xref:fundamentals/dependency-injection). In the following code, `PositionOptions` is added to the service container with and bound to configuration: + +[!code-csharp[](~/fundamentals/configuration/index/samples/6.x/ConfigSample/Program.cs?name=snippet)] + +Using the preceding code, the following code reads the position options: + +[!code-csharp[](~/fundamentals/configuration/index/samples/6.x/ConfigSample/Pages/Test2.cshtml.cs?name=snippet)] + +In the preceding code, changes to the JSON configuration file after the app has started are ***not*** read. To read changes after the app has started, use [IOptionsSnapshot](xref:fundamentals/configuration/options#ios). diff --git a/aspnetcore/fundamentals/configuration/options/includes/options6.md b/aspnetcore/fundamentals/configuration/options/includes/options6.md index 781e59f0de81..cd20035d3815 100644 --- a/aspnetcore/fundamentals/configuration/options/includes/options6.md +++ b/aspnetcore/fundamentals/configuration/options/includes/options6.md @@ -1,7 +1,5 @@ :::moniker range="= aspnetcore-6.0" -By [Kirk Larkin](https://twitter.com/serpent5) and [Rick Anderson](https://twitter.com/RickAndMSFT). - The options pattern uses classes to provide strongly typed access to groups of related settings. When [configuration settings](xref:fundamentals/configuration/index) are isolated by scenario into separate classes, the app adheres to two important software engineering principles: * [Encapsulation](/dotnet/standard/modern-web-apps-azure-architecture/architectural-principles#encapsulation): @@ -17,7 +15,49 @@ This article provides information on the options pattern in ASP.NET Core. For in ## Bind hierarchical configuration -[!INCLUDE[](~/includes/bind6.md)] +The preferred way to read related configuration values is using the [options pattern](xref:fundamentals/configuration/options). For example, to read the following configuration values: + +```json + "Position": { + "Title": "Editor", + "Name": "Joe Smith" + } +``` + +Create the following `PositionOptions` class: + +[!code-csharp[](~/fundamentals/configuration/index/samples/6.x/ConfigSample/Options/PositionOptions.cs?name=snippet)] + +An options class: + +* Must be non-abstract with a public parameterless constructor. +* All public read-write properties of the type are bound. +* Fields are ***not*** bound. In the preceding code, `Position` is not bound. The `Position` field is used so the string `"Position"` doesn't need to be hard coded in the app when binding the class to a configuration provider. + +The following code: + +* Calls [ConfigurationBinder.Bind](xref:Microsoft.Extensions.Configuration.ConfigurationBinder.Bind*) to bind the `PositionOptions` class to the `Position` section. +* Displays the `Position` configuration data. + +[!code-csharp[](~/fundamentals/configuration/index/samples/6.x/ConfigSample/Pages/Test22.cshtml.cs?name=snippet)] + +In the preceding code, by default, changes to the JSON configuration file after the app has started are read. + +[`ConfigurationBinder.Get`](xref:Microsoft.Extensions.Configuration.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: + +[!code-csharp[](~/fundamentals/configuration/index/samples/6.x/ConfigSample/Pages/Test21.cshtml.cs?name=snippet)] + +In the preceding code, by default, changes to the JSON configuration file after the app has started are read. + +An alternative approach when using the ***options pattern*** is to bind the `Position` section and add it to the [dependency injection service container](xref:fundamentals/dependency-injection). In the following code, `PositionOptions` is added to the service container with and bound to configuration: + +[!code-csharp[](~/fundamentals/configuration/index/samples/6.x/ConfigSample/Program.cs?name=snippet)] + +Using the preceding code, the following code reads the position options: + +[!code-csharp[](~/fundamentals/configuration/index/samples/6.x/ConfigSample/Pages/Test2.cshtml.cs?name=snippet)] + +In the preceding code, changes to the JSON configuration file after the app has started are ***not*** read. To read changes after the app has started, use [IOptionsSnapshot](xref:fundamentals/configuration/options#ios). diff --git a/aspnetcore/fundamentals/dependency-injection.md b/aspnetcore/fundamentals/dependency-injection.md index df7e66597505..dd65c031bd42 100644 --- a/aspnetcore/fundamentals/dependency-injection.md +++ b/aspnetcore/fundamentals/dependency-injection.md @@ -105,7 +105,7 @@ The following code is generated by the Razor Pages template using individual acc [!code-csharp[](~/fundamentals/dependency-injection/samples/6.x/DependencyInjectionSample/ProgramEF.cs?name=snippet)] -[!INCLUDE[](~/includes/combine-di6.md)] +[!INCLUDE[](~/includes/combine-service-collection-60-or-later.md)] ## Service lifetimes diff --git a/aspnetcore/fundamentals/dependency-injection/includes/dependency-injection-5-7.md b/aspnetcore/fundamentals/dependency-injection/includes/dependency-injection-5-7.md index 298cde4cb5c0..f82a23b321b3 100644 --- a/aspnetcore/fundamentals/dependency-injection/includes/dependency-injection-5-7.md +++ b/aspnetcore/fundamentals/dependency-injection/includes/dependency-injection-5-7.md @@ -95,7 +95,7 @@ The following code is generated by the Razor Pages template using individual use [!code-csharp[](~/fundamentals/dependency-injection/samples/6.x/DependencyInjectionSample/ProgramEF.cs?name=snippet)] -[!INCLUDE[](~/includes/combine-di6.md)] +[!INCLUDE[](~/includes/combine-service-collection-60-or-later.md)] ## Service lifetimes @@ -485,7 +485,7 @@ The following code is generated by the Razor Pages template using individual use [!code-csharp[](~/fundamentals/dependency-injection/samples/3.x/DependencyInjectionSample/StartupEF.cs?name=snippet)] -[!INCLUDE[](~/includes/combine-di.md)] +[!INCLUDE[](~/includes/combine-service-collection-31-to-60.md)] ## Service lifetimes diff --git a/aspnetcore/fundamentals/dependency-injection/includes/dependency-injection-8.md b/aspnetcore/fundamentals/dependency-injection/includes/dependency-injection-8.md index 79d5cdf9a017..074662e9443c 100644 --- a/aspnetcore/fundamentals/dependency-injection/includes/dependency-injection-8.md +++ b/aspnetcore/fundamentals/dependency-injection/includes/dependency-injection-8.md @@ -96,7 +96,7 @@ The following code is generated by the Razor Pages template using individual acc [!code-csharp[](~/fundamentals/dependency-injection/samples/6.x/DependencyInjectionSample/ProgramEF.cs?name=snippet)] -[!INCLUDE[](~/includes/combine-di6.md)] +[!INCLUDE[](~/includes/combine-service-collection-60-or-later.md)] ## Service lifetimes diff --git a/aspnetcore/fundamentals/host/generic-host.md b/aspnetcore/fundamentals/host/generic-host.md index 2185929dbcd6..ec0985b7fbdd 100644 --- a/aspnetcore/fundamentals/host/generic-host.md +++ b/aspnetcore/fundamentals/host/generic-host.md @@ -207,7 +207,7 @@ To set this value, use the environment variable or configure `HostOptions`. The ### Disable app configuration reload on change -By [default](xref:fundamentals/configuration/index#default), `appsettings.json` and `appsettings.{Environment}.json` are reloaded when the file changes. To disable this reload behavior in .NET 5 or later, set the `hostBuilder:reloadConfigOnChange` key to `false`. +By [default](xref:fundamentals/configuration/index#default-app-configuration-sources), `appsettings.json` and `appsettings.{Environment}.json` are reloaded when the file changes. To disable this reload behavior in .NET 5 or later, set the `hostBuilder:reloadConfigOnChange` key to `false`. **Key**: `hostBuilder:reloadConfigOnChange` **Type**: `bool` (`true` or `false`) @@ -675,7 +675,7 @@ To set this value, use the environment variable or configure `HostOptions`. The ### Disable app configuration reload on change -By [default](xref:fundamentals/configuration/index#default), `appsettings.json` and `appsettings.{Environment}.json` are reloaded when the file changes. To disable this reload behavior in .NET 5 or later, set the `hostBuilder:reloadConfigOnChange` key to `false`. +By [default](xref:fundamentals/configuration/index#default-app-configuration-sources), `appsettings.json` and `appsettings.{Environment}.json` are reloaded when the file changes. To disable this reload behavior in .NET 5 or later, set the `hostBuilder:reloadConfigOnChange` key to `false`. **Key**: `hostBuilder:reloadConfigOnChange` **Type**: `bool` (`true` or `false`) diff --git a/aspnetcore/fundamentals/index.md b/aspnetcore/fundamentals/index.md index e577f3e3508b..a92729105236 100644 --- a/aspnetcore/fundamentals/index.md +++ b/aspnetcore/fundamentals/index.md @@ -135,7 +135,7 @@ For more information, see . ASP.NET Core provides a [configuration](xref:fundamentals/configuration/index) framework that gets settings as name-value pairs from an ordered set of configuration providers. Built-in configuration providers are available for a variety of sources, such as `.json` files, `.xml` files, environment variables, and command-line arguments. Write custom configuration providers to support other sources. -By [default](xref:fundamentals/configuration/index#default), ASP.NET Core apps are configured to read from `appsettings.json`, environment variables, the command line, and more. When the app's configuration is loaded, values from environment variables override values from `appsettings.json`. +By [default](xref:fundamentals/configuration/index#default-app-configuration-sources), ASP.NET Core apps are configured to read from `appsettings.json`, environment variables, the command line, and more. When the app's configuration is loaded, values from environment variables override values from `appsettings.json`. For managing confidential configuration data such as passwords in the development environment, .NET provides the [Secret Manager](xref:security/app-secrets#secret-manager). For production secrets, we recommend [Azure Key Vault](xref:security/key-vault-configuration). diff --git a/aspnetcore/fundamentals/index/includes/index3-7.md b/aspnetcore/fundamentals/index/includes/index3-7.md index 820307480f92..99dd07104c4f 100644 --- a/aspnetcore/fundamentals/index/includes/index3-7.md +++ b/aspnetcore/fundamentals/index/includes/index3-7.md @@ -106,7 +106,7 @@ For more information, see . ASP.NET Core provides a [configuration](xref:fundamentals/configuration/index) framework that gets settings as name-value pairs from an ordered set of configuration providers. Built-in configuration providers are available for a variety of sources, such as `.json` files, `.xml` files, environment variables, and command-line arguments. Write custom configuration providers to support other sources. -By [default](xref:fundamentals/configuration/index#default), ASP.NET Core apps are configured to read from `appsettings.json`, environment variables, the command line, and more. When the app's configuration is loaded, values from environment variables override values from `appsettings.json`. +By [default](xref:fundamentals/configuration/index#default-app-configuration-sources), ASP.NET Core apps are configured to read from `appsettings.json`, environment variables, the command line, and more. When the app's configuration is loaded, values from environment variables override values from `appsettings.json`. For managing confidential configuration data such as passwords, .NET provides the [Secret Manager](xref:security/app-secrets#secret-manager). For production secrets, we recommend [Azure Key Vault](xref:security/key-vault-configuration). @@ -321,9 +321,9 @@ For more information, see . ASP.NET Core provides a configuration framework that gets settings as name-value pairs from an ordered set of configuration providers. Built-in configuration providers are available for a variety of sources, such as `.json` files, `.xml` files, environment variables, and command-line arguments. Write custom configuration providers to support other sources. -By [default](xref:fundamentals/configuration/index#default), ASP.NET Core apps are configured to read from `appsettings.json`, environment variables, the command line, and more. When the app's configuration is loaded, values from environment variables override values from `appsettings.json`. +By [default](xref:fundamentals/configuration/index#default-app-configuration-sources), ASP.NET Core apps are configured to read from `appsettings.json`, environment variables, the command line, and more. When the app's configuration is loaded, values from environment variables override values from `appsettings.json`. -The preferred way to read related configuration values is using the [options pattern](xref:fundamentals/configuration/options). For more information, see [Bind hierarchical configuration data using the options pattern](xref:fundamentals/configuration/index#optpat). +The preferred way to read related configuration values is using the [options pattern](xref:fundamentals/configuration/options). For more information, see [Bind hierarchical configuration data using the options pattern](xref:fundamentals/configuration/index#bind-hierarchical-configuration-data-using-the-options-pattern). For managing confidential configuration data such as passwords, .NET provides the [Secret Manager](xref:security/app-secrets#secret-manager). For production secrets, we recommend [Azure Key Vault](xref:security/key-vault-configuration). diff --git a/aspnetcore/fundamentals/index/includes/index8.md b/aspnetcore/fundamentals/index/includes/index8.md index d6987b331482..4185c3039849 100644 --- a/aspnetcore/fundamentals/index/includes/index8.md +++ b/aspnetcore/fundamentals/index/includes/index8.md @@ -108,7 +108,7 @@ For more information, see . ASP.NET Core provides a [configuration](xref:fundamentals/configuration/index) framework that gets settings as name-value pairs from an ordered set of configuration providers. Built-in configuration providers are available for a variety of sources, such as `.json` files, `.xml` files, environment variables, and command-line arguments. Write custom configuration providers to support other sources. -By [default](xref:fundamentals/configuration/index#default), ASP.NET Core apps are configured to read from `appsettings.json`, environment variables, the command line, and more. When the app's configuration is loaded, values from environment variables override values from `appsettings.json`. +By [default](xref:fundamentals/configuration/index#default-app-configuration-sources), ASP.NET Core apps are configured to read from `appsettings.json`, environment variables, the command line, and more. When the app's configuration is loaded, values from environment variables override values from `appsettings.json`. For managing confidential configuration data such as passwords, .NET provides the [Secret Manager](xref:security/app-secrets#secret-manager). For production secrets, we recommend [Azure Key Vault](xref:security/key-vault-configuration). diff --git a/aspnetcore/fundamentals/minimal-apis/includes/webapplication10.md b/aspnetcore/fundamentals/minimal-apis/includes/webapplication10.md index 5ca6e98c2e2c..6b4151bc55ee 100644 --- a/aspnetcore/fundamentals/minimal-apis/includes/webapplication10.md +++ b/aspnetcore/fundamentals/minimal-apis/includes/webapplication10.md @@ -40,7 +40,7 @@ The following command makes the app respond to port `7777`: dotnet run --urls="https://localhost:7777" ``` -If the Kestrel endpoint is also configured in the `appsettings.json` file, the `appsettings.json` file specified URL is used. For more information, see [Kestrel endpoint configuration](xref:fundamentals/configuration/index#kestrel) +If the Kestrel endpoint is also configured in the `appsettings.json` file, the `appsettings.json` file specified URL is used. For more information, see [Kestrel endpoint configuration](xref:fundamentals/configuration/index#kestrel-endpoint-configuration) #### Read the port from environment diff --git a/aspnetcore/fundamentals/minimal-apis/includes/webapplication7.md b/aspnetcore/fundamentals/minimal-apis/includes/webapplication7.md index 0e6d9e8e7d7b..88b2993bff4a 100644 --- a/aspnetcore/fundamentals/minimal-apis/includes/webapplication7.md +++ b/aspnetcore/fundamentals/minimal-apis/includes/webapplication7.md @@ -39,7 +39,7 @@ The following command makes the app respond to port `7777`: dotnet run --urls="https://localhost:7777" ``` -If the Kestrel endpoint is also configured in the `appsettings.json` file, the `appsettings.json` file specified URL is used. For more information, see [Kestrel endpoint configuration](xref:fundamentals/configuration/index#kestrel) +If the Kestrel endpoint is also configured in the `appsettings.json` file, the `appsettings.json` file specified URL is used. For more information, see [Kestrel endpoint configuration](xref:fundamentals/configuration/index#kestrel-endpoint-configuration) #### Read the port from environment diff --git a/aspnetcore/fundamentals/minimal-apis/includes/webapplication8.md b/aspnetcore/fundamentals/minimal-apis/includes/webapplication8.md index 4b2360d4ab32..cb1dd1c90de1 100644 --- a/aspnetcore/fundamentals/minimal-apis/includes/webapplication8.md +++ b/aspnetcore/fundamentals/minimal-apis/includes/webapplication8.md @@ -40,7 +40,7 @@ The following command makes the app respond to port `7777`: dotnet run --urls="https://localhost:7777" ``` -If the Kestrel endpoint is also configured in the `appsettings.json` file, the `appsettings.json` file specified URL is used. For more information, see [Kestrel endpoint configuration](xref:fundamentals/configuration/index#kestrel) +If the Kestrel endpoint is also configured in the `appsettings.json` file, the `appsettings.json` file specified URL is used. For more information, see [Kestrel endpoint configuration](xref:fundamentals/configuration/index#kestrel-endpoint-configuration) #### Read the port from environment diff --git a/aspnetcore/fundamentals/minimal-apis/includes/webapplication9.md b/aspnetcore/fundamentals/minimal-apis/includes/webapplication9.md index 4cf13d737db0..741744df6adb 100644 --- a/aspnetcore/fundamentals/minimal-apis/includes/webapplication9.md +++ b/aspnetcore/fundamentals/minimal-apis/includes/webapplication9.md @@ -40,7 +40,7 @@ The following command makes the app respond to port `7777`: dotnet run --urls="https://localhost:7777" ``` -If the Kestrel endpoint is also configured in the `appsettings.json` file, the `appsettings.json` file specified URL is used. For more information, see [Kestrel endpoint configuration](xref:fundamentals/configuration/index#kestrel) +If the Kestrel endpoint is also configured in the `appsettings.json` file, the `appsettings.json` file specified URL is used. For more information, see [Kestrel endpoint configuration](xref:fundamentals/configuration/index#kestrel-endpoint-configuration) #### Read the port from environment diff --git a/aspnetcore/host-and-deploy/azure-apps/index.md b/aspnetcore/host-and-deploy/azure-apps/index.md index 6138bbeaf417..dac12615695b 100644 --- a/aspnetcore/host-and-deploy/azure-apps/index.md +++ b/aspnetcore/host-and-deploy/azure-apps/index.md @@ -74,24 +74,10 @@ The preceding packages must be explicitly referenced in the app's project file. ## Override app configuration using the Azure Portal -:::moniker range=">= aspnetcore-3.0" - -App settings in the Azure Portal permit you to set environment variables for the app. Environment variables can be consumed by the [Environment Variables Configuration Provider](xref:fundamentals/configuration/index#environment-variables). - -When an app setting is created or modified in the Azure Portal and the **Save** button is selected, the Azure App is restarted. The environment variable is available to the app after the service restarts. +App settings in the Azure Portal permit you to set environment variables for the app. For more information, see the following resources: -Environment variables are loaded into the app's configuration when [CreateBuilder](/dotnet/api/microsoft.aspnetcore.builder.webapplication.createbuilder) is called to build the host. For more information, see the [Environment Variables Configuration Provider](xref:fundamentals/configuration/index#environment-variables). - -:::moniker-end -:::moniker range="< aspnetcore-3.0" - -App settings in the Azure Portal permit you to set environment variables for the app. Environment variables can be consumed by the [Environment Variables Configuration Provider](xref:fundamentals/configuration/index#evcp). - -When an app setting is created or modified in the Azure Portal and the **Save** button is selected, the Azure App is restarted. The environment variable is available to the app after the service restarts. - -When an app uses the [Web Host](xref:fundamentals/host/web-host), environment variables are loaded into the app's configuration when is called to build the host. For more information, see and the [Environment Variables Configuration Provider](xref:fundamentals/configuration/index#evcp). - -:::moniker-end +* [Configure an App Service app (Azure documentation)](/azure/app-service/configure-common) +* ## Proxy server and load balancer scenarios diff --git a/aspnetcore/includes/combine-di.md b/aspnetcore/includes/combine-di.md deleted file mode 100644 index 20f66214ac9a..000000000000 --- a/aspnetcore/includes/combine-di.md +++ /dev/null @@ -1,18 +0,0 @@ - - -Consider the following `ConfigureServices` method, which registers services and configures options: - -[!code-csharp[](~/fundamentals/configuration/index/samples/3.x/ConfigSample/Startup2.cs?name=snippet)] - -Related groups of registrations can be moved to an extension method to register services. For example, the configuration services are added to the following class: - -[!code-csharp[](~/fundamentals/configuration/index/samples/3.x/ConfigSample/Options/MyConfigServiceCollectionExtensions.cs)] - -The remaining services are registered in a similar class. The following `ConfigureServices` method uses the new extension methods to register the services: - -[!code-csharp[](~/fundamentals/configuration/index/samples/3.x/ConfigSample/Startup4.cs?name=snippet)] - -**_Note:_** Each `services.Add{GROUP_NAME}` extension method adds and potentially configures services. For example, adds the services MVC controllers with views require, and adds the services Razor Pages requires. We recommend that apps follow the naming convention of creating extension methods in the namespace. Creating extension methods in the `Microsoft.Extensions.DependencyInjection` namespace: - -* Encapsulates groups of service registrations. -* Provides convenient [IntelliSense](/visualstudio/ide/using-intellisense) access to the service. diff --git a/aspnetcore/includes/combine-di6.md b/aspnetcore/includes/combine-di6.md deleted file mode 100644 index 1f0b2b9b19c1..000000000000 --- a/aspnetcore/includes/combine-di6.md +++ /dev/null @@ -1,15 +0,0 @@ - - -Consider the following which registers services and configures options: - -[!code-csharp[](~/fundamentals/configuration/index/samples/6.x/ConfigSample/program.cs?name=snippet2)] - -Related groups of registrations can be moved to an extension method to register services. For example, the configuration services are added to the following class: - -[!code-csharp[](~/fundamentals/configuration/index/samples/6.x/ConfigSample/Options/MyConfigServiceCollectionExtensions.cs)] - -The remaining services are registered in a similar class. The following code uses the new extension methods to register the services: - -[!code-csharp[](~/fundamentals/configuration/index/samples/6.x/ConfigSample/program.cs?name=snippet3)] - -**_Note:_** Each `services.Add{GROUP_NAME}` extension method adds and potentially configures services. For example, adds the services MVC controllers with views require, and adds the services Razor Pages requires. diff --git a/aspnetcore/includes/combine-service-collection-31-to-60.md b/aspnetcore/includes/combine-service-collection-31-to-60.md new file mode 100644 index 000000000000..953fd269b81a --- /dev/null +++ b/aspnetcore/includes/combine-service-collection-31-to-60.md @@ -0,0 +1,66 @@ +Consider the following `ConfigureServices` method, which registers services and configures options: + +```csharp +public void ConfigureServices(IServiceCollection services) +{ + services.Configure( + Configuration.GetSection(PositionOptions.Position)); + services.Configure( + Configuration.GetSection(ColorOptions.Color)); + + services.AddScoped(); + services.AddScoped(); + + services.AddRazorPages(); +} +``` + +Related groups of registrations can be moved to an extension method to register services. For example, the configuration services are added to the following class: + +```csharp +using ConfigSample.Options; +using Microsoft.Extensions.Configuration; + +namespace Microsoft.Extensions.DependencyInjection +{ + public static class MyConfigServiceCollectionExtensions + { + public static IServiceCollection AddConfig( + this IServiceCollection services, IConfiguration config) + { + services.Configure( + config.GetSection(PositionOptions.Position)); + services.Configure( + config.GetSection(ColorOptions.Color)); + + return services; + } + + public static IServiceCollection AddMyDependencyGroup( + this IServiceCollection services) + { + services.AddScoped(); + services.AddScoped(); + + return services; + } + } +} +``` + +The remaining services are registered in a similar class. The following `ConfigureServices` method uses the new extension methods to register the services: + +```csharp +public void ConfigureServices(IServiceCollection services) +{ + services.AddConfig(Configuration) + .AddMyDependencyGroup(); + + services.AddRazorPages(); +} +``` + +Each `services.Add{GROUP NAME}` extension method adds and potentially configures services. For example, adds the services MVC controllers with views require, and adds the services Razor Pages requires. We recommend that apps follow the naming convention of creating extension methods in the namespace. Creating extension methods in the `Microsoft.Extensions.DependencyInjection` namespace: + +* Encapsulates groups of service registrations. +* Provides convenient [IntelliSense](/visualstudio/ide/using-intellisense) access to the service. diff --git a/aspnetcore/includes/combine-service-collection-60-or-later.md b/aspnetcore/includes/combine-service-collection-60-or-later.md new file mode 100644 index 000000000000..9c1281e82381 --- /dev/null +++ b/aspnetcore/includes/combine-service-collection-60-or-later.md @@ -0,0 +1,71 @@ +Consider the following which registers services and configures options: + +```csharp +using ConfigSample.Options; +using Microsoft.Extensions.DependencyInjection.ConfigSample.Options; + +var builder = WebApplication.CreateBuilder(args); + +builder.Services.AddRazorPages(); + +builder.Services.Configure( + builder.Configuration.GetSection(PositionOptions.Position)); +builder.Services.Configure( + builder.Configuration.GetSection(ColorOptions.Color)); + +builder.Services.AddScoped(); +builder.Services.AddScoped(); + +var app = builder.Build(); +``` + +Related groups of registrations can be moved to an extension method to register services. For example, the configuration services are added to the following class: + +```csharp +using ConfigSample.Options; +using Microsoft.Extensions.Configuration; + +namespace Microsoft.Extensions.DependencyInjection +{ + public static class MyConfigServiceCollectionExtensions + { + public static IServiceCollection AddConfig( + this IServiceCollection services, IConfiguration config) + { + services.Configure( + config.GetSection(PositionOptions.Position)); + services.Configure( + config.GetSection(ColorOptions.Color)); + + return services; + } + + public static IServiceCollection AddMyDependencyGroup( + this IServiceCollection services) + { + services.AddScoped(); + services.AddScoped(); + + return services; + } + } +} +``` + +The remaining services are registered in a similar class. The following code uses the new extension methods to register the services: + +```csharp +using Microsoft.Extensions.DependencyInjection.ConfigSample.Options; + +var builder = WebApplication.CreateBuilder(args); + +builder.Services + .AddConfig(builder.Configuration) + .AddMyDependencyGroup(); + +builder.Services.AddRazorPages(); + +var app = builder.Build(); +``` + +**_Note:_** Each `services.Add{GROUP_NAME}` extension method adds and potentially configures services. For example, adds the services MVC controllers with views require, and adds the services Razor Pages requires. diff --git a/aspnetcore/includes/environmentVarableColon.md b/aspnetcore/includes/environmentVarableColon.md index 7227622d81ca..7dd205f822c4 100644 --- a/aspnetcore/includes/environmentVarableColon.md +++ b/aspnetcore/includes/environmentVarableColon.md @@ -1,3 +1,4 @@ -The `:` separator doesn't work with environment variable hierarchical keys on all platforms. For example, the `:` separator is not supported by [Bash](https://linuxhint.com/bash-environment-variables/). The double underscore, `__`, is: +The `:` separator doesn't work with environment variable hierarchical keys on all platforms. For example, the `:` separator isn't supported by [Bash](https://linuxhint.com/bash-environment-variables/). The double underscore, `__`, is: + * Supported by all platforms. -* Automatically replaced by a colon, `:`. +* Automatically replaced by a colon (`:`). diff --git a/aspnetcore/includes/managed-identities-conn-strings.md b/aspnetcore/includes/managed-identities-conn-strings.md index e8d80e875779..688198a40f27 100644 --- a/aspnetcore/includes/managed-identities-conn-strings.md +++ b/aspnetcore/includes/managed-identities-conn-strings.md @@ -4,6 +4,5 @@ ms.author: tdykstra ms.date: 10/16/2024 ms.topic: include --- - > [!WARNING] -> This article shows the use of connection strings. With a local database the user doesn't have to be authenticated, but in production, connection strings sometimes include a password to authenticate. A resource owner password credential (ROPC) is a security risk that should be avoided in production databases. Production apps should use the most secure authentication flow available. For more information on authentication for apps deployed to test or production environments, see [Secure authentication flows](xref:security/index#secure-authentication-flows). +> This article shows the use of connection strings. When using a local database for development and testing, database user authentication via the connection string isn't required. In production environments, connection strings sometimes include a password to authenticate database access or database operations. A resource owner password credential (ROPC) in a connection string is a security risk to avoid in production apps. Production apps should use the most secure authentication flow available. For more information on authentication for apps deployed to test or production environments, see . diff --git a/aspnetcore/security/app-secrets.md b/aspnetcore/security/app-secrets.md index 71e86debf398..14b403fff648 100644 --- a/aspnetcore/security/app-secrets.md +++ b/aspnetcore/security/app-secrets.md @@ -192,7 +192,7 @@ Mapping an entire object literal to a POCO (a simple .NET class with properties) [!INCLUDE[secrets.json file](~/includes/app-secrets/secrets-json-file-and-text.md)] -To map the preceding secrets to a POCO, use the .NET Configuration API's [object graph binding](xref:fundamentals/configuration/index#boa) feature. The following code binds to a custom `MovieSettings` POCO and accesses the `ServiceApiKey` property value: +To map the preceding secrets to a POCO, use the .NET Configuration API's [object graph binding](xref:fundamentals/configuration/index#bind-an-array) feature. The following code binds to a custom `MovieSettings` POCO and accesses the `ServiceApiKey` property value: [!code-csharp[](~/security/app-secrets/samples/3.x/UserSecrets/Startup3.cs?name=snippet_BindToObjectGraph)] diff --git a/aspnetcore/security/app-secrets/includes/app-secrets-3-5.md b/aspnetcore/security/app-secrets/includes/app-secrets-3-5.md index a393059d94be..ce828378da89 100644 --- a/aspnetcore/security/app-secrets/includes/app-secrets-3-5.md +++ b/aspnetcore/security/app-secrets/includes/app-secrets-3-5.md @@ -163,7 +163,7 @@ Mapping an entire object literal to a POCO (a simple .NET class with properties) [!INCLUDE[secrets.json file](~/includes/app-secrets/secrets-json-file-and-text.md)] -To map the preceding secrets to a POCO, use the .NET Configuration API's [object graph binding](xref:fundamentals/configuration/index#boa) feature. The following code binds to a custom `MovieSettings` POCO and accesses the `ServiceApiKey` property value: +To map the preceding secrets to a POCO, use the .NET Configuration API's [object graph binding](xref:fundamentals/configuration/index#bind-an-array) feature. The following code binds to a custom `MovieSettings` POCO and accesses the `ServiceApiKey` property value: [!code-csharp[](~/security/app-secrets/samples/3.x/UserSecrets/Startup3.cs?name=snippet_BindToObjectGraph)] diff --git a/aspnetcore/security/key-vault-configuration.md b/aspnetcore/security/key-vault-configuration.md index 6b123ae04926..992d8058e8ea 100644 --- a/aspnetcore/security/key-vault-configuration.md +++ b/aspnetcore/security/key-vault-configuration.md @@ -288,7 +288,7 @@ When this approach is implemented: The provider can read configuration values into an array for binding to a POCO array. -When reading from a configuration source that allows keys to contain colon (`:`) separators, a numeric key segment is used to distinguish the keys that make up an array (`:0:`, `:1:`, … `:{n}:`). For more information, see [Configuration: Bind an array to a class](xref:fundamentals/configuration/index#boa). +When reading from a configuration source that allows keys to contain colon (`:`) separators, a numeric key segment is used to distinguish the keys that make up an array (`:0:`, `:1:`, … `:{n}:`). For more information, see [Configuration: Bind an array to a class](xref:fundamentals/configuration/index#bind-an-array). Azure Key Vault keys can't use a colon as a separator. The approach described in this article uses double dashes (`--`) as a separator for hierarchical values (sections). Array keys are stored in Azure Key Vault with double dashes and numeric key segments (`--0--`, `--1--`, … `--{n}--`). @@ -678,7 +678,7 @@ When this approach is implemented: The provider can read configuration values into an array for binding to a POCO array. -When reading from a configuration source that allows keys to contain colon (`:`) separators, a numeric key segment is used to distinguish the keys that make up an array (`:0:`, `:1:`, … `:{n}:`). For more information, see [Configuration: Bind an array to a class](xref:fundamentals/configuration/index#boa). +When reading from a configuration source that allows keys to contain colon (`:`) separators, a numeric key segment is used to distinguish the keys that make up an array (`:0:`, `:1:`, … `:{n}:`). For more information, see [Configuration: Bind an array to a class](xref:fundamentals/configuration/index#bind-an-array). Azure Key Vault keys can't use a colon as a separator. The approach described in this article uses double dashes (`--`) as a separator for hierarchical values (sections). Array keys are stored in Azure Key Vault with double dashes and numeric key segments (`--0--`, `--1--`, … `--{n}--`).