Permalink
Fetching contributors…
Cannot retrieve contributors at this time
1857 lines (1267 sloc) 73.6 KB
title author description ms.author ms.custom ms.date uid
Configuration in ASP.NET Core
guardrex
Learn how to use the Configuration API to configure an ASP.NET Core app.
riande
mvc
10/09/2018
fundamentals/configuration/index

Configuration in ASP.NET Core

By Luke Latham

App configuration in ASP.NET Core is based on key-value pairs established by configuration providers. Configuration providers read configuration data into key-value pairs from a variety of configuration sources:

::: moniker range=">= aspnetcore-2.1"

  • Azure Key Vault
  • Command-line arguments
  • Custom providers (installed or created)
  • Directory files
  • Environment variables
  • In-memory .NET objects
  • Settings files

::: moniker-end

::: moniker range="= aspnetcore-2.0 || aspnetcore-1.1"

  • Azure Key Vault
  • Command-line arguments
  • Custom providers (installed or created)
  • Environment variables
  • In-memory .NET objects
  • Settings files

::: moniker-end

::: moniker range="= aspnetcore-1.0"

  • Command-line arguments
  • Custom providers (installed or created)
  • Environment variables
  • In-memory .NET objects
  • Settings files

::: moniker-end

The options pattern is an extension of the configuration concepts described in this topic. Options uses classes to represent groups of related settings. For more information on using the options pattern, see xref:fundamentals/configuration/options.

View or download sample code (how to download)

The examples provided in this topic rely upon:

  • Setting the base path of the app with xref:Microsoft.Extensions.Configuration.FileConfigurationExtensions.SetBasePath*. SetBasePath is made available to an app by referencing the Microsoft.Extensions.Configuration.FileExtensions package.
  • Resolving sections of configuration files with xref:Microsoft.Extensions.Configuration.ConfigurationSection.GetSection*. GetSection is made available to an app by referencing the Microsoft.Extensions.Configuration package.
  • Binding configuration to .NET classes with xref:Microsoft.Extensions.Configuration.ConfigurationBinder.Bind* and Get<T>. Bind and Get<T> are made available to an app by referencing the Microsoft.Extensions.Configuration.Binder package. Get<T> is available in ASP.NET Core 1.1 or later.

::: moniker range=">= aspnetcore-2.1"

These three packages are included in the Microsoft.AspNetCore.App metapackage.

::: moniker-end

::: moniker range="= aspnetcore-2.0"

These three packages are included in the Microsoft.AspNetCore.All metapackage.

::: moniker-end

Host vs. 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 become part of the app's global configuration. For more information on how the configuration providers are used when the host is built and how configuration sources affect host configuration, see xref:fundamentals/host/index.

Security

Adopt the following best practices:

  • Never store passwords or other sensitive data in configuration provider code or in plain text configuration files.
  • 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.

Learn more about how to use multiple environments and managing the safe storage of app secrets in development with the Secret Manager (includes advice on using environment variables to store sensitive data). The Secret Manager uses the File Configuration Provider to store user secrets in a JSON file on the local system. The File Configuration Provider is described later in this topic.

Azure Key Vault is one option for the safe storage of app secrets. For more information, see xref:security/key-vault-configuration.

Hierarchical configuration data

The Configuration API is capable of maintaining hierarchical configuration data by flattening the hierarchical data with the use of a delimiter in the configuration keys.

In the following JSON file, four keys exist in a structured hierarchy of two sections:

{
  "section0": {
    "key0": "value",
    "key1": "value"
  },
  "section1": {
    "key0": "value",
    "key1": "value"
  }
}

When the file is read into configuration, unique keys are created to maintain the original hierarchical data structure of the configuration source. The sections and keys are flattened with the use of a colon (:) to maintain the original structure:

  • section0:key0
  • section0:key1
  • section1:key0
  • section1:key1

xref:Microsoft.Extensions.Configuration.ConfigurationSection.GetSection* and xref:Microsoft.Extensions.Configuration.IConfiguration.GetChildren* 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.

Conventions

At app startup, configuration sources are read in the order that their configuration providers are specified.

File Configuration Providers have the ability to reload configuration when an underlying settings file is changed after app startup. The File Configuration Provider is described later in this topic.

xref:Microsoft.Extensions.Configuration.IConfiguration is available in the app's Dependency Injection (DI) container. Configuration providers can't utilize DI, as it's not available when they're set up by the host.

Configuration keys adopt the following conventions:

  • Keys are case-insensitive. For example, ConnectionString and connectionstring are treated as equivalent keys.
  • If a value for the same key is set by the same or different configuration providers, the last value set on the key is the value used.
  • 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 converted to a colon.
    • In Azure Key Vault, hierarchical keys use -- (two dashes) as a separator. You must provide code to replace the dashes with a colon when the secrets are loaded into the app's configuration.
  • The xref:Microsoft.Extensions.Configuration.ConfigurationBinder supports binding arrays to objects using array indices in configuration keys. Array binding is described in the Bind an array to a class section.

Configuration values adopt the following conventions:

  • Values are strings.
  • Null values can't be stored in configuration or bound to objects.

Providers

The following table shows the configuration providers available to ASP.NET Core apps.

::: moniker range=">= aspnetcore-2.1"

Provider Provides configuration from…
Azure Key Vault Configuration Provider (Security topics) Azure Key Vault
Command-line Configuration Provider Command-line parameters
Custom configuration provider Custom source
Environment variables Configuration Provider Environment variables
File Configuration Provider Files (INI, JSON, XML)
Key-per-file Configuration Provider Directory files
Memory Configuration Provider In-memory collections
User secrets (Secret Manager) (Security topics) File in the user profile directory

::: moniker-end

::: moniker range="= aspnetcore-2.0 || aspnetcore-1.1"

Provider Provides configuration from…
Azure Key Vault Configuration Provider (Security topics) Azure Key Vault
Command-line Configuration Provider Command-line parameters
Custom configuration provider Custom source
Environment variables Configuration Provider Environment variables
File Configuration Provider Files (INI, JSON, XML)
Memory Configuration Provider In-memory collections
User secrets (Secret Manager) (Security topics) File in the user profile directory

::: moniker-end

::: moniker range="= aspnetcore-1.0"

Provider Provides configuration from…
Command-line Configuration Provider Command-line parameters
Custom configuration provider Custom source
Environment variables Configuration Provider Environment variables
File Configuration Provider Files (INI, JSON, XML)
Memory Configuration Provider In-memory collections
User secrets (Secret Manager) (Security topics) File in the user profile directory

::: moniker-end

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

A typical sequence of configuration providers is:

  1. Files (appsettings.json, appsettings.{Environment}.json, where {Environment} is the app's current hosting environment)
  2. Azure Key Vault
  3. User secrets (Secret Manager) (in the Development environment only)
  4. Environment variables
  5. Command-line arguments

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

::: moniker range=">= aspnetcore-2.0"

This sequence of providers is put into place when you initialize a new xref:Microsoft.AspNetCore.Hosting.WebHostBuilder with xref:Microsoft.AspNetCore.WebHost.CreateDefaultBuilder*. For more information, see Web Host: Set up a host.

::: moniker-end

::: moniker range="< aspnetcore-2.0"

This sequence of providers can be created for the app (not the host) with a xref:Microsoft.Extensions.Configuration.ConfigurationBuilder and a call to its xref:Microsoft.Extensions.Configuration.ConfigurationBuilder.Build* method in Startup:

public Startup(IHostingEnvironment env)
{
    var builder = new ConfigurationBuilder()
        .SetBasePath(Directory.GetCurrentDirectory())
        .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
        .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, 
            reloadOnChange: true);

    var appAssembly = Assembly.Load(new AssemblyName(env.ApplicationName));

    if (appAssembly != null)
    {
        builder.AddUserSecrets(appAssembly, optional: true);
    }

    builder.AddEnvironmentVariables();

    Configuration = builder.Build();
}

public IConfiguration Configuration { get; }

public void ConfigureServices(IServiceCollection services)
{
    services.AddSingleton<IConfiguration>(Configuration);
}

In the preceding example, the environment name (env.EnvironmentName) and app assembly name (env.ApplicationName) are provided by the xref:Microsoft.Extensions.Hosting.IHostingEnvironment. For more information, see xref:fundamentals/environments.

::: moniker-end

::: moniker range=">= aspnetcore-2.1"

ConfigureAppConfiguration

Call xref:Microsoft.Extensions.Hosting.HostBuilder.ConfigureAppConfiguration* when building the Web Host to specify the app's configuration providers in addition to those added automatically by xref:Microsoft.AspNetCore.WebHost.CreateDefaultBuilder*:

[!code-csharp]

::: moniker-end

Command-line Configuration Provider

The xref:Microsoft.Extensions.Configuration.CommandLine.CommandLineConfigurationProvider loads configuration from command-line argument key-value pairs at runtime.

To activate command-line configuration, the xref:Microsoft.Extensions.Configuration.CommandLineConfigurationExtensions.AddCommandLine* extension method is called on an instance of xref:Microsoft.Extensions.Configuration.ConfigurationBuilder.

::: moniker range=">= aspnetcore-2.0"

AddCommandLine is automatically called when you initialize a new xref:Microsoft.AspNetCore.Hosting.WebHostBuilder with xref:Microsoft.AspNetCore.WebHost.CreateDefaultBuilder*. For more information, see Web Host: Set up a host.

CreateDefaultBuilder also loads:

  • Optional configuration from appsettings.json and appsettings.{Environment}.json.
  • User secrets (Secret Manager) (in the Development environment).
  • Environment variables.

CreateDefaultBuilder adds the Command-line Configuration Provider last. Command-line arguments passed at runtime override configuration set by the other providers.

CreateDefaultBuilder acts when the host is constructed. Therefore, command-line configuration activated by CreateDefaultBuilder can affect how the host is configured.

::: moniker-end

::: moniker range=">= aspnetcore-2.1"

Call xref:Microsoft.Extensions.Hosting.HostBuilder.ConfigureAppConfiguration* when building the host to specify the app's configuration.

AddCommandLine has already been called by CreateDefaultBuilder. If you need to provide app configuration and still be able to override that configuration with command-line arguments, call the app's additional providers in xref:Microsoft.Extensions.Hosting.HostBuilder.ConfigureAppConfiguration* and call AddCommandLine last.

public class Program
{
    public static void Main(string[] args)
    {
        CreateWebHostBuilder(args).Build().Run();
    }

    public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
        WebHost.CreateDefaultBuilder(args)
            .ConfigureAppConfiguration((hostingContext, config) =>
            {
                // Call other providers here and call AddCommandLine last.
                config.AddCommandLine(args)
            })
            .UseStartup<Startup>();
}

When creating a xref:Microsoft.AspNetCore.Hosting.WebHostBuilder directly, call xref:Microsoft.AspNetCore.Hosting.HostingAbstractionsWebHostBuilderExtensions.UseConfiguration* with the configuration:

::: moniker-end

::: moniker range="= aspnetcore-2.0"

Apply the configuration to xref:Microsoft.AspNetCore.Hosting.WebHostBuilder with the xref:Microsoft.AspNetCore.Hosting.HostingAbstractionsWebHostBuilderExtensions.UseConfiguration* method.

AddCommandLine has already been called by CreateDefaultBuilder when UseConfiguration is called. If you need to provide app configuration and still be able to override that configuration with command-line arguments, call the app's additional providers on a ConfigurationBuilder and call AddCommandLine last.

public class Program
{
    public static void Main(string[] args)
    {
        CreateWebHostBuilder(args).Build().Run();
    }

    public static IWebHostBuilder CreateWebHostBuilder(string[] args)
    {
        var config = new ConfigurationBuilder()
            // Call other providers here and call AddCommandLine last.
            .AddCommandLine(args)
            .Build();

        return WebHost.CreateDefaultBuilder(args)
            .UseConfiguration(config)
            .UseStartup<Startup>();
    }
}

When creating a xref:Microsoft.AspNetCore.Hosting.WebHostBuilder directly, call xref:Microsoft.AspNetCore.Hosting.HostingAbstractionsWebHostBuilderExtensions.UseConfiguration* with the configuration:

::: moniker-end

::: moniker range="< aspnetcore-2.0"

To activate command-line configuration, call the xref:Microsoft.Extensions.Configuration.CommandLineConfigurationExtensions.AddCommandLine* extension method on an instance of xref:Microsoft.Extensions.Configuration.ConfigurationBuilder.

Call the provider last to allow the command-line arguments passed at runtime to override configuration set by other configuration providers.

Apply the configuration to xref:Microsoft.AspNetCore.Hosting.WebHostBuilder with the xref:Microsoft.AspNetCore.Hosting.HostingAbstractionsWebHostBuilderExtensions.UseConfiguration* method:

::: moniker-end

var config = new ConfigurationBuilder()
    // Call additional providers here as needed.
    // Call AddCommandLine last to allow arguments to override other configuration.
    .AddCommandLine(args)
    .Build();

var host = new WebHostBuilder()
    .UseConfiguration(config)
    .UseKestrel()
    .UseStartup<Startup>();

Example

::: moniker range=">= aspnetcore-2.0"

The 2.x sample app takes advantage of the static convenience method CreateDefaultBuilder to build the host, which includes a call to xref:Microsoft.Extensions.Configuration.CommandLineConfigurationExtensions.AddCommandLine*.

::: moniker-end

::: moniker range="< aspnetcore-2.0"

The 1.x sample app calls xref:Microsoft.Extensions.Configuration.CommandLineConfigurationExtensions.AddCommandLine* on a xref:Microsoft.Extensions.Configuration.ConfigurationBuilder.

::: moniker-end

  1. Open a command prompt in the project's directory.
  2. Supply a command-line argument to the dotnet run command, dotnet run CommandLineKey=CommandLineValue.
  3. After the app is running, open a browser to the app at http://localhost:5000.
  4. Observe that the output contains the key-value pair for the configuration command-line argument provided to dotnet run.

Arguments

The value must follow an equals sign (=), or the key must have a prefix (-- or /) when the value follows a space. The value can be null if an equals sign is used (for example, CommandLineKey=).

Key prefix Example
No prefix CommandLineKey1=value1
Two dashes (--) --CommandLineKey2=value2, --CommandLineKey2 value2
Forward slash (/) /CommandLineKey3=value3, /CommandLineKey3 value3

Within the same command, don't mix command-line argument key-value pairs that use an equals sign with key-value pairs that use a space.

Example commands:

dotnet run CommandLineKey1=value --CommandLineKey2=value /CommandLineKey2=value
dotnet run --CommandLineKey1 value /CommandLineKey2 value
dotnet run CommandLineKey1= CommandLineKey2=value

Switch mappings

Switch mappings allow key name replacement logic. When you manually build configuration with a xref:Microsoft.Extensions.Configuration.ConfigurationBuilder, you can provide a dictionary of switch replacements to the xref:Microsoft.Extensions.Configuration.CommandLineConfigurationExtensions.AddCommandLine* 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 (the key replacement) 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 a dash (-) or double-dash (--).
  • The switch mappings dictionary must not contain duplicate keys.

::: moniker range=">= aspnetcore-2.1"

Call xref:Microsoft.Extensions.Hosting.HostBuilder.ConfigureAppConfiguration* when building the host to specify the app's configuration:

public class Program
{
    public static readonly Dictionary<string, string> _switchMappings = 
        new Dictionary<string, string>
        {
            { "-CLKey1", "CommandLineKey1" },
            { "-CLKey2", "CommandLineKey2" }
        };

    public static void Main(string[] args)
    {
        CreateWebHostBuilder(args).Build().Run();
    }

    // Do not pass the args to CreateDefaultBuilder
    public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
        WebHost.CreateDefaultBuilder()
            .ConfigureAppConfiguration((hostingContext, config) =>
            {
                config.AddCommandLine(args, _switchMappings)
            })
            .UseStartup<Startup>();
}

As shown in the preceding example, the call to CreateDefaultBuilder shouldn't pass arguments when switch mappings are used. CreateDefaultBuilder method's AddCommandLine call doesn't include mapped switches, and there's no way to pass the switch mapping dictionary to CreateDefaultBuilder. If the arguments include a mapped switch and are passed to CreateDefaultBuilder, its AddCommandLine provider fails to initialize with a xref:System.FormatException. 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.

::: moniker-end

::: moniker range="= aspnetcore-2.0"

public class Program
{
    public static void Main(string[] args)
    {
        CreateWebHostBuilder(args).Build().Run();
    }

    public static IWebHostBuilder CreateWebHostBuilder(string[] args)
    {
        var switchMappings = new Dictionary<string, string>
            {
                { "-CLKey1", "CommandLineKey1" },
                { "-CLKey2", "CommandLineKey2" }
            };

        var config = new ConfigurationBuilder()
            .AddCommandLine(args, switchMappings)
            .Build();

        // Do not pass the args to CreateDefaultBuilder
        return WebHost.CreateDefaultBuilder()
            .UseConfiguration(config)
            .UseStartup<Startup>();
    }
}

As shown in the preceding example, the call to CreateDefaultBuilder shouldn't pass arguments when switch mappings are used. CreateDefaultBuilder method's AddCommandLine call doesn't include mapped switches, and there's no way to pass the switch mapping dictionary to CreateDefaultBuilder. If the arguments include a mapped switch and are passed to CreateDefaultBuilder, its AddCommandLine provider fails to initialize with a xref:System.FormatException. 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.

::: moniker-end

::: moniker range="< aspnetcore-2.0"

public static void Main(string[] args)
{
    var switchMappings = new Dictionary<string, string>
        {
            { "-CLKey1", "CommandLineKey1" },
            { "-CLKey2", "CommandLineKey2" }
        };

    var config = new ConfigurationBuilder()
        .AddCommandLine(args, switchMappings)
        .Build();

    var host = new WebHostBuilder()
        .UseConfiguration(config)
        .UseKestrel()
        .UseStartup<Startup>()
        .Start();

    using (host)
    {
        Console.ReadLine();
    }
}

::: moniker-end

After the switch mappings dictionary is created, it contains the data shown in the following table.

Key Value
-CLKey1 CommandLineKey1
-CLKey2 CommandLineKey2

If the switch-mapped keys are used when starting the app, configuration receives the configuration value on the key supplied by the dictionary:

dotnet run -CLKey1=value1 -CLKey2=value2

After running the preceding command, configuration contains the values shown in the following table.

Key Value
CommandLineKey1 value1
CommandLineKey2 value2

Environment Variables Configuration Provider

The xref:Microsoft.Extensions.Configuration.EnvironmentVariables.EnvironmentVariablesConfigurationProvider loads configuration from environment variable key-value pairs at runtime.

To activate environment variables configuration, call the xref:Microsoft.Extensions.Configuration.EnvironmentVariablesExtensions.AddEnvironmentVariables* extension method on an instance of xref:Microsoft.Extensions.Configuration.ConfigurationBuilder.

When working with hierarchical keys in environment variables, a colon separator (:) may not work on all platforms. A double underscore (__) is supported by all platforms and is replaced by a colon.

Azure App Service permits you to set environment variables in the Azure Portal that can override app configuration using the Environment Variables Configuration Provider. For more information, see Azure Apps: Override app configuration using the Azure Portal.

::: moniker range=">= aspnetcore-2.0"

AddEnvironmentVariables is automatically called when you initialize a new xref:Microsoft.AspNetCore.Hosting.WebHostBuilder with xref:Microsoft.AspNetCore.WebHost.CreateDefaultBuilder*. For more information, see Web Host: Set up a host.

CreateDefaultBuilder also loads:

  • Optional configuration from appsettings.json and appsettings.{Environment}.json.
  • User secrets (Secret Manager) (in the Development environment).
  • Command-line arguments.

The Environment Variable Configuration Provider is called after configuration is established from user secrets and appsettings files. Calling the provider in this position allows the environment variables read at runtime to override configuration set by user secrets and appsettings files.

::: moniker-end

::: moniker range=">= aspnetcore-2.1"

Call xref:Microsoft.Extensions.Hosting.HostBuilder.ConfigureAppConfiguration* when building the host to specify the app's configuration.

AddEnvironmentVariables for environment variables prefixed with ASPNETCORE_ has already been called by CreateDefaultBuilder. If you need to provide app configuration from additional environment variables, call the app's additional providers in xref:Microsoft.Extensions.Hosting.HostBuilder.ConfigureAppConfiguration* and call AddEnvironmentVariables with the prefix.

public class Program
{
    public static void Main(string[] args)
    {
        CreateWebHostBuilder(args).Build().Run();
    }

    public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
        WebHost.CreateDefaultBuilder(args)
            .ConfigureAppConfiguration((hostingContext, config) =>
            {
                // Call additional providers here as needed.
                // Call AddEnvironmentVariables last if you need to allow environment
                // variables to override values from other providers.
                config.AddEnvironmentVariables(prefix: "PREFIX_")
            })
            .UseStartup<Startup>();
}

When creating a xref:Microsoft.AspNetCore.Hosting.WebHostBuilder directly, call xref:Microsoft.AspNetCore.Hosting.HostingAbstractionsWebHostBuilderExtensions.UseConfiguration* with the configuration:

::: moniker-end

::: moniker range="= aspnetcore-2.0"

Call the AddEnvironmentVariables extension method on an instance of xref:Microsoft.Extensions.Configuration.ConfigurationBuilder. Apply the configuration to xref:Microsoft.AspNetCore.Hosting.WebHostBuilder with the xref:Microsoft.AspNetCore.Hosting.HostingAbstractionsWebHostBuilderExtensions.UseConfiguration* method.

AddEnvironmentVariables for environment variables prefixed with ASPNETCORE_ has already been called by CreateDefaultBuilder. If you need to provide app configuration from additional environment variables, call the app's additional providers in xref:Microsoft.Extensions.Hosting.HostBuilder.ConfigureAppConfiguration* and call AddEnvironmentVariables with the prefix.

public class Program
{
    public static void Main(string[] args)
    {
        CreateWebHostBuilder(args).Build().Run();
    }

    public static IWebHostBuilder CreateWebHostBuilder(string[] args)
    {
        var config = new ConfigurationBuilder()
            // Call additional providers here as needed.
            // Call AddEnvironmentVariables last if you need to allow environment
            // variables to override values from other providers.
            .AddEnvironmentVariables(prefix: "PREFIX_")
            .Build();

        return WebHost.CreateDefaultBuilder(args)
            .UseConfiguration(config)
            .UseStartup<Startup>();
    }
}

When creating a xref:Microsoft.AspNetCore.Hosting.WebHostBuilder directly, call xref:Microsoft.AspNetCore.Hosting.HostingAbstractionsWebHostBuilderExtensions.UseConfiguration* with the configuration:

::: moniker-end

::: moniker range="< aspnetcore-2.0"

Apply the configuration to xref:Microsoft.AspNetCore.Hosting.WebHostBuilder with the xref:Microsoft.AspNetCore.Hosting.HostingAbstractionsWebHostBuilderExtensions.UseConfiguration* method:

::: moniker-end

var config = new ConfigurationBuilder()
    .AddEnvironmentVariables()
    .Build();

var host = new WebHostBuilder()
    .UseConfiguration(config)
    .UseKestrel()
    .UseStartup<Startup>();

Example

::: moniker range=">= aspnetcore-2.0"

The 2.x sample app takes advantage of the static convenience method CreateDefaultBuilder to build the host, which includes a call to AddEnvironmentVariables.

::: moniker-end

::: moniker range="< aspnetcore-2.0"

The 1.x sample app calls AddEnvironmentVariables on a ConfigurationBuilder.

::: moniker-end

  1. Run the sample app. Open a browser to the app at http://localhost:5000.
  2. Observe that the output contains the key-value pair for the environment variable ENVIRONMENT. The value reflects the environment in which the app is running, typically Development when running locally.

To keep the list of environment variables rendered by the app short, the app filters environment variables to those that start with the following:

  • ASPNETCORE_
  • urls
  • Logging
  • ENVIRONMENT
  • contentRoot
  • AllowedHosts
  • applicationName
  • CommandLine

::: moniker range=">= aspnetcore-2.0"

If you wish to expose all of the environment variables available to the app, change the FilteredConfiguration in Pages/Index.cshtml.cs to the following:

::: moniker-end

::: moniker range="< aspnetcore-2.0"

If you wish to expose all of the environment variables available to the app, change the FilteredConfiguration in Controllers/HomeController.cs to the following:

::: moniker-end

FilteredConfiguration = _config.AsEnumerable();

Prefixes

Environment variables loaded into the app's configuration are filtered when you supply a prefix to the AddEnvironmentVariables method. For example, to filter environment variables on the prefix CUSTOM_, supply the prefix to the configuration provider:

var config = new ConfigurationBuilder()
    .AddEnvironmentVariables("CUSTOM_")
    .Build();

The prefix is stripped off when the configuration key-value pairs are created.

::: moniker range=">= aspnetcore-2.0"

The static convenience method CreateDefaultBuilder creates a xref:Microsoft.AspNetCore.Hosting.WebHostBuilder to establish the app's host. When WebHostBuilder is created, it finds its host configuration in environment variables prefixed with ASPNETCORE_.

::: moniker-end

Connection string prefixes

The Configuration API has special processing rules for four connection string environment variables involved in configuring Azure connection strings for the app environment. Environment variables with the prefixes shown in the table are loaded into the app if no prefix is supplied to AddEnvironmentVariables.

Connection string prefix Provider
CUSTOMCONNSTR_ Custom provider
MYSQLCONNSTR_ MySQL
SQLAZURECONNSTR_ Azure SQL Database
SQLCONNSTR_ 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

xref:Microsoft.Extensions.Configuration.FileConfigurationProvider is the base class for loading configuration from the file system. The following configuration providers are dedicated to specific file types:

INI Configuration Provider

The xref:Microsoft.Extensions.Configuration.Ini.IniConfigurationProvider loads configuration from INI file key-value pairs at runtime.

To activate INI file configuration, call the xref:Microsoft.Extensions.Configuration.IniConfigurationExtensions.AddIniFile* extension method on an instance of xref:Microsoft.Extensions.Configuration.ConfigurationBuilder.

The colon can be used to as a section delimiter in INI file configuration.

Overloads permit specifying:

  • Whether the file is optional.
  • Whether the configuration is reloaded if the file changes.
  • The xref:Microsoft.Extensions.FileProviders.IFileProvider used to access the file.

::: moniker range=">= aspnetcore-2.1"

Call xref:Microsoft.Extensions.Hosting.HostBuilder.ConfigureAppConfiguration* when building the host to specify the app's configuration:

public class Program
{
    public static void Main(string[] args)
    {
        CreateWebHostBuilder(args).Build().Run();
    }

    public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
        WebHost.CreateDefaultBuilder(args)
            .ConfigureAppConfiguration((hostingContext, config) =>
            {
                config.SetBasePath(Directory.GetCurrentDirectory());
                config.AddIniFile("config.ini", optional: true, reloadOnChange: true)
            })
            .UseStartup<Startup>();
}

When creating a xref:Microsoft.AspNetCore.Hosting.WebHostBuilder directly, call xref:Microsoft.AspNetCore.Hosting.HostingAbstractionsWebHostBuilderExtensions.UseConfiguration* with the configuration:

::: moniker-end

::: moniker range="= aspnetcore-2.0"

When calling CreateDefaultBuilder, call xref:Microsoft.AspNetCore.Hosting.HostingAbstractionsWebHostBuilderExtensions.UseConfiguration* with the configuration:

public class Program
{
    public static void Main(string[] args)
    {
        CreateWebHostBuilder(args).Build().Run();
    }

    public static IWebHostBuilder CreateWebHostBuilder(string[] args)
    {
        var config = new ConfigurationBuilder()
            .SetBasePath(Directory.GetCurrentDirectory())
            .AddIniFile("config.ini", optional: true, reloadOnChange: true)
            .Build();

        return WebHost.CreateDefaultBuilder(args)
            .UseConfiguration(config)
            .UseStartup<Startup>();
    }
}

When creating a xref:Microsoft.AspNetCore.Hosting.WebHostBuilder directly, call xref:Microsoft.AspNetCore.Hosting.HostingAbstractionsWebHostBuilderExtensions.UseConfiguration* with the configuration:

::: moniker-end

::: moniker range="< aspnetcore-2.0"

Apply the configuration to xref:Microsoft.AspNetCore.Hosting.WebHostBuilder with the xref:Microsoft.AspNetCore.Hosting.HostingAbstractionsWebHostBuilderExtensions.UseConfiguration* method:

::: moniker-end

var config = new ConfigurationBuilder()
    .SetBasePath(Directory.GetCurrentDirectory())
    .AddIniFile("config.ini", optional: true, reloadOnChange: true)
    .Build();

var host = new WebHostBuilder()
    .UseConfiguration(config)
    .UseKestrel()
    .UseStartup<Startup>();

A generic example of an INI configuration file:

[section0]
key0=value
key1=value

[section1]
subsection:key=value

[section2:subsection0]
key=value

[section2:subsection1]
key=value

The previous configuration file loads the following keys with value:

  • section0:key0
  • section0:key1
  • section1:subsection:key
  • section2:subsection0:key
  • section2:subsection1:key

JSON Configuration Provider

The xref:Microsoft.Extensions.Configuration.Json.JsonConfigurationProvider loads configuration from JSON file key-value pairs during runtime.

To activate JSON file configuration, call the xref:Microsoft.Extensions.Configuration.JsonConfigurationExtensions.AddJsonFile* extension method on an instance of xref:Microsoft.Extensions.Configuration.ConfigurationBuilder.

Overloads permit specifying:

  • Whether the file is optional.
  • Whether the configuration is reloaded if the file changes.
  • The xref:Microsoft.Extensions.FileProviders.IFileProvider used to access the file.

::: moniker range=">= aspnetcore-2.0"

AddJsonFile is automatically called twice when you initialize a new xref:Microsoft.AspNetCore.Hosting.WebHostBuilder with xref:Microsoft.AspNetCore.WebHost.CreateDefaultBuilder*. The method is called to load configuration from:

  • appsettings.json – This file is read first. The environment version of the file can override the values provided by the appsettings.json file.
  • appsettings.{Environment}.json – The environment version of the file is loaded based on the IHostingEnvironment.EnvironmentName.

For more information, see Web Host: Set up a host.

CreateDefaultBuilder also loads:

  • Environment variables.
  • User secrets (Secret Manager) (in the Development environment).
  • Command-line arguments.

The JSON Configuration Provider is established first. Therefore, user secrets, environment variables, and command-line arguments override configuration set by the appsettings files.

::: moniker-end

::: moniker range=">= aspnetcore-2.1"

Call xref:Microsoft.Extensions.Hosting.HostBuilder.ConfigureAppConfiguration* when building the host to specify the app's configuration for files other than appsettings.json and appsettings.{Environment}.json:

public class Program
{
    public static void Main(string[] args)
    {
        CreateWebHostBuilder(args).Build().Run();
    }

    public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
        WebHost.CreateDefaultBuilder(args)
            .ConfigureAppConfiguration((hostingContext, config) =>
            {
                config.SetBasePath(Directory.GetCurrentDirectory());
                config.AddJsonFile("config.json", optional: true, reloadOnChange: true)
            })
            .UseStartup<Startup>();
}

When creating a xref:Microsoft.AspNetCore.Hosting.WebHostBuilder directly, call xref:Microsoft.AspNetCore.Hosting.HostingAbstractionsWebHostBuilderExtensions.UseConfiguration* with the configuration:

::: moniker-end

::: moniker range="= aspnetcore-2.0"

You can also directly call the AddJsonFile extension method on an instance of xref:Microsoft.Extensions.Configuration.ConfigurationBuilder.

When calling CreateDefaultBuilder, call xref:Microsoft.AspNetCore.Hosting.HostingAbstractionsWebHostBuilderExtensions.UseConfiguration* with the configuration:

public class Program
{
    public static void Main(string[] args)
    {
        CreateWebHostBuilder(args).Build().Run();
    }

    public static IWebHostBuilder CreateWebHostBuilder(string[] args)
    {
        var config = new ConfigurationBuilder()
            .SetBasePath(Directory.GetCurrentDirectory())
            .AddJsonFile("config.json", optional: true, reloadOnChange: true)
            .Build();

        return WebHost.CreateDefaultBuilder(args)
            .UseConfiguration(config)
            .UseStartup<Startup>();
    }
}

When creating a xref:Microsoft.AspNetCore.Hosting.WebHostBuilder directly, call xref:Microsoft.AspNetCore.Hosting.HostingAbstractionsWebHostBuilderExtensions.UseConfiguration* with the configuration:

::: moniker-end

::: moniker range="< aspnetcore-2.0"

Apply the configuration to xref:Microsoft.AspNetCore.Hosting.WebHostBuilder with the xref:Microsoft.AspNetCore.Hosting.HostingAbstractionsWebHostBuilderExtensions.UseConfiguration* method:

::: moniker-end

var config = new ConfigurationBuilder()
    .SetBasePath(Directory.GetCurrentDirectory())
    .AddJsonFile("config.json", optional: true, reloadOnChange: true)
    .Build();

var host = new WebHostBuilder()
    .UseConfiguration(config)
    .UseKestrel()
    .UseStartup<Startup>();

Example

::: moniker range=">= aspnetcore-2.0"

The 2.x sample app takes advantage of the static convenience method CreateDefaultBuilder to build the host, which includes two calls to AddJsonFile. Configuration is loaded from appsettings.json and appsettings.{Environment}.json.

::: moniker-end

::: moniker range="< aspnetcore-2.0"

The 1.x sample app calls AddJsonFile twice on a ConfigurationBuilder. Configuration is loaded from appsettings.json and appsettings.{Environment}.json.

::: moniker-end

  1. Run the sample app. Open a browser to the app at http://localhost:5000.
  2. Observe that the output contains key-value pairs for the configuration shown in the table depending on the environment. Logging configuration keys use the colon (:) as a hierarchical separator.
Key Development Value Production Value
Logging:LogLevel:System Information Information
Logging:LogLevel:Microsoft Information Information
Logging:LogLevel:Default Debug Error
AllowedHosts * *

XML Configuration Provider

The xref:Microsoft.Extensions.Configuration.Xml.XmlConfigurationProvider loads configuration from XML file key-value pairs at runtime.

To activate XML file configuration, call the xref:Microsoft.Extensions.Configuration.XmlConfigurationExtensions.AddXmlFile* extension method on an instance of xref:Microsoft.Extensions.Configuration.ConfigurationBuilder.

Overloads permit specifying:

  • Whether the file is optional.
  • Whether the configuration is reloaded if the file changes.
  • The xref:Microsoft.Extensions.FileProviders.IFileProvider used to access the file.

The root node of the configuration file is ignored when the configuration key-value pairs are created. Don't specify a Document Type Definition (DTD) or namespace in the file.

::: moniker range=">= aspnetcore-2.1"

Call xref:Microsoft.Extensions.Hosting.HostBuilder.ConfigureAppConfiguration* when building the host to specify the app's configuration:

public class Program
{
    public static void Main(string[] args)
    {
        CreateWebHostBuilder(args).Build().Run();
    }

    public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
        WebHost.CreateDefaultBuilder(args)
            .ConfigureAppConfiguration((hostingContext, config) =>
            {
                config.SetBasePath(Directory.GetCurrentDirectory());
                config.AddXmlFile("config.xml", optional: true, reloadOnChange: true)
            })
            .UseStartup<Startup>();
}

When creating a xref:Microsoft.AspNetCore.Hosting.WebHostBuilder directly, call xref:Microsoft.AspNetCore.Hosting.HostingAbstractionsWebHostBuilderExtensions.UseConfiguration* with the configuration:

::: moniker-end

::: moniker range="= aspnetcore-2.0"

When calling CreateDefaultBuilder, call xref:Microsoft.AspNetCore.Hosting.HostingAbstractionsWebHostBuilderExtensions.UseConfiguration* with the configuration:

public class Program
{
    public static void Main(string[] args)
    {
        CreateWebHostBuilder(args).Build().Run();
    }

    public static IWebHostBuilder CreateWebHostBuilder(string[] args)
    {
        var config = new ConfigurationBuilder()
            .SetBasePath(Directory.GetCurrentDirectory())
            .AddXmlFile("config.xml", optional: true, reloadOnChange: true)
            .Build();

        return WebHost.CreateDefaultBuilder(args)
            .UseConfiguration(config)
            .UseStartup<Startup>();
    }
}

When creating a xref:Microsoft.AspNetCore.Hosting.WebHostBuilder directly, call xref:Microsoft.AspNetCore.Hosting.HostingAbstractionsWebHostBuilderExtensions.UseConfiguration* with the configuration:

::: moniker-end

::: moniker range="< aspnetcore-2.0"

Apply the configuration to xref:Microsoft.AspNetCore.Hosting.WebHostBuilder with the xref:Microsoft.AspNetCore.Hosting.HostingAbstractionsWebHostBuilderExtensions.UseConfiguration* method:

::: moniker-end

var config = new ConfigurationBuilder()
    .SetBasePath(Directory.GetCurrentDirectory())
    .AddXmlFile("config.xml", optional: true, reloadOnChange: true)
    .Build();

var host = new WebHostBuilder()
    .UseConfiguration(config)
    .UseKestrel()
    .UseStartup<Startup>();

XML configuration files can use distinct element names for repeating sections:

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
  <section0>
    <key0>value</key0>
    <key1>value</key1>
  </section0>
  <section1>
    <key0>value</key0>
    <key1>value</key1>
  </section1>
</configuration>

The previous configuration file loads the following keys with value:

  • section0:key0
  • section0:key1
  • section1:key0
  • section1:key1

Repeating elements that use the same element name work if the name attribute is used to distinguish the elements:

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
  <section name="section0">
    <key name="key0">value</key>
    <key name="key1">value</key>
  </section>
  <section name="section1">
    <key name="key0">value</key>
    <key name="key1">value</key>
  </section>
</configuration>

The previous configuration file loads the following keys with value:

  • section:section0🔑key0
  • section:section0🔑key1
  • section:section1🔑key0
  • section:section1🔑key1

Attributes can be used to supply values:

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
  <key attribute="value" />
  <section>
    <key attribute="value" />
  </section>
</configuration>

The previous configuration file loads the following keys with value:

  • key:attribute
  • section🔑attribute

::: moniker range=">= aspnetcore-2.1"

Key-per-file Configuration Provider

The xref:Microsoft.Extensions.Configuration.KeyPerFile.KeyPerFileConfigurationProvider 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 xref:Microsoft.Extensions.Configuration.KeyPerFileConfigurationBuilderExtensions.AddKeyPerFile* extension method on an instance of xref:Microsoft.Extensions.Configuration.ConfigurationBuilder. The directoryPath to the files must be an absolute path.

Overloads permit specifying:

  • An Action<KeyPerFileConfigurationSource> delegate that configures the source.
  • Whether the directory is optional and the path to the directory.

Call xref:Microsoft.Extensions.Hosting.HostBuilder.ConfigureAppConfiguration* when building the host to specify the app's configuration:

public class Program
{
    public static void Main(string[] args)
    {
        CreateWebHostBuilder(args).Build().Run();
    }

    public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
        WebHost.CreateDefaultBuilder(args)
            .ConfigureAppConfiguration((hostingContext, config) =>
            {
                config.SetBasePath(Directory.GetCurrentDirectory());
                config.AddKeyPerFile(directoryPath: path, optional: true)
            })
            .UseStartup<Startup>();
}

When creating a xref:Microsoft.AspNetCore.Hosting.WebHostBuilder directly, call xref:Microsoft.AspNetCore.Hosting.HostingAbstractionsWebHostBuilderExtensions.UseConfiguration* with the configuration:

var path = Path.Combine(Directory.GetCurrentDirectory(), "path/to/files");
var config = new ConfigurationBuilder()
    .AddKeyPerFile(directoryPath: path, optional: true)
    .Build();

var host = new WebHostBuilder()
    .UseConfiguration(config)
    .UseKestrel()
    .UseStartup<Startup>();

::: moniker-end

Memory Configuration Provider

The xref:Microsoft.Extensions.Configuration.Memory.MemoryConfigurationProvider uses an in-memory collection as configuration key-value pairs.

To activate in-memory collection configuration, call the xref:Microsoft.Extensions.Configuration.MemoryConfigurationBuilderExtensions.AddInMemoryCollection* extension method on an instance of xref:Microsoft.Extensions.Configuration.ConfigurationBuilder.

The configuration provider can be initialized with an IEnumerable<KeyValuePair<String,String>>.

::: moniker range=">= aspnetcore-2.1"

Call xref:Microsoft.Extensions.Hosting.HostBuilder.ConfigureAppConfiguration* when building the host to specify the app's configuration:

public class Program
{
    public static readonly Dictionary<string, string> _dict = 
        new Dictionary<string, string>
        {
            {"MemoryCollectionKey1", "value1"},
            {"MemoryCollectionKey2", "value2"}
        };

    public static void Main(string[] args)
    {
        CreateWebHostBuilder(args).Build().Run();
    }

    public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
        WebHost.CreateDefaultBuilder(args)
            .ConfigureAppConfiguration((hostingContext, config) =>
            {
                config.AddInMemoryCollection(_dict)
            })
            .UseStartup<Startup>();
}

When creating a xref:Microsoft.AspNetCore.Hosting.WebHostBuilder directly, call xref:Microsoft.AspNetCore.Hosting.HostingAbstractionsWebHostBuilderExtensions.UseConfiguration* with the configuration:

::: moniker-end

::: moniker range="= aspnetcore-2.0"

When calling CreateDefaultBuilder, call xref:Microsoft.AspNetCore.Hosting.HostingAbstractionsWebHostBuilderExtensions.UseConfiguration* with the configuration:

public class Program
{
    public static void Main(string[] args)
    {
        CreateWebHostBuilder(args).Build().Run();
    }

    public static IWebHostBuilder CreateWebHostBuilder(string[] args)
    {
        var dict = new Dictionary<string, string>
            {
                {"MemoryCollectionKey1", "value1"},
                {"MemoryCollectionKey2", "value2"}
            };

        var config = new ConfigurationBuilder()
            .AddInMemoryCollection(dict)
            .Build();

        return WebHost.CreateDefaultBuilder(args)
            .UseConfiguration(config)
            .UseStartup<Startup>();
    }
}

When creating a xref:Microsoft.AspNetCore.Hosting.WebHostBuilder directly, call xref:Microsoft.AspNetCore.Hosting.HostingAbstractionsWebHostBuilderExtensions.UseConfiguration* with the configuration:

::: moniker-end

::: moniker range="< aspnetcore-2.0"

Apply the configuration to xref:Microsoft.AspNetCore.Hosting.WebHostBuilder with the xref:Microsoft.AspNetCore.Hosting.HostingAbstractionsWebHostBuilderExtensions.UseConfiguration* method:

::: moniker-end

var dict = new Dictionary<string, string>
    {
        {"MemoryCollectionKey1", "value1"},
        {"MemoryCollectionKey2", "value2"}
    };

var config = new ConfigurationBuilder()
    .AddInMemoryCollection(dict)
    .Build();

var host = new WebHostBuilder()
    .UseConfiguration(config)
    .UseKestrel()
    .UseStartup<Startup>();

GetValue

ConfigurationBinder.GetValue<T> extracts a value from configuration with a specified key and converts it to the specified type. An overload permits you to provide a default value if the key isn't found.

The following example extracts the string value from configuration with the key NumberKey, types the value as an int, and stores the value in the variable intValue. If NumberKey isn't found in the configuration keys, intValue receives the default value of 99:

var intValue = config.GetValue<int>("NumberKey", 99);

GetSection, GetChildren, and Exists

For the examples that follow, consider the following JSON file. Four keys are found across two sections, one of which includes a pair of subsections:

{
  "section0": {
    "key0": "value",
    "key1": "value"
  },
  "section1": {
    "key0": "value",
    "key1": "value"
  },
  "section2": {
    "subsection0" : {
      "key0": "value",
      "key1": "value"
    },
    "subsection1" : {
      "key0": "value",
      "key1": "value"
    }
  }
}

When the file is read into configuration, the following unique hierarchical keys are created to hold the configuration values:

  • section0:key0
  • section0:key1
  • section1:key0
  • section1:key1
  • section2:subsection0:key0
  • section2:subsection0:key1
  • section2:subsection1:key0
  • section2:subsection1:key1

GetSection

IConfiguration.GetSection extracts a configuration subsection with the specified subsection key.

To return an xref:Microsoft.Extensions.Configuration.IConfigurationSection containing only the key-value pairs in section1, call GetSection and supply the section name:

var configSection = _config.GetSection("section1");

Similarly, to obtain the values for keys in section2:subsection0, call GetSection and supply the section path:

var configSection = _config.GetSection("section2:subsection0");

GetSection never returns null. If a matching section isn't found, an empty IConfigurationSection is returned.

GetChildren

A call to IConfiguration.GetChildren on section2 obtains an IEnumerable<IConfigurationSection> that includes:

  • subsection0
  • subsection1
var configSection = _config.GetSection("section2");

var children = configSection.GetChildren();

::: moniker range=">= aspnetcore-2.0"

Exists

Use ConfigurationExtensions.Exists to determine if a configuration section exists:

var sectionExists = _config.GetSection("section2:subsection2").Exists();

Given the example data, sectionExists is false because there isn't a section2:subsection2 section in the configuration data.

::: moniker-end

Bind to a class

Configuration can be bound to classes that represent groups of related settings using the options pattern. For more information, see xref:fundamentals/configuration/options.

Configuration values are returned as strings, but calling xref:Microsoft.Extensions.Configuration.ConfigurationBinder.Bind* enables the construction of POCO objects.

The sample app contains a Starship model (Models/Starship.cs):

::: moniker range=">= aspnetcore-2.0"

[!code-csharp]

::: moniker-end

::: moniker range="< aspnetcore-2.0"

[!code-csharp]

::: moniker-end

The starship section of the starship.json file creates the configuration when the sample app uses the JSON Configuration Provider to load the configuration:

::: moniker range=">= aspnetcore-2.0"

[!code-json]

::: moniker-end

::: moniker range="< aspnetcore-2.0"

[!code-json]

::: moniker-end

The following configuration key-value pairs are created:

Key Value
starship:name USS Enterprise
starship:registry NCC-1701
starship:class Constitution
starship:length 304.8
starship:commissioned False
trademark Paramount Pictures Corp. http://www.paramount.com

The sample app calls GetSection with the starship key. The starship key-value pairs are isolated. The Bind method is called on the subsection passing in an instance of the Starship class. After binding the instance values, the instance is assigned to a property for rendering:

::: moniker range=">= aspnetcore-2.0"

[!code-csharp]

::: moniker-end

::: moniker range="< aspnetcore-2.0"

[!code-csharp]

::: moniker-end

Bind to an object graph

xref:Microsoft.Extensions.Configuration.ConfigurationBinder.Bind* is capable of binding an entire POCO object graph.

The sample contains a TvShow model whose object graph includes Metadata and Actors classes (Models/TvShow.cs):

::: moniker range=">= aspnetcore-2.0"

[!code-csharp]

::: moniker-end

::: moniker range="< aspnetcore-2.0"

[!code-csharp]

::: moniker-end

The sample app has a tvshow.xml file containing the configuration data:

::: moniker range=">= aspnetcore-2.0"

[!code-xml]

::: moniker-end

::: moniker range="< aspnetcore-2.0"

[!code-xml]

::: moniker-end

Configuration is bound to the entire TvShow object graph with the Bind method. The bound instance is assigned to a property for rendering:

::: moniker range=">= aspnetcore-2.0"

var tvShow = new TvShow();
_config.GetSection("tvshow").Bind(tvShow);
TvShow = tvShow;

::: moniker-end

::: moniker range="< aspnetcore-2.0"

var tvShow = new TvShow();
_config.GetSection("tvshow").Bind(tvShow);
viewModel.TvShow = tvShow;

::: moniker-end

::: moniker range=">= aspnetcore-1.1"

ConfigurationBinder.Get<T> binds and returns the specified type. Get<T> is more convenient than using Bind. The following code shows how to use Get<T> with the preceding example, which allows the bound instance to be directly assigned to the property used for rendering:

::: moniker-end

::: moniker range=">= aspnetcore-2.0"

[!code-csharp]

::: moniker-end

::: moniker range="= aspnetcore-1.1"

[!code-csharp]

::: moniker-end

Bind an array to a class

The sample app demonstrates the concepts explained in this section.

The xref:Microsoft.Extensions.Configuration.ConfigurationBinder.Bind* supports binding arrays to objects using array indices in configuration keys. Any array format that exposes a numeric key segment (:0:, :1:, … :{n}:) is capable of array binding to a POCO class array.

[!NOTE] Binding is provided by convention. Custom configuration providers aren't required to implement array binding.

In-memory array processing

Consider the configuration keys and values shown in the following table.

Key Value
array:0 value0
array:1 value1
array:2 value2
array:4 value4
array:5 value5

These keys and values are loaded in the sample app using the Memory Configuration Provider:

::: moniker range=">= aspnetcore-2.0"

[!code-csharp]

::: moniker-end

::: moniker range="< aspnetcore-2.0"

[!code-csharp]

::: moniker-end

The array skips a value for index #3. The configuration binder isn't capable of binding null values or creating null entries in bound objects, which becomes clear in a moment when the result of binding this array to an object is demonstrated.

In the sample app, a POCO class is available to hold the bound configuration data:

::: moniker range=">= aspnetcore-2.0"

[!code-csharp]

::: moniker-end

::: moniker range="< aspnetcore-2.0"

[!code-csharp]

::: moniker-end

The configuration data is bound to the object:

var arrayExample = new ArrayExample();
_config.GetSection("array").Bind(arrayExample);

::: moniker range=">= aspnetcore-1.1"

ConfigurationBinder.Get<T> syntax can also be used, which results in more compact code:

::: moniker-end

::: moniker range=">= aspnetcore-2.0"

[!code-csharp]

::: moniker-end

::: moniker range="= aspnetcore-1.1"

[!code-csharp]

::: moniker-end

The bound object, an instance of ArrayExample, receives the array data from configuration.

ArrayExamples.Entries Index ArrayExamples.Entries Value
0 value0
1 value1
2 value2
3 value4
4 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 merely 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 ArrayExamples instance by any configuration provider that produces the correct key-value pair in configuration. If the sample included an additional JSON Configuration Provider with the missing key-value pair, the ArrayExamples.Entries matches the complete configuration array:

missing_value.json:

{
  "array:entries:3": "value3"
}

::: moniker range=">= aspnetcore-2.0"

In xref:Microsoft.Extensions.Hosting.HostBuilder.ConfigureAppConfiguration*:

config.AddJsonFile("missing_value.json", optional: false, reloadOnChange: false);

::: moniker-end

::: moniker range="< aspnetcore-2.0"

In the Startup constructor:

.AddJsonFile("missing_value.json", optional: false, reloadOnChange: false);

::: moniker-end

The key-value pair shown in the table is loaded into configuration.

Key Value
array:entries:3 value3

If the ArrayExamples class instance is bound after the JSON Configuration Provider includes the entry for index #3, the ArrayExamples.Entries array includes the value.

ArrayExamples.Entries Index ArrayExamples.Entries Value
0 value0
1 value1
2 value2
3 value3
4 value4
5 value5

JSON array processing

If a JSON file contains an array, configuration keys are created for the array elements with a zero-based section index. In the following configuration file, subsection is an array:

::: moniker range=">= aspnetcore-2.0"

[!code-json]

::: moniker-end

::: moniker range="< aspnetcore-2.0"

[!code-json]

::: moniker-end

The JSON Configuration Provider reads the configuration data into the following key-value pairs:

Key Value
json_array:key valueA
json_array:subsection:0 valueB
json_array:subsection:1 valueC
json_array:subsection:2 valueD

In the sample app, the following POCO class is available to bind the configuration key-value pairs:

::: moniker range=">= aspnetcore-2.0"

[!code-csharp]

::: moniker-end

::: moniker range="< aspnetcore-2.0"

[!code-csharp]

::: moniker-end

After binding, JsonArrayExample.Key holds the value valueA. The subsection values are stored in the POCO array property, Subsection.

JsonArrayExample.Subsection Index JsonArrayExample.Subsection Value
0 valueB
1 valueC
2 valueD

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).

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:

::: moniker range=">= aspnetcore-2.0"

[!code-csharp]

::: moniker-end

::: moniker range="< aspnetcore-2.0"

[!code-csharp]

::: moniker-end

Add an EFConfigurationContext to store and access the configured values.

EFConfigurationProvider/EFConfigurationContext.cs:

::: moniker range=">= aspnetcore-2.0"

[!code-csharp]

::: moniker-end

::: moniker range="< aspnetcore-2.0"

[!code-csharp]

::: moniker-end

Create a class that implements xref:Microsoft.Extensions.Configuration.IConfigurationSource.

EFConfigurationProvider/EFConfigurationSource.cs:

::: moniker range=">= aspnetcore-2.0"

[!code-csharp]

::: moniker-end

::: moniker range="< aspnetcore-2.0"

[!code-csharp]

::: moniker-end

Create the custom configuration provider by inheriting from xref:Microsoft.Extensions.Configuration.ConfigurationProvider. The configuration provider initializes the database when it's empty.

EFConfigurationProvider/EFConfigurationProvider.cs:

::: moniker range=">= aspnetcore-2.0"

[!code-csharp]

::: moniker-end

::: moniker range="< aspnetcore-2.0"

[!code-csharp]

::: moniker-end

An AddEFConfiguration extension method permits adding the configuration source to a ConfigurationBuilder.

Extensions/EntityFrameworkExtensions.cs:

::: moniker range=">= aspnetcore-2.0"

[!code-csharp]

::: moniker-end

::: moniker range="< aspnetcore-2.0"

[!code-csharp]

::: moniker-end

The following code shows how to use the custom EFConfigurationProvider in Program.cs:

::: moniker range=">= aspnetcore-2.0"

[!code-csharp]

::: moniker-end

::: moniker range="< aspnetcore-2.0"

[!code-csharp]

::: moniker-end

Access configuration during startup

Inject IConfiguration into the Startup constructor to access configuration values in Startup.ConfigureServices. To access configuration in Startup.Configure, either inject IConfiguration directly into the method or use the instance from the constructor:

public class Startup
{
    private readonly IConfiguration _config;

    public Startup(IConfiguration config)
    {
        _config = config;
    }

    public void ConfigureServices(IServiceCollection services)
    {
        var value = _config["key"];
    }

    public void Configure(IApplicationBuilder app, IConfiguration config)
    {
        var value = config["key"];
    }
}

For an example of accessing configuration using startup convenience methods, see App startup: Convenience methods.

Access configuration in a Razor Pages page or MVC view

To access configuration settings in a Razor Pages page or an MVC view, add a using directive (C# reference: using directive) for the Microsoft.Extensions.Configuration namespace and inject xref:Microsoft.Extensions.Configuration.IConfiguration into the page or view.

In a Razor Pages page:

@page
@model IndexModel
@using Microsoft.Extensions.Configuration
@inject IConfiguration Configuration

<!DOCTYPE html>
<html lang="en">
<head>
    <title>Index Page</title>
</head>
<body>
    <h1>Access configuration in a Razor Pages page</h1>
    <p>Configuration value for 'key': @Configuration["key"]</p>
</body>
</html>

In an MVC view:

@using Microsoft.Extensions.Configuration
@inject IConfiguration Configuration

<!DOCTYPE html>
<html lang="en">
<head>
    <title>Index View</title>
</head>
<body>
    <h1>Access configuration in an MVC view</h1>
    <p>Configuration value for 'key': @Configuration["key"]</p>
</body>
</html>

Add configuration from an external assembly

An xref:Microsoft.AspNetCore.Hosting.IHostingStartup implementation allows adding enhancements to an app at startup from an external assembly outside of the app's Startup class. For more information, see xref:fundamentals/configuration/platform-specific-configuration.

Additional resources