ASP.NET Core 中的配置Configuration in ASP.NET Core

作者:Rick AndersonKirk LarkinBy Rick Anderson and Kirk Larkin

ASP.NET Core 中的配置是使用一个或多个配置提供程序执行的。Configuration in ASP.NET Core is performed using one or more configuration providers. 配置提供程序使用各种配置源从键值对读取配置数据:Configuration providers read configuration data from key-value pairs using a variety of configuration sources:

  • 设置文件,例如 appsettings.jsonSettings files, such as appsettings.json
  • 环境变量Environment variables
  • Azure Key VaultAzure Key Vault
  • Azure 应用程序配置Azure App Configuration
  • 命令行参数Command-line arguments
  • 已安装或已创建的自定义提供程序Custom providers, installed or created
  • 目录文件Directory files
  • 内存中的 .NET 对象In-memory .NET objects

查看或下载示例代码如何下载View or download sample code (how to download)

默认配置Default configuration

通过 dotnet new 或 Visual Studio 创建的 ASP.NET Core Web 应用会生成以下代码:ASP.NET Core web apps created with dotnet new or Visual Studio generate the following code:

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

    public static IHostBuilder CreateHostBuilder(string[] args) =>
        Host.CreateDefaultBuilder(args)
            .ConfigureWebHostDefaults(webBuilder =>
            {
                webBuilder.UseStartup<Startup>();
            });
}

CreateDefaultBuilder 按照以下顺序为应用提供默认配置:CreateDefaultBuilder provides default configuration for the app in the following order:

  1. ChainedConfigurationProvider:添加现有 IConfiguration 作为源。ChainedConfigurationProvider : Adds an existing IConfiguration as a source. 在默认配置示例中,添加主机配置,并将它设置为应用配置的第一个源。In the default configuration case, adds the host configuration and setting it as the first source for the app configuration.
  2. 使用 JSON 配置提供程序通过 appsettings.json 提供。appsettings.json using the JSON configuration provider.
  3. 使用 JSON 配置提供程序通过 appsettings.Environment.json 提供 。appsettings.Environment.json using the JSON configuration provider. 例如,appsettings.Production.json 和 appsettings.Development.json 。For example, appsettings.Production.json and appsettings.Development.json.
  4. 应用在 Development 环境中运行时的应用机密App secrets when the app runs in the Development environment.
  5. 使用环境变量配置提供程序通过环境变量提供。Environment variables using the Environment Variables configuration provider.
  6. 使用命令行配置提供程序通过命令行参数提供。Command-line arguments using the Command-line configuration provider.

后来添加的配置提供程序会替代之前的密钥设置。Configuration providers that are added later override previous key settings. 例如,如果在 appsettings.json 和环境中设置了 MyKey,则会使用环境值。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 overrides all other providers.

若要详细了解 CreateDefaultBuilder,请参阅默认生成器设置For more information on CreateDefaultBuilder, see Default builder settings.

以下代码按添加顺序显示了已启用的配置提供程序:The following code displays the enabled configuration providers in the order they were added:

public class Index2Model : PageModel
{
    private IConfigurationRoot ConfigRoot;

    public Index2Model(IConfiguration configRoot)
    {
        ConfigRoot = (IConfigurationRoot)configRoot;
    }

    public ContentResult OnGet()
    {           
        string str = "";
        foreach (var provider in ConfigRoot.Providers.ToList())
        {
            str += provider.ToString() + "\n";
        }

        return Content(str);
    }
}

appsettings.jsonappsettings.json

请考虑使用以下 appsettings.json 文件:Consider the following appsettings.json file:

{
    "Position": {
        "Title": "编辑器",
        "Name": "Joe Smith"
    },
    "MyKey": "My appsettings.json Value",
    "Logging": {
        "LogLevel": {
            "Default": "Information",
            "Microsoft": "Warning",
            "Microsoft.Hosting.Lifetime": "Information"
        }
    },
    "AllowedHosts": "*"
}

以下来自示例下载的代码显示了上述的一些配置设置:The following code from the sample download displays several of the preceding configurations settings:

public class TestModel : PageModel
{
    // requires using Microsoft.Extensions.Configuration;
    private readonly IConfiguration Configuration;

    public TestModel(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public ContentResult OnGet()
    {
        var myKeyValue = Configuration["MyKey"];
        var title = Configuration["Position:Title"];
        var name = Configuration["Position:Name"];
        var defaultLogLevel = Configuration["Logging:LogLevel:Default"];


        return Content($"MyKey value: {myKeyValue} \n" +
                       $"Title: {title} \n" +
                       $"Name: {name} \n" +
                       $"Default Log Level: {defaultLogLevel}");
    }
}

默认的 JsonConfigurationProvider 会按以下顺序加载配置:The default JsonConfigurationProvider loads configuration in the following order:

  1. appsettings.jsonappsettings.json
  2. appsettings.Environment.json :例如,appsettings.Production.json 和 appsettings.Development.json 文件。appsettings.Environment.json : For example, the appsettings.Production.json and appsettings.Development.json files. 文件的环境版本是根据 IHostingEnvironment.EnvironmentName 加载的。The environment version of the file is loaded based on the IHostingEnvironment.EnvironmentName. 有关详细信息,请参阅 在 ASP.NET Core 中使用多个环境For more information, see 在 ASP.NET Core 中使用多个环境.

appsettings.Environment.json 值将替代 appsettings.json 中的密钥 。appsettings.Environment.json values override keys in appsettings.json. 例如,默认情况下:For example, by default:

  • 在开发环境中,appsettings.Development.json 配置将覆盖在 appsettings.json 中找到的值 。In development, appsettings.Development.json configuration overwrites values found in appsettings.json.
  • 在生产环境中,appsettings.Production.json 配置将覆盖在 appsettings.json 中找到的值 。In production, appsettings.Production.json configuration overwrites values found in appsettings.json. 例如,在将应用部署到 Azure 时。For example, when deploying the app to Azure.

使用选项模式绑定分层配置数据Bind hierarchical configuration data using the options pattern

读取相关配置值的首选方法是使用选项模式The preferred way to read related configuration values is using the options pattern. 例如,若要读取以下配置值,请执行以下操作:For example, to read the following configuration values:

  "Position": {
    "Title": "Editor",
    "Name": "Joe Smith"
  }

创建以下 PositionOptions 类:Create the following PositionOptions class:

public class PositionOptions
{
    public const string Position = "Position";

    public string Title { get; set; }
    public string Name { get; set; }
}

选项类: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. 在上面的代码中,Position 未绑定。In the preceding code, Position is not bound. 由于使用了 Position 属性,因此在将类绑定到配置提供程序时,不需要在应用中对字符串 "Position" 进行硬编码。The Position property 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:

  • 调用 ConfigurationBinder.BindPositionOptions 类绑定到 Position 部分。Calls ConfigurationBinder.Bind to bind the PositionOptions class to the Position section.
  • 显示 Position 配置数据。Displays the Position configuration data.
public class Test22Model : PageModel
{
    private readonly IConfiguration Configuration;

    public Test22Model(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public ContentResult OnGet()
    {
        var positionOptions = new PositionOptions();
        Configuration.GetSection(PositionOptions.Position).Bind(positionOptions);

        return Content($"Title: {positionOptions.Title} \n" +
                       $"Name: {positionOptions.Name}");
    }
}

在上面的代码中,默认读取在应用启动后对 JSON 配置文件所做的更改。In the preceding code, by default, changes to the JSON configuration file after the app has started are read.

ConfigurationBinder.Get<T> 绑定并返回指定的类型。ConfigurationBinder.Get<T> binds and returns the specified type. 使用 ConfigurationBinder.Get<T> 可能比使用 ConfigurationBinder.Bind 更方便。ConfigurationBinder.Get<T> may be more convenient than using ConfigurationBinder.Bind. 下面的代码演示如何将 ConfigurationBinder.Get<T>PositionOptions 类配合使用:The following code shows how to use ConfigurationBinder.Get<T> with the PositionOptions class:

public class Test21Model : PageModel
{
    private readonly IConfiguration Configuration;
    public PositionOptions positionOptions { get; private set; }

    public Test21Model(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public ContentResult OnGet()
    {            
        positionOptions = Configuration.GetSection(PositionOptions.Position)
                                                     .Get<PositionOptions>();

        return Content($"Title: {positionOptions.Title} \n" +
                       $"Name: {positionOptions.Name}");
    }
}

在上面的代码中,默认读取在应用启动后对 JSON 配置文件所做的更改。In the preceding code, by default, changes to the JSON configuration file after the app has started are read.

使用选项模式时的替代方法是绑定 Position 部分并将它添加到依赖项注入服务容器An alternative approach when using the options pattern is to bind the Position section and add it to the dependency injection service container. 在以下代码中,PositionOptions 已通过 Configure 被添加到了服务容器并已绑定到了配置:In the following code, PositionOptions is added to the service container with Configure and bound to configuration:

public void ConfigureServices(IServiceCollection services)
{
    services.Configure<PositionOptions>(Configuration.GetSection(
                                        PositionOptions.Position));
    services.AddRazorPages();
}

通过使用前面的代码,以下代码将读取位置选项:Using the preceding code, the following code reads the position options:

public class Test2Model : PageModel
{
    private readonly PositionOptions _options;

    public Test2Model(IOptions<PositionOptions> options)
    {
        _options = options.Value;
    }

    public ContentResult OnGet()
    {
        return Content($"Title: {_options.Title} \n" +
                       $"Name: {_options.Name}");
    }
}

在上面的代码中,不会读取在应用启动后对 JSON 配置文件所做的更改。In the preceding code, changes to the JSON configuration file after the app has started are not read. 若要读取在应用启动后的更改,请使用 IOptionsSnapshotTo read changes after the app has started, use IOptionsSnapshot.

使用默认配置,会通过 reloadOnChange: true 启用 appsettings.json 和 appsettings.Environment.json 文件 。Using the default configuration, the appsettings.json and appsettings.Environment.json files are enabled with reloadOnChange: true. 应用启动后,对 appsettings.json 和 appsettings.Environment.json 文件做出的更改将由 JSON 配置提供程序读取 。Changes made to the appsettings.json and appsettings.Environment.json file after the app starts are read by the JSON configuration provider.

有关添加其他 JSON 配置文件的信息,请参阅本文档中的 JSON 配置提供程序See JSON configuration provider in this document for information on adding additional JSON configuration files.

安全和机密管理器Security and secret manager

配置数据指南:Configuration data guidelines:

  • 请勿在配置提供程序代码或纯文本配置文件中存储密码或其他敏感数据。Never store passwords or other sensitive data in configuration provider code or in plain text configuration files. 机密管理器可用于存储开发环境中的机密。The Secret manager 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.

默认情况下机密管理器会在 appsettings.json 和 appsettings.Environment.json 之后读取配置设置 。By default, Secret manager reads configuration settings after appsettings.json and appsettings.Environment.json.

有关存储密码或其他敏感数据的详细信息:For more information on storing passwords or other sensitive data:

Azure Key Vault 安全存储 ASP.NET Core 应用的应用机密。Azure Key Vault safely stores app secrets for ASP.NET Core apps. 有关详细信息,请参阅 <xref:security/key-vault-configuration>。For more information, see <xref:security/key-vault-configuration>.

环境变量Environment variables

使用默认配置,EnvironmentVariablesConfigurationProvider 会在读取 appsettings.json、appsettings.Environment.json 和机密管理器后从环境变量键值对加载配置 。Using the default configuration, the EnvironmentVariablesConfigurationProvider loads configuration from environment variable key-value pairs after reading appsettings.json, appsettings.Environment.json, and Secret manager. 因此,从环境中读取的键值会替代从 appsettings.json、appsettings.Environment.json 和机密管理器中读取的值 。Therefore, key values read from the environment override values read from appsettings.json, appsettings.Environment.json, and Secret manager.

所有平台上的环境变量分层键都不支持 : 分隔符。The : separator doesn't work with environment variable hierarchical keys on all platforms. __(双下划线):__, the double underscore, is:

  • 受所有平台支持。Supported by all platforms. 例如,Bash 不支持 : 分隔符,但支持 __For example, the : separator is not supported by Bash, but __ is.
  • 自动替换为 :Automatically replaced by a :

以下 set 命令:The following set commands:

  • 在 Windows 上设置上述示例的环境键和值。Set the environment keys and values of the preceding example on Windows.
  • 在使用示例下载时测试设置。Test the settings when using the sample download. dotnet run 命令必须在项目目录中运行。The dotnet run command must be run in the project directory.
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.
  • 不会由通过 Visual Studio 启动的浏览器读取。Won't be read by browsers launched with Visual Studio.

以下 setx 命令可用于在 Windows 上设置环境键和值。The following setx commands can be used to set the environment keys and values on Windows. set 不同,setx 设置是持久的。Unlike set, setx settings are persisted. /M 在系统环境中设置变量。/M sets the variable in the system environment. 如果未使用 /M 开关,则会设置用户环境变量。If the /M switch isn't used, a user environment variable is set.

setx MyKey "My key from setx Environment" /M
setx Position__Title Setx_Environment_Editor /M
setx Position__Name Environment_Rick /M

测试前面的命令是否会替代 appsettings.json 和 appsettings.Environment.json: To test that the preceding commands override appsettings.json and appsettings.Environment.json:

  • 使用 Visual Studio:退出并重启 Visual Studio。With Visual Studio: Exit and restart Visual Studio.
  • 使用 CLI:启动新的命令窗口并输入 dotnet runWith the CLI: Start a new command window and enter dotnet run.

使用字符串调用 AddEnvironmentVariables 以指定环境变量的前缀:Call AddEnvironmentVariables with a string to specify a prefix for environment variables:

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

    public static IHostBuilder CreateHostBuilder(string[] args) =>
        Host.CreateDefaultBuilder(args)
            .ConfigureAppConfiguration((hostingContext, config) =>
            {
                config.AddEnvironmentVariables(prefix: "MyCustomPrefix_");
            })
            .ConfigureWebHostDefaults(webBuilder =>
            {
                webBuilder.UseStartup<Startup>();
            });
}

在上述代码中:In the preceding code:

前缀会在读取配置键值对时被去除。The prefix is stripped off when the configuration key-value pairs are read.

以下命令对自定义前缀进行测试:The following commands test the custom prefix:

set MyCustomPrefix_MyKey="My key with MyCustomPrefix_ Environment"
set MyCustomPrefix_Position__Title=Editor_with_customPrefix
set MyCustomPrefix_Position__Name=Environment_Rick_cp
dotnet run

默认配置会加载前缀为 DOTNET_ASPNETCORE_ 的环境变量和命令行参数。The default configuration loads environment variables and command line arguments prefixed with DOTNET_ and ASPNETCORE_. DOTNET_ASPNETCORE_ 前缀会由 ASP.NET Core 用于主机和应用配置,但不用于用户配置。The DOTNET_ and ASPNETCORE_ prefixes are used by ASP.NET Core for host and app configuration, but not for user configuration. 有关主机和应用配置的详细信息,请参阅 .NET 通用主机For more information on host and app configuration, see .NET Generic Host.

Azure 应用服务上,选择“设置”>“配置”页面上的“新应用程序设置” 。On Azure App Service, select New application setting on the Settings > Configuration page. Azure 应用服务应用程序设置:Azure App Service application settings are:

  • 已静态加密且通过加密的通道进行传输。Encrypted at rest and transmitted over an encrypted channel.
  • 已作为环境变量公开。Exposed as environment variables.

有关详细信息,请参阅 Azure 应用:使用 Azure 门户替代应用配置For more information, see Azure Apps: Override app configuration using the Azure Portal.

有关 Azure 数据库连接字符串的信息,请参阅连接字符串前缀See Connection string prefixes for information on Azure database connection strings.

命令行Command-line

使用默认配置,CommandLineConfigurationProvider 会从以下配置源后的命令行参数键值对中加载配置:Using the default configuration, the CommandLineConfigurationProvider loads configuration from command-line argument key-value pairs after the following configuration sources:

默认情况下,在命令行上设置的配置值会替代通过所有其他配置提供程序设置的配置值。By 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 =:

dotnet run MyKey="My key from command line" Position:Title=Cmd Position:Name=Cmd_Rick

以下命令使用 / 设置键和值:The following command sets keys and values using /:

dotnet run /MyKey "Using /" /Position:Title=Cmd_ /Position:Name=Cmd_Rick

以下命令使用 -- 设置键和值:The following command sets keys and values using --:

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. 例如 MySetting=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. 提供针对 AddCommandLine 方法的交换替换字典。Provide a dictionary of switch replacements to the 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 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.

若要使用交换映射字典,请将它传递到对 AddCommandLine 的调用中:To use a switch mappings dictionary, pass it into the call to AddCommandLine:

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

    public static IHostBuilder CreateHostBuilder(string[] args)
    {
        var switchMappings = new Dictionary<string, string>()
         {
             { "-k1", "key1" },
             { "-k2", "key2" },
             { "--alt3", "key3" },
             { "--alt4", "key4" },
             { "--alt5", "key5" },
             { "--alt6", "key6" },
         };

        return Host.CreateDefaultBuilder(args)
            .ConfigureAppConfiguration((hostingContext, config) =>
            {
                config.AddCommandLine(args, switchMappings);
            })
            .ConfigureWebHostDefaults(webBuilder =>
            {
                webBuilder.UseStartup<Startup>();
            });
    }
}

下面的代码显示了替换后的键的键值:The following code shows the key values for the replaced keys:

public class Test3Model : PageModel
{
    private readonly IConfiguration Config;

    public Test3Model(IConfiguration configuration)
    {
        Config = configuration;
    }

    public ContentResult OnGet()
    {
        return Content(
                $"Key1: '{Config["Key1"]}'\n" +
                $"Key2: '{Config["Key2"]}'\n" +
                $"Key3: '{Config["Key3"]}'\n" +
                $"Key4: '{Config["Key4"]}'\n" +
                $"Key5: '{Config["Key5"]}'\n" +
                $"Key6: '{Config["Key6"]}'");
    }
}

运行以下命令以测试键替换:Run the following command to test the key replacement:

dotnet run -k1=value1 -k2 value2 --alt3=value2 /alt4=value3 --alt5 value5 /alt6 value6

注意:目前,= 不能用于设置带有单划线 - 的键替换值。Note: Currently, = cannot be used to set key-replacement values with a single dash -. 请参阅此 GitHub 问题See this GitHub issue.

以下命令可用于测试键替换:The following command works to test key replacement:

dotnet run -k1 value1 -k2 value2 --alt3=value2 /alt4=value3 --alt5 value5 /alt6 value6

对于使用交换映射的应用,调用 CreateDefaultBuilder 不应传递参数。For apps that use switch mappings, the call to CreateDefaultBuilder shouldn't pass arguments. CreateDefaultBuilder 方法的 AddCommandLine 调用不包括映射的交换,并且无法将交换映射字典传递给 CreateDefaultBuilderThe CreateDefaultBuilder method's AddCommandLine call doesn't include mapped switches, and there's no way to pass the switch-mapping dictionary to CreateDefaultBuilder. 解决方案不是将参数传递给 CreateDefaultBuilder,而是允许 ConfigurationBuilder 方法的 AddCommandLine 方法处理参数和交换映射字典。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.

分层配置数据Hierarchical configuration data

配置 API 在配置键中使用分隔符来展平分层数据,以此来读取分层配置数据。The Configuration API reads hierarchical configuration data by flattening the hierarchical data with the use of a delimiter in the configuration keys.

示例下载包含以下 appsettings.json 文件:The sample download contains the following appsettings.json file:

{
    "Position": {
        "Title": "编辑器",
        "Name": "Joe Smith"
    },
    "MyKey": "My appsettings.json Value",
    "Logging": {
        "LogLevel": {
            "Default": "Information",
            "Microsoft": "Warning",
            "Microsoft.Hosting.Lifetime": "Information"
        }
    },
    "AllowedHosts": "*"
}

以下来自示例下载的代码显示了一些配置设置:The following code from the sample download displays several of the configurations settings:

public class TestModel : PageModel
{
    // requires using Microsoft.Extensions.Configuration;
    private readonly IConfiguration Configuration;

    public TestModel(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public ContentResult OnGet()
    {
        var myKeyValue = Configuration["MyKey"];
        var title = Configuration["Position:Title"];
        var name = Configuration["Position:Name"];
        var defaultLogLevel = Configuration["Logging:LogLevel:Default"];


        return Content($"MyKey value: {myKeyValue} \n" +
                       $"Title: {title} \n" +
                       $"Name: {name} \n" +
                       $"Default Log Level: {defaultLogLevel}");
    }
}

读取分层配置数据的首选方法是使用选项模式。The preferred way to read hierarchical configuration data is using the options pattern. 有关详细信息,请参阅本文档中的绑定分层配置数据For more information, see Bind hierarchical configuration data in this document.

GetSectionGetChildren 方法可用于隔离各个节和配置数据中某节的子节。GetSection and GetChildren methods are available to isolate sections and children of a section in the configuration data. 稍后将在 GetSection、GetChildren 和 Exists 中介绍这些方法。These methods are described later in GetSection, GetChildren, and Exists.

配置键和值Configuration keys and values

配置键:Configuration keys:

  • 不区分大小写。Are case-insensitive. 例如,ConnectionStringconnectionstring 被视为等效键。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.
  • 分层键Hierarchical keys
    • 在配置 API 中,冒号分隔符 (:) 适用于所有平台。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 :.
    • 在 Azure Key Vault 中,分层键使用 -- 作为分隔符。In Azure Key Vault, hierarchical keys use -- as a separator. 当机密加载到应用的配置中时,Azure Key Vault 配置提供程序 会自动将 -- 替换为 :The Azure Key Vault configuration provider automatically replaces -- with a : when the secrets are loaded into the app's configuration.
  • ConfigurationBinder 支持使用配置键中的数组索引将数组绑定到对象。The 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:

  • 为字符串。Are strings.
  • NULL 值不能存储在配置中或绑定到对象。Null values can't be stored in configuration or bound to objects.

配置提供程序Configuration providers

下表显示了 ASP.NET Core 应用可用的配置提供程序。The following table shows the configuration providers available to ASP.NET Core apps.

| 提供程序Provider | 通过以下对象提供配置Provides configuration from | | --- title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'
  • 'Identity''Identity'
  • 'Let's Encrypt''Let's Encrypt'
  • 'Razor''Razor'
  • 'SignalR' uid:'SignalR' uid:

---- | --- title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:---- | --- title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'
  • 'Identity''Identity'
  • 'Let's Encrypt''Let's Encrypt'
  • 'Razor''Razor'
  • 'SignalR' uid:'SignalR' uid:

------------------ | | Azure Key Vault 配置提供程序 | Azure Key Vault | | Azure 应用程序配置提供程序 | Azure 应用程序配置 | | 命令行配置提供程序 | 命令行参数 | | 自定义配置提供程序 | 自定义源 | | 环境变量配置提供程序 | 环境变量 | | 文件配置提供程序 | INI、JSON 和 XML 文件 | | 每文件密钥配置提供程序 | 目录文件 | | 内存配置提供程序 | 内存中集合 | | 机密管理器 | 用户配置文件目录中的文件 |------------------ | | Azure Key Vault configuration provider | Azure Key Vault | | Azure App configuration provider | Azure App Configuration | | Command-line configuration provider | Command-line parameters | | Custom configuration provider | Custom source | | Environment Variables configuration provider | Environment variables | | File configuration provider | INI, JSON, and XML files | | Key-per-file configuration provider | Directory files | | Memory configuration provider | In-memory collections | | Secret Manager | 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.jsonappsettings.json
  2. appsettings.Environment.json appsettings.Environment.json
  3. 机密管理器Secret Manager
  4. 使用环境变量配置提供程序通过环境变量提供。Environment variables using the Environment Variables configuration provider.
  5. 使用命令行配置提供程序通过命令行参数提供。Command-line arguments using the Command-line configuration provider.

通常的做法是将命令行配置提供程序添加到一系列提供程序的末尾,使命令行参数能够替代由其他提供程序设置的配置。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.

连接字符串前缀Connection string prefixes

对于四个连接字符串环境变量,配置 API 具有特殊的处理规则。The Configuration API has special processing rules for four connection string environment variables. 这些连接字符串涉及了为应用环境配置 Azure 连接字符串。These connection strings are involved in configuring Azure connection strings for the app environment. 使用默认配置或没有向 AddEnvironmentVariables 应用前缀时,具有表中所示前缀的环境变量将加载到应用中。Environment variables with the prefixes shown in the table are loaded into the app with the default configuration or when no prefix is supplied to AddEnvironmentVariables.

| 连接字符串前缀Connection string prefix | 提供程序Provider | | --- title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'
  • 'Identity''Identity'
  • 'Let's Encrypt''Let's Encrypt'
  • 'Razor''Razor'
  • 'SignalR' uid:'SignalR' uid:

------------ | --- title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:------------ | --- title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'
  • 'Identity''Identity'
  • 'Let's Encrypt''Let's Encrypt'
  • 'Razor''Razor'
  • 'SignalR' uid:'SignalR' uid:

---- | | CUSTOMCONNSTR_ | 自定义提供程序 | | MYSQLCONNSTR_ | MySQL | | SQLAZURECONNSTR_ | Azure SQL 数据库 | | SQLCONNSTR_ | SQL Server |---- | | 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:

  • 通过删除环境变量前缀并添加配置键节 (ConnectionStrings) 来创建配置键。The configuration key is created by removing the environment variable prefix and adding a configuration key section (ConnectionStrings).
  • 创建一个新的配置键值对,表示数据库连接提供程序(CUSTOMCONNSTR_ 除外,它没有声明的提供程序)。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 | | --- title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'
  • 'Identity''Identity'
  • 'Let's Encrypt''Let's Encrypt'
  • 'Razor''Razor'
  • 'SignalR' uid:'SignalR' uid:

------------ | --- title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:------------ | --- title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'
  • 'Identity''Identity'
  • 'Let's Encrypt''Let's Encrypt'
  • 'Razor''Razor'
  • 'SignalR' uid:'SignalR' uid:

-------------- | --- title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:-------------- | --- title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'
  • 'Identity''Identity'
  • 'Let's Encrypt''Let's Encrypt'
  • 'Razor''Razor'
  • 'SignalR' uid:'SignalR' uid:

---------------------------------------- | | CUSTOMCONNSTR_{KEY} | ConnectionStrings:{KEY} | 配置条目未创建。---------------------------------------- | | CUSTOMCONNSTR_{KEY} | ConnectionStrings:{KEY} | Configuration entry not created. | | MYSQLCONNSTR_{KEY} | ConnectionStrings:{KEY} | 键:ConnectionStrings:{KEY}_ProviderName| | MYSQLCONNSTR_{KEY} | ConnectionStrings:{KEY} | Key: ConnectionStrings:{KEY}_ProviderName:
值:MySql.Data.MySqlClient | | SQLAZURECONNSTR_{KEY} | ConnectionStrings:{KEY} | 键:ConnectionStrings:{KEY}_ProviderNameValue: MySql.Data.MySqlClient | | SQLAZURECONNSTR_{KEY} | ConnectionStrings:{KEY} | Key: ConnectionStrings:{KEY}_ProviderName:
值:System.Data.SqlClient | | SQLCONNSTR_{KEY} | ConnectionStrings:{KEY} | 键:ConnectionStrings:{KEY}_ProviderNameValue: System.Data.SqlClient | | SQLCONNSTR_{KEY} | ConnectionStrings:{KEY} | Key: ConnectionStrings:{KEY}_ProviderName:
值:System.Data.SqlClient |Value: System.Data.SqlClient |

JSON 配置提供程序JSON configuration provider

JsonConfigurationProvider 从 JSON 文件键值对加载配置。The JsonConfigurationProvider 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:

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

    public static IHostBuilder CreateHostBuilder(string[] args) =>
        Host.CreateDefaultBuilder(args)
            .ConfigureAppConfiguration((hostingContext, config) =>
            {
                config.AddJsonFile("MyConfig.json", 
                    optional: true, 
                    reloadOnChange: true);
            })
            .ConfigureWebHostDefaults(webBuilder =>
            {
                webBuilder.UseStartup<Startup>();
            });
}

前面的代码:The preceding code:

通常情况下,你不会希望自定义 JSON 文件替代在环境变量配置提供程序命令行配置提供程序中设置的值。You typically don't want a custom JSON file overriding values set in the Environment variables configuration provider and the Command-line configuration provider.

以下代码会清除所有配置提供程序并添加多个配置提供程序:The following code clears all the configuration providers and adds several configuration providers:

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

    public static IHostBuilder CreateHostBuilder(string[] args) =>
        Host.CreateDefaultBuilder(args)
            .ConfigureAppConfiguration((hostingContext, config) =>
            {
                config.Sources.Clear();

                var env = hostingContext.HostingEnvironment;

                config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
                      .AddJsonFile($"appsettings.{env.EnvironmentName}.json", 
                                     optional: true, reloadOnChange: true);

                config.AddJsonFile("MyConfig.json", optional: true, reloadOnChange: true)
                      .AddJsonFile($"MyConfig.{env.EnvironmentName}.json",
                                     optional: true, reloadOnChange: true);

                config.AddEnvironmentVariables();

                if (args != null)
                {
                    config.AddCommandLine(args);
                }
            })
            .ConfigureWebHostDefaults(webBuilder =>
            {
                webBuilder.UseStartup<Startup>();
            });
}

在前面的代码中,MyConfig.json 和 MyConfig.Environment.json 文件中的设置 :In the preceding code, settings in the MyConfig.json and MyConfig.Environment.json files:

示例下载包含以下 MyConfig.json 文件:The sample download contains the following MyConfig.json file:

{
    "Position": {
        "Title": "“我的配置”标题",
        "Name": "My Config Smith"
    },
    "MyKey": "MyConfig.json Value",
    "Logging": {
        "LogLevel": {
            "Default": "Information",
            "Microsoft": "Warning",
            "Microsoft.Hosting.Lifetime": "Information"
        }
    },
    "AllowedHosts": "*"
}

以下来自示例下载的代码显示了上述的一些配置设置:The following code from the sample download displays several of the preceding configurations settings:

public class TestModel : PageModel
{
    // requires using Microsoft.Extensions.Configuration;
    private readonly IConfiguration Configuration;

    public TestModel(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public ContentResult OnGet()
    {
        var myKeyValue = Configuration["MyKey"];
        var title = Configuration["Position:Title"];
        var name = Configuration["Position:Name"];
        var defaultLogLevel = Configuration["Logging:LogLevel:Default"];


        return Content($"MyKey value: {myKeyValue} \n" +
                       $"Title: {title} \n" +
                       $"Name: {name} \n" +
                       $"Default Log Level: {defaultLogLevel}");
    }
}

文件配置提供程序File configuration provider

FileConfigurationProvider 是从文件系统加载配置的基类。FileConfigurationProvider is the base class for loading configuration from the file system. 以下配置提供程序派生自 FileConfigurationProviderThe following configuration providers derive from FileConfigurationProvider:

INI 配置提供程序INI configuration provider

IniConfigurationProvider 在运行时从 INI 文件键值对加载配置。The IniConfigurationProvider loads configuration from INI file key-value pairs at runtime.

以下代码会清除所有配置提供程序并添加多个配置提供程序:The following code clears all the configuration providers and adds several configuration providers:

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

    public static IHostBuilder CreateHostBuilder(string[] args) =>
        Host.CreateDefaultBuilder(args)
            .ConfigureAppConfiguration((hostingContext, config) =>
            {
                config.Sources.Clear();

                var env = hostingContext.HostingEnvironment;

                config.AddIniFile("MyIniConfig.ini", optional: true, reloadOnChange: true)
                      .AddIniFile($"MyIniConfig.{env.EnvironmentName}.ini",
                                     optional: true, reloadOnChange: true);

                config.AddEnvironmentVariables();

                if (args != null)
                {
                    config.AddCommandLine(args);
                }
            })
            .ConfigureWebHostDefaults(webBuilder =>
            {
                webBuilder.UseStartup<Startup>();
            });
}

在前面的代码中,MyIniConfig.ini 和 MyIniConfig.Environment.ini 文件中的设置会被以下提供程序中的设置替代 :In the preceding code, settings in the MyIniConfig.ini and MyIniConfig.Environment.ini files are overridden by settings in the:

示例下载包含以下 MyIniConfig.ini 文件:The sample download contains the following MyIniConfig.ini file:

MyKey="MyIniConfig.ini Value"

[Position]
Title="My INI Config title"
Name="My INI Config name"

[Logging:LogLevel]
Default=Information
Microsoft=Warning

以下来自示例下载的代码显示了上述的一些配置设置:The following code from the sample download displays several of the preceding configurations settings:

public class TestModel : PageModel
{
    // requires using Microsoft.Extensions.Configuration;
    private readonly IConfiguration Configuration;

    public TestModel(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public ContentResult OnGet()
    {
        var myKeyValue = Configuration["MyKey"];
        var title = Configuration["Position:Title"];
        var name = Configuration["Position:Name"];
        var defaultLogLevel = Configuration["Logging:LogLevel:Default"];


        return Content($"MyKey value: {myKeyValue} \n" +
                       $"Title: {title} \n" +
                       $"Name: {name} \n" +
                       $"Default Log Level: {defaultLogLevel}");
    }
}

XML 配置提供程序XML configuration provider

XmlConfigurationProvider 在运行时从 XML 文件键值对加载配置。The XmlConfigurationProvider loads configuration from XML file key-value pairs at runtime.

以下代码会清除所有配置提供程序并添加多个配置提供程序:The following code clears all the configuration providers and adds several configuration providers:

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

    public static IHostBuilder CreateHostBuilder(string[] args) =>
        Host.CreateDefaultBuilder(args)
            .ConfigureAppConfiguration((hostingContext, config) =>
            {
                config.Sources.Clear();

                var env = hostingContext.HostingEnvironment;

                config.AddXmlFile("MyXMLFile.xml", optional: true, reloadOnChange: true)
                      .AddXmlFile($"MyXMLFile.{env.EnvironmentName}.xml",
                                     optional: true, reloadOnChange: true);

                config.AddEnvironmentVariables();

                if (args != null)
                {
                    config.AddCommandLine(args);
                }
            })
            .ConfigureWebHostDefaults(webBuilder =>
            {
                webBuilder.UseStartup<Startup>();
            });
}

在前面的代码中,MyXMLFile.xml 和 MyXMLFile.Environment.xml 文件中的设置会被以下提供程序中的设置替代 :In the preceding code, settings in the MyXMLFile.xml and MyXMLFile.Environment.xml files are overridden by settings in the:

示例下载包含以下 MyXMLFile.xml 文件:The sample download contains the following MyXMLFile.xml file:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <MyKey>MyXMLFile Value</MyKey>
  <Position>
    <Title>Title from  MyXMLFile</Title>
    <Name>Name from MyXMLFile</Name>
  </Position>
  <Logging>
    <LogLevel>
      <Default>Information</Default>
      <Microsoft>Warning</Microsoft>
    </LogLevel>
  </Logging>
</configuration>

以下来自示例下载的代码显示了上述的一些配置设置:The following code from the sample download displays several of the preceding configurations settings:

public class TestModel : PageModel
{
    // requires using Microsoft.Extensions.Configuration;
    private readonly IConfiguration Configuration;

    public TestModel(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public ContentResult OnGet()
    {
        var myKeyValue = Configuration["MyKey"];
        var title = Configuration["Position:Title"];
        var name = Configuration["Position:Name"];
        var defaultLogLevel = Configuration["Logging:LogLevel:Default"];


        return Content($"MyKey value: {myKeyValue} \n" +
                       $"Title: {title} \n" +
                       $"Name: {name} \n" +
                       $"Default Log Level: {defaultLogLevel}");
    }
}

如果使用 name 属性来区分元素,则使用相同元素名称的重复元素可以正常工作: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 00</key>
    <key name="key1">value 01</key>
  </section>
  <section name="section1">
    <key name="key0">value 10</key>
    <key name="key1">value 11</key>
  </section>
</configuration>

以下代码会读取前面的配置文件并显示键和值:The following code reads the previous configuration file and displays the keys and values:

public class IndexModel : PageModel
{
    private readonly IConfiguration Configuration;

    public IndexModel(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public ContentResult OnGet()
    {
        var key00 = "section:section0:key:key0";
        var key01 = "section:section0:key:key1";
        var key10 = "section:section1:key:key0";
        var key11 = "section:section1:key:key1";

        var val00 = Configuration[key00];
        var val01 = Configuration[key01];
        var val10 = Configuration[key10];
        var val11 = Configuration[key11];

        return Content($"{key00} value: {val00} \n" +
                       $"{key01} value: {val01} \n" +
                       $"{key10} value: {val10} \n" +
                       $"{key10} value: {val11} \n"
                       );
    }
}

属性可用于提供值:Attributes can be used to supply values:

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

以前的配置文件使用 value 加载以下键:The previous configuration file loads the following keys with value:

  • key:attributekey:attribute
  • section:key:attributesection:key:attribute

Key-per-file 配置提供程序Key-per-file configuration provider

KeyPerFileConfigurationProvider 使用目录的文件作为配置键值对。The KeyPerFileConfigurationProvider uses a directory's files as configuration key-value pairs. 该键是文件名。The key is the file name. 该值包含文件的内容。The value contains the file's contents. Key-per-file 配置提供程序用于 Docker 托管方案。The Key-per-file configuration provider is used in Docker hosting scenarios.

若要激活 Key-per-file 配置,请在 ConfigurationBuilder 的实例上调用 AddKeyPerFile 扩展方法。To activate key-per-file configuration, call the AddKeyPerFile extension method on an instance of ConfigurationBuilder. 文件的 directoryPath 必须是绝对路径。The directoryPath to the files must be an absolute path.

重载允许指定:Overloads permit specifying:

  • 配置源的 Action<KeyPerFileConfigurationSource> 委托。An Action<KeyPerFileConfigurationSource> 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. 例如,文件名 Logging__LogLevel__System 生成配置键 Logging:LogLevel:SystemFor example, the file name Logging__LogLevel__System produces the configuration key Logging:LogLevel:System.

构建主机时调用 ConfigureAppConfiguration 以指定应用的配置:Call ConfigureAppConfiguration when building the host to specify the app's configuration:

.ConfigureAppConfiguration((hostingContext, config) =>
{
    var path = Path.Combine(
        Directory.GetCurrentDirectory(), "path/to/files");
    config.AddKeyPerFile(directoryPath: path, optional: true);
})

内存配置提供程序Memory configuration provider

MemoryConfigurationProvider 使用内存中集合作为配置键值对。The MemoryConfigurationProvider uses an in-memory collection as configuration key-value pairs.

以下代码将内存集合添加到配置系统中:The following code adds a memory collection to the configuration system:

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

    public static IHostBuilder CreateHostBuilder(string[] args)
    {
        var Dict = new Dictionary<string, string>
        {
           {"MyKey", "Dictionary MyKey Value"},
           {"Position:Title", "Dictionary_Title"},
           {"Position:Name", "Dictionary_Name" },
           {"Logging:LogLevel:Default", "Warning"}
        };

        return Host.CreateDefaultBuilder(args)
            .ConfigureAppConfiguration((hostingContext, config) =>
            {
                config.AddInMemoryCollection(Dict);
            })
            .ConfigureWebHostDefaults(webBuilder =>
            {
                webBuilder.UseStartup<Startup>();
            });
    }
}

以下来自示例下载的代码显示了上述配置设置:The following code from the sample download displays the preceding configurations settings:

public class TestModel : PageModel
{
    // requires using Microsoft.Extensions.Configuration;
    private readonly IConfiguration Configuration;

    public TestModel(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public ContentResult OnGet()
    {
        var myKeyValue = Configuration["MyKey"];
        var title = Configuration["Position:Title"];
        var name = Configuration["Position:Name"];
        var defaultLogLevel = Configuration["Logging:LogLevel:Default"];


        return Content($"MyKey value: {myKeyValue} \n" +
                       $"Title: {title} \n" +
                       $"Name: {name} \n" +
                       $"Default Log Level: {defaultLogLevel}");
    }
}

在前面的代码中,config.AddInMemoryCollection(Dict) 会被添加到默认配置提供程序之后。In the preceding code, config.AddInMemoryCollection(Dict) is added after the default configuration providers. 有关对配置提供程序进行排序的示例,请参阅 JSON 配置提供程序For an example of ordering the configuration providers, see JSON configuration provider.

有关使用 MemoryConfigurationProvider 的其他示例,请参阅绑定数组See Bind an array for another example using MemoryConfigurationProvider.

GetValueGetValue

ConfigurationBinder.GetValue<T> 从配置中提取一个具有指定键的值,并将它转换为指定的类型:ConfigurationBinder.GetValue<T> extracts a single value from configuration with a specified key and converts it to the specified type:

public class TestNumModel : PageModel
{
    private readonly IConfiguration Configuration;

    public TestNumModel(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public ContentResult OnGet()
    {
        var number = Configuration.GetValue<int>("NumberKey", 99);
        return Content($"{number}");
    }
}

在前面的代码中,如果在配置中找不到 NumberKey,则使用默认值 99In the preceding code, if NumberKey isn't found in the configuration, the default value of 99 is used.

GetSection、GetChildren 和 ExistsGetSection, GetChildren, and Exists

对于下面的示例,请考虑以下 MySubsection.json 文件:For the examples that follow, consider the following MySubsection.json file:

{
  "section0": {
    "key0": "value00",
    "key1": "value01"
  },
  "section1": {
    "key0": "value10",
    "key1": "value11"
  },
  "section2": {
    "subsection0": {
      "key0": "value200",
      "key1": "value201"
    },
    "subsection1": {
      "key0": "value210",
      "key1": "value211"
    }
  }
}

以下代码将 MySubsection.json 添加到配置提供程序:The following code adds MySubsection.json to the configuration providers:

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

    public static IHostBuilder CreateHostBuilder(string[] args) =>
        Host.CreateDefaultBuilder(args)
            .ConfigureAppConfiguration((hostingContext, config) =>
            {
                config.AddJsonFile("MySubsection.json", 
                    optional: true, 
                    reloadOnChange: true);
            })
            .ConfigureWebHostDefaults(webBuilder =>
            {
                webBuilder.UseStartup<Startup>();
            });
}

GetSectionGetSection

IConfiguration.GetSection 会返回具有指定子节键的配置子节。IConfiguration.GetSection returns a configuration subsection with the specified subsection key.

以下代码将返回 section1 的值:The following code returns values for section1:

public class TestSectionModel : PageModel
{
    private readonly IConfiguration Config;

    public TestSectionModel(IConfiguration configuration)
    {
        Config = configuration.GetSection("section1");
    }

    public ContentResult OnGet()
    {
        return Content(
                $"section1:key0: '{Config["key0"]}'\n" +
                $"section1:key1: '{Config["key1"]}'");
    }
}

以下代码将返回 section2:subsection0 的值:The following code returns values for section2:subsection0:

public class TestSection2Model : PageModel
{
    private readonly IConfiguration Config;

    public TestSection2Model(IConfiguration configuration)
    {
        Config = configuration.GetSection("section2:subsection0");
    }

    public ContentResult OnGet()
    {
        return Content(
                $"section2:subsection0:key0 '{Config["key0"]}'\n" +
                $"section2:subsection0:key1:'{Config["key1"]}'");
    }
}

GetSection 永远不会返回 nullGetSection never returns null. 如果找不到匹配的节,则返回空 IConfigurationSectionIf a matching section isn't found, an empty IConfigurationSection is returned.

GetSection 返回匹配的部分时,Value 未填充。When GetSection returns a matching section, Value isn't populated. 存在该部分时,返回一个 KeyPath 部分。A Key and Path are returned when the section exists.

GetChildren 和 ExistsGetChildren and Exists

以下代码将调用 IConfiguration.GetChildren 并返回 section2:subsection0 的值:The following code calls IConfiguration.GetChildren and returns values for section2:subsection0:

public class TestSection4Model : PageModel
{
    private readonly IConfiguration Config;

    public TestSection4Model(IConfiguration configuration)
    {
        Config = configuration;
    }

    public ContentResult OnGet()
    {
        string s = null;
        var selection = Config.GetSection("section2");
        if (!selection.Exists())
        {
            throw new System.Exception("section2 does not exist.");
        }
        var children = selection.GetChildren();

        foreach (var subSection in children)
        {
            int i = 0;
            var key1 = subSection.Key + ":key" + i++.ToString();
            var key2 = subSection.Key + ":key" + i.ToString();
            s += key1 + " value: " + selection[key1] + "\n";
            s += key2 + " value: " + selection[key2] + "\n";
        }
        return Content(s);
    }
}

前面的代码将调用 ConfigurationExtensions.Exists 以验证该节是否存在:The preceding code calls ConfigurationExtensions.Exists to verify the section exists:

绑定数组Bind an array

ConfigurationBinder.Bind 支持使用配置键中的数组索引将数组绑定到对象。The ConfigurationBinder.Bind supports binding arrays to objects using array indices in configuration keys. 公开数值键段的任何数组格式都能够与 POCO 类数组进行数组绑定。Any array format that exposes a numeric key segment is capable of array binding to a POCO class array.

请考虑示例下载中的 MyArray.json:Consider MyArray.json from the sample download:

{
  "array": {
    "entries": {
      "0": "value00",
      "1": "value10",
      "2": "value20",
      "4": "value40",
      "5": "value50"
    }
  }
}

以下代码将 MyArray.json 添加到配置提供程序:The following code adds MyArray.json to the configuration providers:

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

    public static IHostBuilder CreateHostBuilder(string[] args) =>
        Host.CreateDefaultBuilder(args)
            .ConfigureAppConfiguration((hostingContext, config) =>
            {
                config.AddJsonFile("MyArray.json", 
                    optional: true, 
                    reloadOnChange: true);
            })
            .ConfigureWebHostDefaults(webBuilder =>
            {
                webBuilder.UseStartup<Startup>();
            });
}

以下代码将读取配置并显示值:The following code reads the configuration and displays the values:

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<ArrayExample>();
        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:

Index: 0  Value: value00
Index: 1  Value: value10
Index: 2  Value: value20
Index: 3  Value: value40
Index: 4  Value: value50

在前面的输出中,索引 3 具有值 value40,与 MyArray.json 中的 "4": "value40", 相对应。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. 配置绑定器不能绑定 NULL 值,也不能在绑定的对象中创建 NULL 条目The configuration binder isn't capable of binding null values or creating null entries in bound objects

以下代码将通过 AddInMemoryCollection 扩展方法加载 array:entries 配置:The following code loads the array:entries configuration with the AddInMemoryCollection extension method:

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

    public static IHostBuilder CreateHostBuilder(string[] args)
    {
        var arrayDict = new Dictionary<string, string>
        {
            {"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<Startup>();
            });
    }
}

以下代码将读取 arrayDict Dictionary 中的配置并显示值:The following code reads the configuration in the arrayDict Dictionary and displays the values:

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<ArrayExample>();
        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:

Index: 0  Value: value0
Index: 1  Value: value1
Index: 2  Value: value2
Index: 3  Value: value4
Index: 4  Value: value5

绑定对象中的索引 #3 保留 array:4 配置键的配置数据及其值 value4Index #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. 无法在配置数据中保留 null 值,并且当配置键中的数组跳过一个或多个索引时,不会在绑定对象中创建 null 值条目。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.

可以在由任何读取索引 #3 键/值对的配置提供程序绑定到 ArrayExample 实例之前提供索引 #3 的缺失配置项。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. 请考虑示例下载中的以下 Value3.json 文件:Consider the following Value3.json file from the sample download:

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

以下代码包含 Value3.json 和 arrayDict Dictionary 的配置:The following code includes configuration for Value3.json and the arrayDict Dictionary:

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

    public static IHostBuilder CreateHostBuilder(string[] args)
    {
        var arrayDict = new Dictionary<string, string>
        {
            {"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<Startup>();
            });
    }
}

以下代码将读取上述配置并显示值:The following code reads the preceding configuration and displays the values:

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<ArrayExample>();
        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:

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

该示例应用演示了如何使用实体框架 (EF) 创建从数据库读取配置键值对的基本配置提供程序。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:

  • EF 内存中数据库用于演示目的。The EF in-memory database is used for demonstration purposes. 若要使用需要连接字符串的数据库,请实现辅助 ConfigurationBuilder 以从另一个配置提供程序提供连接字符串。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.

定义用于在数据库中存储配置值的 EFConfigurationValue 实体。Define an EFConfigurationValue entity for storing configuration values in the database.

Models/EFConfigurationValue.csModels/EFConfigurationValue.cs:

public class EFConfigurationValue
{
    public string Id { get; set; }
    public string Value { get; set; }
}

添加 EFConfigurationContext 以存储和访问配置的值。Add an EFConfigurationContext to store and access the configured values.

EFConfigurationProvider/EFConfigurationContext.csEFConfigurationProvider/EFConfigurationContext.cs:

public class EFConfigurationContext : DbContext
{
    public EFConfigurationContext(DbContextOptions options) : base(options)
    {
    }

    public DbSet<EFConfigurationValue> Values { get; set; }
}

创建用于实现 IConfigurationSource 的类。Create a class that implements IConfigurationSource.

EFConfigurationProvider/EFConfigurationSource.csEFConfigurationProvider/EFConfigurationSource.cs:

public class EFConfigurationSource : IConfigurationSource
{
    private readonly Action<DbContextOptionsBuilder> _optionsAction;

    public EFConfigurationSource(Action<DbContextOptionsBuilder> optionsAction)
    {
        _optionsAction = optionsAction;
    }

    public IConfigurationProvider Build(IConfigurationBuilder builder)
    {
        return new EFConfigurationProvider(_optionsAction);
    }
}

通过从 ConfigurationProvider 继承来创建自定义配置提供程序。Create the custom configuration provider by inheriting from ConfigurationProvider. 当数据库为空时,配置提供程序将对其进行初始化。The configuration provider initializes the database when it's empty. 由于配置密钥不区分大小写,因此用来初始化数据库的字典是用不区分大小写的比较程序 (StringComparer.OrdinalIgnoreCase) 创建的。Since configuration keys are case-insensitive, the dictionary used to initialize the database is created with the case-insensitive comparer (StringComparer.OrdinalIgnoreCase).

EFConfigurationProvider/EFConfigurationProvider.csEFConfigurationProvider/EFConfigurationProvider.cs:

public class EFConfigurationProvider : ConfigurationProvider
{
    public EFConfigurationProvider(Action<DbContextOptionsBuilder> optionsAction)
    {
        OptionsAction = optionsAction;
    }

    Action<DbContextOptionsBuilder> OptionsAction { get; }

    // Load config data from EF DB.
    public override void Load()
    {
        var builder = new DbContextOptionsBuilder<EFConfigurationContext>();

        OptionsAction(builder);

        using (var dbContext = new EFConfigurationContext(builder.Options))
        {
            dbContext.Database.EnsureCreated();

            Data = !dbContext.Values.Any()
                ? CreateAndSaveDefaultValues(dbContext)
                : dbContext.Values.ToDictionary(c => c.Id, c => c.Value);
        }
    }

    private static IDictionary<string, string> CreateAndSaveDefaultValues(
        EFConfigurationContext dbContext)
    {
        // Quotes (c)2005 Universal Pictures: Serenity
        // https://www.uphe.com/movies/serenity
        var configValues = 
            new Dictionary<string, string>(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;
    }
}

可以使用 AddEFConfiguration 扩展方法将配置源添加到 ConfigurationBuilderAn AddEFConfiguration extension method permits adding the configuration source to a ConfigurationBuilder.

Extensions/EntityFrameworkExtensions.cs:Extensions/EntityFrameworkExtensions.cs:

public static class EntityFrameworkExtensions
{
    public static IConfigurationBuilder AddEFConfiguration(
        this IConfigurationBuilder builder, 
        Action<DbContextOptionsBuilder> optionsAction)
    {
        return builder.Add(new EFConfigurationSource(optionsAction));
    }
}

下面的代码演示如何在 Program.cs 中使用自定义的 EFConfigurationProviderThe following code shows how to use the custom EFConfigurationProvider in Program.cs:

public class Program
{
    public static Dictionary<string, string> arrayDict = 
        new Dictionary<string, string>
        {
            {"array:entries:0", "value0"},
            {"array:entries:1", "value1"},
            {"array:entries:2", "value2"},
            {"array:entries:4", "value4"},
            {"array:entries:5", "value5"}
        };

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

    public static IHostBuilder CreateHostBuilder(string[] args) =>
        Host.CreateDefaultBuilder(args)
            .ConfigureAppConfiguration((hostingContext, config) =>
            {
                config.AddInMemoryCollection(arrayDict);
                config.AddJsonFile(
                    "json_array.json", optional: false, reloadOnChange: false);
                config.AddJsonFile(
                    "starship.json", optional: false, reloadOnChange: false);
                config.AddXmlFile(
                    "tvshow.xml", optional: false, reloadOnChange: false);
                config.AddEFConfiguration(
                    options => options.UseInMemoryDatabase("InMemoryDb"));
                config.AddCommandLine(args);
            })
            .ConfigureWebHostDefaults(webBuilder =>
            {
                webBuilder.UseStartup<Startup>();
            });
}

访问 Startup 中的配置Access configuration in Startup

以下代码显示 Startup 方法中的配置数据:The following code displays configuration data in Startup methods:

public class Startup
{
    public Startup(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public IConfiguration Configuration { get; }

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddRazorPages();
        Console.WriteLine($"MyKey : {Configuration["MyKey"]}");
    }

    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        Console.WriteLine($"Position:Title : {Configuration["Position:Title"]}");

        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }
        else
        {
            app.UseExceptionHandler("/Error");
            app.UseHsts();
        }

        app.UseHttpsRedirection();
        app.UseStaticFiles();

        app.UseRouting();

        app.UseAuthorization();

        app.UseEndpoints(endpoints =>
        {
            endpoints.MapRazorPages();
        });
    }
}

有关使用启动便捷方法访问配置的示例,请参阅应用启动:便捷方法For an example of accessing configuration using startup convenience methods, see App startup: Convenience methods.

访问 Razor Pages 中的配置Access configuration in Razor Pages

以下代码显示 Razor Pages 中的配置数据:The following code displays configuration data in a Razor Page:

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

Configuration value for 'MyKey': @Configuration["MyKey"]

在以下代码中,MyOptions 已通过 Configure 被添加到了服务容器并已绑定到了配置:In the following code, MyOptions is added to the service container with Configure and bound to configuration:

public void ConfigureServices(IServiceCollection services)
{
    services.Configure<MyOptions>(Configuration.GetSection("MyOptions"));

    services.AddRazorPages();
}

以下标记使用 @inject Razor 指令来解析和显示选项值:The following markup uses the @inject Razor directive to resolve and display the options values:

@page
@model SampleApp.Pages.Test3Model
@using Microsoft.Extensions.Options
@inject IOptions<MyOptions> optionsAccessor


<p><b>Option1:</b> @optionsAccessor.Value.Option1</p>
<p><b>Option2:</b> @optionsAccessor.Value.Option2</p>

访问 MVC 视图文件中的配置Access configuration in a MVC view file

以下代码显示 MVC 视图中的配置数据:The following code displays configuration data in a MVC view:

@using Microsoft.Extensions.Configuration
@inject IConfiguration Configuration

Configuration value for 'MyKey': @Configuration["MyKey"]

使用委托来配置选项Configure options with a delegate

在委托中配置的选项替代在配置提供程序中设置的值。Options configured in a delegate override values set in the configuration providers.

示例应用中的示例 2 展示了如何使用委托来配置选项。Configuring options with a delegate is demonstrated as Example 2 in the sample app.

在以下代码中,向服务容器添加了 IConfigureOptions<TOptions> 服务。In the following code, an IConfigureOptions<TOptions> service is added to the service container. 它使用委托来配置 MyOptions 的值:It uses a delegate to configure values for MyOptions:

public void ConfigureServices(IServiceCollection services)
{
    services.Configure<MyOptions>(myOptions =>
    {
        myOptions.Option1 = "Value configured in delegate";
        myOptions.Option2 = 500;
    });

    services.AddRazorPages();
}

以下代码显示选项值:The following code displays the options values:

public class Test2Model : PageModel
{
    private readonly IOptions<MyOptions> _optionsDelegate;

    public Test2Model(IOptions<MyOptions> optionsDelegate )
    {
        _optionsDelegate = optionsDelegate;
    }

    public ContentResult OnGet()
    {
        return Content($"Option1: {_optionsDelegate.Value.Option1} \n" +
                       $"Option2: {_optionsDelegate.Value.Option2}");
    }
}

在前面的示例中,Option1Option2 的值在 appsettings.json 中指定,然后被配置的委托替代。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. 有关在构建主机时如何使用配置提供程序以及配置源如何影响主机配置的详细信息,请参阅 ASP.NET Core 基础知识For more information on how the configuration providers are used when the host is built and how configuration sources affect host configuration, see ASP.NET Core 基础知识.

默认主机配置Default host configuration

有关使用 Web 主机时默认配置的详细信息,请参阅本主题的 ASP.NET Core 2.2 版本For details on the default configuration when using the Web Host, see the ASP.NET Core 2.2 version of this topic.

  • 主机配置通过以下方式提供:Host configuration is provided from:
  • 已建立 Web 主机默认配置 (ConfigureWebHostDefaults):Web Host default configuration is established (ConfigureWebHostDefaults):
    • Kestrel 用作 Web 服务器,并使用应用的配置提供程序对其进行配置。Kestrel is used as the web server and configured using the app's configuration providers.
    • 添加主机筛选中间件。Add Host Filtering Middleware.
    • 如果 ASPNETCORE_FORWARDEDHEADERS_ENABLED 环境变量设置为 true,则添加转发的标头中间件。Add Forwarded Headers Middleware if the ASPNETCORE_FORWARDEDHEADERS_ENABLED environment variable is set to true.
    • 启用 IIS 集成。Enable IIS integration.

其他配置Other configuration

本主题仅与应用配置相关。This topic only pertains to app configuration. 运行和托管 ASP.NET Core 应用的其他方面是使用本主题中未包含的配置文件进行配置:Other aspects of running and hosting ASP.NET Core apps are configured using configuration files not covered in this topic:

  • launch.json/launchSettings.json 是用于开发环境的工具配置文件,如launch.json/launchSettings.json are tooling configuration files for the Development environment, described:
  • web.config 是服务器配置文件,如以下主题中所述:web.config is a server configuration file, described in the following topics:
    • <xref:host-and-deploy/iis/index>
    • <xref:host-and-deploy/aspnet-core-module>

若要详细了解如何从旧版 ASP.NET 迁移应用配置,请参阅 从 ASP.NET 迁移到 ASP.NET CoreFor more information on migrating app configuration from earlier versions of ASP.NET, see 从 ASP.NET 迁移到 ASP.NET Core.

从外部程序集添加配置Add configuration from an external assembly

通过 IHostingStartup 实现,可在启动时从应用 Startup 类之外的外部程序集向应用添加增强功能。An IHostingStartup implementation allows adding enhancements to an app at startup from an external assembly outside of the app's Startup class. 有关详细信息,请参阅 <xref:fundamentals/configuration/platform-specific-configuration>。For more information, see <xref:fundamentals/configuration/platform-specific-configuration>.

其他资源Additional resources

ASP.NET Core 中的应用配置基于配置提供程序建立的键值对。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:

  • Azure Key VaultAzure Key Vault
  • Azure 应用程序配置Azure App Configuration
  • 命令行参数Command-line arguments
  • (已安装或已创建的)自定义提供程序Custom providers (installed or created)
  • 目录文件Directory files
  • 环境变量Environment variables
  • 内存中的 .NET 对象In-memory .NET objects
  • 设置文件Settings files

Microsoft.AspNetCore.App metapackage 中包含通用配置提供程序方案的配置包 (Microsoft Extensions.Configuration)。Configuration packages for common configuration provider scenarios (Microsoft.Extensions.Configuration) are included in the Microsoft.AspNetCore.App metapackage.

后面的代码示例和示例应用中的代码示例使用 Microsoft.Extensions.Configuration 命名空间:Code examples that follow and in the sample app use the Microsoft.Extensions.Configuration namespace:

using Microsoft.Extensions.Configuration;

选项模式是本主题中描述的配置概念的扩展。The options pattern is an extension of the configuration concepts described in this topic. 选项使用类来表示相关设置的组。Options use classes to represent groups of related settings. 有关详细信息,请参阅 <xref:fundamentals/configuration/options>。For more information, see <xref:fundamentals/configuration/options>.

查看或下载示例代码如何下载View or download sample code (how to download)

主机与应用配置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. 有关在构建主机时如何使用配置提供程序以及配置源如何影响主机配置的详细信息,请参阅 ASP.NET Core 基础知识For more information on how the configuration providers are used when the host is built and how configuration sources affect host configuration, see ASP.NET Core 基础知识.

其他配置Other configuration

本主题仅与应用配置相关。This topic only pertains to app configuration. 运行和托管 ASP.NET Core 应用的其他方面是使用本主题中未包含的配置文件进行配置:Other aspects of running and hosting ASP.NET Core apps are configured using configuration files not covered in this topic:

  • launch.json/launchSettings.json 是用于开发环境的工具配置文件,如launch.json/launchSettings.json are tooling configuration files for the Development environment, described:
  • web.config 是服务器配置文件,如以下主题中所述:web.config is a server configuration file, described in the following topics:
    • <xref:host-and-deploy/iis/index>
    • <xref:host-and-deploy/aspnet-core-module>

若要详细了解如何从旧版 ASP.NET 迁移应用配置,请参阅 从 ASP.NET 迁移到 ASP.NET CoreFor more information on migrating app configuration from earlier versions of ASP.NET, see 从 ASP.NET 迁移到 ASP.NET Core.

默认配置Default configuration

基于 ASP.NET Core dotnet new模板的 Web 应用在生成主机时会调用 CreateDefaultBuilderWeb apps based on the ASP.NET Core dotnet new templates call CreateDefaultBuilder when building a host. CreateDefaultBuilder 按照以下顺序为应用提供默认配置:CreateDefaultBuilder provides default configuration for the app in the following order:

以下内容适用于使用 Web 主机的应用。The following applies to apps using the Web Host. 有关使用通用主机时默认配置的详细信息,请参阅本主题的最新版本For details on the default configuration when using the Generic Host, see the latest version of this topic.

安全性Security

采用以下做法来保护敏感配置数据:Adopt the following practices to secure sensitive configuration data:

  • 请勿在配置提供程序代码或纯文本配置文件中存储密码或其他敏感数据。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.

有关详细信息,请参阅下列主题:For more information, see the following topics:

Azure Key Vault 安全存储 ASP.NET Core 应用的应用机密。Azure Key Vault safely stores app secrets for ASP.NET Core apps. 有关详细信息,请参阅 <xref:security/key-vault-configuration>。For more information, see <xref:security/key-vault-configuration>.

分层配置数据Hierarchical configuration data

配置 API 能够通过在配置键中使用分隔符来展平分层数据以保持分层配置数据。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.

在以下 JSON 文件中,两个节的结构化层次结构中存在四个键: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:key0section0:key0
  • section0:key1section0:key1
  • section1:key0section1:key0
  • section1:key1section1:key1

GetSectionGetChildren 方法可用于隔离各个节和配置数据中某节的子节。GetSection and GetChildren methods are available to isolate sections and children of a section in the configuration data. 稍后将在 GetSection、GetChildren 和 Exists 中介绍这些方法。These methods are described later in GetSection, GetChildren, and Exists.

约定Conventions

源和提供程序Sources and providers

在应用启动时,将按照指定的配置提供程序的顺序读取配置源。At app startup, configuration sources are read in the order that their configuration providers are specified.

实现更改检测的配置提供程序能够在基础设置更改时重新加载配置。Configuration providers that implement change detection have the ability to reload configuration when an underlying setting is changed. 例如,文件配置提供程序(本主题后面将对此进行介绍)和 Azure Key Vault 配置提供程序实现更改检测。For example, the File Configuration Provider (described later in this topic) and the Azure Key Vault Configuration Provider implement change detection.

应用的依赖关系注入 (DI) 容器中提供了 IConfigurationIConfiguration is available in the app's dependency injection (DI) container. IConfiguration 可注入到 Razor Pages PageModel 或 MVC Controller 中,以获取类的配置。IConfiguration can be injected into a Razor Pages PageModel or MVC Controller to obtain configuration for the class.

在下面的示例中,使用 _config 字段来访问配置值:In the following examples, the _config field is used to access configuration values:

public class IndexModel : PageModel
{
    private readonly IConfiguration _config;

    public IndexModel(IConfiguration config)
    {
        _config = config;
    }
}
public class HomeController : Controller
{
    private readonly IConfiguration _config;

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

配置提供程序不能使用 DI,因为主机在设置这些提供程序时 DI 不可用。Configuration providers can't utilize DI, as it's not available when they're set up by the host.

Keys

配置键采用以下约定:Configuration keys adopt the following conventions:

  • 键不区分大小写。Keys are case-insensitive. 例如,ConnectionStringconnectionstring 被视为等效键。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
    • 在配置 API 中,冒号分隔符 (:) 适用于所有平台。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.
    • 在 Azure Key Vault 中,分层键使用 --(两个破折号)作为分隔符。In Azure Key Vault, hierarchical keys use -- (two dashes) as a separator. 将机密加载到应用的配置中时,用冒号替换破折号。Write code to replace the dashes with a colon when the secrets are loaded into the app's configuration.
  • ConfigurationBinder 支持使用配置键中的数组索引将数组绑定到对象。The 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.

Values

配置值采用以下约定:Configuration values adopt the following conventions:

  • 值是字符串。Values are strings.
  • NULL 值不能存储在配置中或绑定到对象。Null values can't be stored in configuration or bound to objects.

提供程序Providers

下表显示了 ASP.NET Core 应用可用的配置提供程序。The following table shows the configuration providers available to ASP.NET Core apps.

| 提供程序Provider | 通过以下对象提供配置…Provides configuration from… | | --- title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'
  • 'Identity''Identity'
  • 'Let's Encrypt''Let's Encrypt'
  • 'Razor''Razor'
  • 'SignalR' uid:'SignalR' uid:

---- | --- title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:---- | --- title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'
  • 'Identity''Identity'
  • 'Let's Encrypt''Let's Encrypt'
  • 'Razor''Razor'
  • 'SignalR' uid:'SignalR' uid:

------------------ | | Azure Key Vault 配置提供程序(“安全性”主题)| Azure Key Vault | | Azure 应用程序配置提供程序(Azure 文档)| Azure 应用程序配置 | | 命令行配置提供程序 | 命令行参数 | | 自定义配置提供程序 | 自定义源 | | 环境变量配置提供程序 | 环境变量 | | 文件配置提供程序 | 文件(INI、JSON、XML)| | 每文件密钥配置提供程序 | 目录文件 | | 内存配置提供程序 | 内存中集合 | | 用户机密(机密管理器)(“安全性” 主题)| 用户配置文件目录中的文件 |------------------ | | Azure Key Vault Configuration Provider (Security topics) | Azure Key Vault | | Azure App Configuration Provider (Azure documentation) | Azure App Configuration | | 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 |

按照启动时指定的配置提供程序的顺序读取配置源。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 the code arranges them. 代码中的配置提供程序应以特定顺序排列,从而满足应用所需的基础配置源的优先级。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、appsettings.{Environment}.json,其中 {Environment} 是应用的当前托管环境) Files (appsettings.json, appsettings.{Environment}.json, where {Environment} is the app's current hosting environment)
  2. Azure 密钥保管库Azure Key Vault
  3. 用户机密 (Secret Manager)(仅限开发环境中)User secrets (Secret Manager) (Development environment only)
  4. 环境变量Environment variables
  5. 命令行参数Command-line arguments

通常的做法是将命令行配置提供程序置于一系列提供程序的末尾,以允许命令行参数替代由其他提供程序设置的配置。A common practice is 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.

使用 CreateDefaultBuilder 初始化新的主机生成器时,将使用上述提供程序序列。The preceding sequence of providers is used when a new host builder is initialized with CreateDefaultBuilder. 有关详细信息,请参阅默认配置部分。For more information, see the Default configuration section.

用 UseConfiguration 配置主机生成器Configure the host builder with UseConfiguration

若要配置主机生成器,请使用配置在主机生成器上调用 UseConfigurationTo configure the host builder, call UseConfiguration on the host builder with the configuration.

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>();
}

ConfigureAppConfigurationConfigureAppConfiguration

构建主机时调用 ConfigureAppConfiguration 以指定应用的配置提供程序以及 CreateDefaultBuilder 自动添加的配置提供程序:Call ConfigureAppConfiguration when building the host to specify the app's configuration providers in addition to those added automatically by CreateDefaultBuilder:

public class Program
{
    public static Dictionary<string, string> arrayDict = 
        new Dictionary<string, string>
        {
            {"array:entries:0", "value0"},
            {"array:entries:1", "value1"},
            {"array:entries:2", "value2"},
            {"array:entries:4", "value4"},
            {"array:entries:5", "value5"}
        };

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

    public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
        WebHost.CreateDefaultBuilder(args)
            .ConfigureAppConfiguration((hostingContext, config) =>
            {
                config.AddInMemoryCollection(arrayDict);
                config.AddJsonFile(
                    "json_array.json", optional: false, reloadOnChange: false);
                config.AddJsonFile(
                    "starship.json", optional: false, reloadOnChange: false);
                config.AddXmlFile(
                    "tvshow.xml", optional: false, reloadOnChange: false);
                config.AddEFConfiguration(
                    options => options.UseInMemoryDatabase("InMemoryDb"));
                config.AddCommandLine(args);
            })
            .UseStartup<Startup>();
}

用命令行参数替代以前的配置Override previous configuration with command-line arguments

若要提供命令行参数可替代的应用配置,最后请调用 AddCommandLineTo provide app configuration that can be overridden with command-line arguments, call AddCommandLine last:

.ConfigureAppConfiguration((hostingContext, config) =>
{
    // Call other providers here
    config.AddCommandLine(args);
})

删除 CreateDefaultBuilder 添加的提供程序Remove providers added by CreateDefaultBuilder

要删除 CreateDefaultBuilder 添加的提供程序,请先对 IConfigurationBuilder.Sources 调用 ClearTo remove the providers added by CreateDefaultBuilder, call Clear on the IConfigurationBuilder.Sources first:

.ConfigureAppConfiguration((hostingContext, config) =>
{
    config.Sources.Clear();
    // Add providers here
})

在应用启动期间使用配置Consume configuration during app startup

在应用启动期间,可以使用 ConfigureAppConfiguration 中提供给应用的配置,包括 Startup.ConfigureServicesConfiguration supplied to the app in ConfigureAppConfiguration is available during the app's startup, including Startup.ConfigureServices. 有关详细信息,请参阅在启动期间访问配置部分。For more information, see the Access configuration during startup section.

命令行配置提供程序Command-line Configuration Provider

CommandLineConfigurationProvider 在运行时从命令行参数键值对加载配置。The CommandLineConfigurationProvider loads configuration from command-line argument key-value pairs at runtime.

要激活命令行配置,请在 ConfigurationBuilder 的实例上调用 AddCommandLine 扩展方法。To activate command-line configuration, the AddCommandLine extension method is called on an instance of ConfigurationBuilder.

调用 CreateDefaultBuilder(string []) 时会自动调用 AddCommandLineAddCommandLine is automatically called when CreateDefaultBuilder(string []) is called. 有关详细信息,请参阅默认配置部分。For more information, see the Default configuration section.

此外,CreateDefaultBuilder 也会加载:CreateDefaultBuilder also loads:

  • appsettings.json 和 appsettings.{Environment}.json 文件中的可选配置 。Optional configuration from appsettings.json and appsettings.{Environment}.json files.
  • 用户机密 (Secret Manager)(在开发环境中)。User secrets (Secret Manager) in the Development environment.
  • 环境变量。Environment variables.

CreateDefaultBuilder 最后添加命令行配置提供程序。CreateDefaultBuilder adds the Command-line Configuration Provider last. 在运行时传递的命令行参数会替代由其他提供程序设置的配置。Command-line arguments passed at runtime override configuration set by the other providers.

CreateDefaultBuilder 在构造主机时起作用。CreateDefaultBuilder acts when the host is constructed. 因此,CreateDefaultBuilder 激活的命令行配置可能会影响主机的配置方式。Therefore, command-line configuration activated by CreateDefaultBuilder can affect how the host is configured.

对于基于 ASP.NET Core 模板的应用,CreateDefaultBuilder 已调用 AddCommandLineFor apps based on the ASP.NET Core templates, AddCommandLine has already been called by CreateDefaultBuilder. 若要添加其他配置提供程序并保持能够用命令行参数替代这些提供程序的配置,请在 ConfigureAppConfiguration 中调用应用的其他提供程序,并最后调用 AddCommandLineTo add additional configuration providers and maintain the ability to override configuration from those providers with command-line arguments, call the app's additional providers in ConfigureAppConfiguration and call AddCommandLine last.

.ConfigureAppConfiguration((hostingContext, config) =>
{
    // Call other providers here
    config.AddCommandLine(args);
})

示例Example

示例应用利用静态便捷方法 CreateDefaultBuilder 来生成主机,其中包括一个对 AddCommandLine 的调用。The sample app takes advantage of the static convenience method CreateDefaultBuilder to build the host, which includes a call to AddCommandLine.

  1. 在项目的目录中打开命令提示符。Open a command prompt in the project's directory.
  2. dotnet run 命令提供命令行参数 dotnet run CommandLineKey=CommandLineValueSupply a command-line argument to the dotnet run command, dotnet run CommandLineKey=CommandLineValue.
  3. 应用运行后,在 http://localhost:5000 打开应用的浏览器。After the app is running, open a browser to the app at http://localhost:5000.
  4. 观察输出是否包含提供给 dotnet run 的配置命令行参数的键值对。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. 如果使用等号(例如 CommandLineKey=),则不需要该值。The value isn't required if an equals sign is used (for example, CommandLineKey=).

| 键前缀Key prefix | 示例Example | | --- title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'
  • 'Identity''Identity'
  • 'Let's Encrypt''Let's Encrypt'
  • 'Razor''Razor'
  • 'SignalR' uid:'SignalR' uid:

------------ | --- title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:------------ | --- title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'
  • 'Identity''Identity'
  • 'Let's Encrypt''Let's Encrypt'
  • 'Razor''Razor'
  • 'SignalR' uid:'SignalR' uid:

--------------------------- | | 无前缀 | CommandLineKey1=value1 | | 双破折号 (--) | --CommandLineKey2=value2--CommandLineKey2 value2 | | 正斜杠 (/) | /CommandLineKey3=value3/CommandLineKey3 value3 |--------------------------- | | 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=value1 --CommandLineKey2=value2 /CommandLineKey3=value3
dotnet run --CommandLineKey1 value1 /CommandLineKey2 value2
dotnet run CommandLineKey1= CommandLineKey2=value2

交换映射Switch mappings

交换映射支持键名替换逻辑。Switch mappings allow key name replacement logic. 使用 ConfigurationBuilder 手动构建配置时,需要为 AddCommandLine 方法提供交换替换字典。When manually building configuration with a ConfigurationBuilder, provide a dictionary of switch replacements to the 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.

创建交换映射字典。Create a switch mappings dictionary. 在以下示例中,创建了两个交换映射:In the following example, two switch mappings are created:

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

生成主机后,使用交换映射字典来调用 AddCommandLineWhen the host is built, call AddCommandLine with the switch mappings dictionary:

.ConfigureAppConfiguration((hostingContext, config) =>
{
    config.AddCommandLine(args, _switchMappings);
})

对于使用交换映射的应用,调用 CreateDefaultBuilder 不应传递参数。For apps that use switch mappings, the call to CreateDefaultBuilder shouldn't pass arguments. CreateDefaultBuilder 方法的 AddCommandLine 调用不包括映射的交换,并且无法将交换映射字典传递给 CreateDefaultBuilderThe CreateDefaultBuilder method's AddCommandLine call doesn't include mapped switches, and there's no way to pass the switch mapping dictionary to CreateDefaultBuilder. 解决方案不是将参数传递给 CreateDefaultBuilder,而是允许 ConfigurationBuilder 方法的 AddCommandLine 方法处理参数和交换映射字典。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.

创建交换映射字典后,它将包含下表所示的数据。After the switch mappings dictionary is created, it contains the data shown in the following table.

| Key | “值”Value | | --- title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'
  • 'Identity''Identity'
  • 'Let's Encrypt''Let's Encrypt'
  • 'Razor''Razor'
  • 'SignalR' uid:'SignalR' uid:

----- | --- title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:----- | --- title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'
  • 'Identity''Identity'
  • 'Let's Encrypt''Let's Encrypt'
  • 'Razor''Razor'
  • 'SignalR' uid:'SignalR' uid:

--------- | | -CLKey1 | CommandLineKey1 | | -CLKey2 | CommandLineKey2 |--------- | | -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 | | --- title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'
  • 'Identity''Identity'
  • 'Let's Encrypt''Let's Encrypt'
  • 'Razor''Razor'
  • 'SignalR' uid:'SignalR' uid:

--------- | --- title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:--------- | --- title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'
  • 'Identity''Identity'
  • 'Let's Encrypt''Let's Encrypt'
  • 'Razor''Razor'
  • 'SignalR' uid:'SignalR' uid:

---- | | CommandLineKey1 | value1 | | CommandLineKey2 | value2 |---- | | CommandLineKey1 | value1 | | CommandLineKey2 | value2 |

环境变量配置提供程序Environment Variables Configuration Provider

EnvironmentVariablesConfigurationProvider 在运行时从环境变量键值对加载配置。The EnvironmentVariablesConfigurationProvider loads configuration from environment variable key-value pairs at runtime.

要激活环境变量配置,请在 ConfigurationBuilder 的实例上调用 AddEnvironmentVariables 扩展方法。To activate environment variables configuration, call the AddEnvironmentVariables extension method on an instance of ConfigurationBuilder.

所有平台上的环境变量分层键都不支持 : 分隔符。The : separator doesn't work with environment variable hierarchical keys on all platforms. __(双下划线):__, the double underscore, is:

  • 受所有平台支持。Supported by all platforms. 例如,Bash 不支持 : 分隔符,但支持 __For example, the : separator is not supported by Bash, but __ is.
  • 自动替换为 :Automatically replaced by a :

借助 Azure 应用服务,可在 Azure 门户中设置使用环境变量配置提供程序替代应用配置的环境变量。Azure App Service permits setting environment variables in the Azure Portal that can override app configuration using the Environment Variables Configuration Provider. 有关详细信息,请参阅 Azure 应用:使用 Azure 门户替代应用配置For more information, see Azure Apps: Override app configuration using the Azure Portal.

如果使用 Web 主机初始化新的主机生成器,且调用 CreateDefaultBuilder,则使用 AddEnvironmentVariables主机配置加载前缀为 ASPNETCORE_ 的环境变量。AddEnvironmentVariables is used to load environment variables prefixed with ASPNETCORE_ for host configuration when a new host builder is initialized with the Web Host and CreateDefaultBuilder is called. 有关详细信息,请参阅默认配置部分。For more information, see the Default configuration section.

此外,CreateDefaultBuilder 也会加载:CreateDefaultBuilder also loads:

  • 来自没有前缀的环境变量的应用配置,方法是通过调用不带前缀的 AddEnvironmentVariablesApp configuration from unprefixed environment variables by calling AddEnvironmentVariables without a prefix.
  • appsettings.json 和 appsettings.{Environment}.json 文件中的可选配置 。Optional configuration from appsettings.json and appsettings.{Environment}.json files.
  • 用户机密 (Secret Manager)(在开发环境中)。User secrets (Secret Manager) in the Development environment.
  • 命令行参数。Command-line arguments.

环境变量配置提供程序是在配置已根据用户机密和 appsettings 文件建立后调用。The Environment Variables Configuration Provider is called after configuration is established from user secrets and appsettings files. 在此位置调用提供程序允许在运行时读取的环境变量替代由用户机密和 appsettings 文件设置的配置。Calling the provider in this position allows the environment variables read at runtime to override configuration set by user secrets and appsettings files.

要从其他环境变量提供应用配置,请在 ConfigureAppConfiguration 中调用应用的其他提供程序,并使用前缀调用 AddEnvironmentVariablesTo provide app configuration from additional environment variables, call the app's additional providers in ConfigureAppConfiguration and call AddEnvironmentVariables with the prefix:

.ConfigureAppConfiguration((hostingContext, config) =>
{
    config.AddEnvironmentVariables(prefix: "PREFIX_");
})

最后调用 AddEnvironmentVariables让带给定前缀的环境变量可替代其他提供程序中的值。Call AddEnvironmentVariables last to allow environment variables with the given prefix to override values from other providers.

示例Example

示例应用利用静态便捷方法 CreateDefaultBuilder 来生成主机,其中包括一个对 AddEnvironmentVariables 的调用。The sample app takes advantage of the static convenience method CreateDefaultBuilder to build the host, which includes a call to AddEnvironmentVariables.

  1. 运行示例应用。Run the sample app. http://localhost:5000 打开应用的浏览器。Open a browser to the app at http://localhost:5000.
  2. 观察输出是否包含环境变量 ENVIRONMENT 的键值对。Observe that the output contains the key-value pair for the environment variable ENVIRONMENT. 该值反映了应用运行的环境,在本地运行时通常为 DevelopmentThe 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. 请参阅示例应用的“Pages/Index.cshtml.cs”文件。See the sample app's Pages/Index.cshtml.cs file.

要公开应用可用的所有环境变量,请将 Pages/Index.cshtml.cs 中的 FilteredConfiguration 更改为以下内容:To expose all of the environment variables available to the app, change the FilteredConfiguration in Pages/Index.cshtml.cs to the following:

FilteredConfiguration = _config.AsEnumerable();

前缀Prefixes

AddEnvironmentVariables 方法提供前缀时,将筛选加载到应用的配置中的环境变量。Environment variables loaded into the app's configuration are filtered when supplying a prefix to the AddEnvironmentVariables method. 例如,要筛选前缀 CUSTOM_ 上的环境变量,请将前缀提供给配置提供程序: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.

若已创建主机生成器,则主机配置由环境变量提供。When the host builder is created, host configuration is provided by environment variables. 有关用于这些环境变量的前缀的详细信息,请参阅默认配置部分。For more information on the prefix used for these environment variables, see the Default configuration section.

连接字符串前缀Connection string prefixes

针对为应用环境配置 Azure 连接字符串所涉及的四个连接字符串环境变量,配置 API 具有特殊的处理规则。The Configuration API has special processing rules for four connection string environment variables involved in configuring Azure connection strings for the app environment. 如果没有向 AddEnvironmentVariables 提供前缀,则具有表中所示前缀的环境变量将加载到应用中。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 | | --- title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'
  • 'Identity''Identity'
  • 'Let's Encrypt''Let's Encrypt'
  • 'Razor''Razor'
  • 'SignalR' uid:'SignalR' uid:

------------ | --- title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:------------ | --- title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'
  • 'Identity''Identity'
  • 'Let's Encrypt''Let's Encrypt'
  • 'Razor''Razor'
  • 'SignalR' uid:'SignalR' uid:

---- | | CUSTOMCONNSTR_ | 自定义提供程序 | | MYSQLCONNSTR_ | MySQL | | SQLAZURECONNSTR_ | Azure SQL 数据库 | | SQLCONNSTR_ | SQL Server |---- | | 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:

  • 通过删除环境变量前缀并添加配置键节 (ConnectionStrings) 来创建配置键。The configuration key is created by removing the environment variable prefix and adding a configuration key section (ConnectionStrings).
  • 创建一个新的配置键值对,表示数据库连接提供程序(CUSTOMCONNSTR_ 除外,它没有声明的提供程序)。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 | | --- title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'
  • 'Identity''Identity'
  • 'Let's Encrypt''Let's Encrypt'
  • 'Razor''Razor'
  • 'SignalR' uid:'SignalR' uid:

------------ | --- title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:------------ | --- title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'
  • 'Identity''Identity'
  • 'Let's Encrypt''Let's Encrypt'
  • 'Razor''Razor'
  • 'SignalR' uid:'SignalR' uid:

-------------- | --- title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:-------------- | --- title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'
  • 'Identity''Identity'
  • 'Let's Encrypt''Let's Encrypt'
  • 'Razor''Razor'
  • 'SignalR' uid:'SignalR' uid:

---------------------------------------- | | CUSTOMCONNSTR_{KEY} | ConnectionStrings:{KEY} | 配置条目未创建。---------------------------------------- | | CUSTOMCONNSTR_{KEY} | ConnectionStrings:{KEY} | Configuration entry not created. | | MYSQLCONNSTR_{KEY} | ConnectionStrings:{KEY} | 键:ConnectionStrings:{KEY}_ProviderName| | MYSQLCONNSTR_{KEY} | ConnectionStrings:{KEY} | Key: ConnectionStrings:{KEY}_ProviderName:
值:MySql.Data.MySqlClient | | SQLAZURECONNSTR_{KEY} | ConnectionStrings:{KEY} | 键:ConnectionStrings:{KEY}_ProviderNameValue: MySql.Data.MySqlClient | | SQLAZURECONNSTR_{KEY} | ConnectionStrings:{KEY} | Key: ConnectionStrings:{KEY}_ProviderName:
值:System.Data.SqlClient | | SQLCONNSTR_{KEY} | ConnectionStrings:{KEY} | 键:ConnectionStrings:{KEY}_ProviderNameValue: System.Data.SqlClient | | SQLCONNSTR_{KEY} | ConnectionStrings:{KEY} | Key: ConnectionStrings:{KEY}_ProviderName:
值:System.Data.SqlClient |Value: System.Data.SqlClient |

示例Example

在服务器上创建了一个自定义连接字符串环境变量:A custom connection string environment variable is created on the server:

  • 名称:CUSTOMCONNSTR_ReleaseDBName: CUSTOMCONNSTR_ReleaseDB
  • 值:Data Source=ReleaseSQLServer;Initial Catalog=MyReleaseDB;Integrated Security=TrueValue: Data Source=ReleaseSQLServer;Initial Catalog=MyReleaseDB;Integrated Security=True

如果 IConfiguration 已引入并分配给名为 _config 的字段,请读取值:If IConfiguration is injected and assigned to a field named _config, read the value:

_config["ConnectionStrings:ReleaseDB"]

文件配置提供程序File Configuration Provider

FileConfigurationProvider 是从文件系统加载配置的基类。FileConfigurationProvider is the base class for loading configuration from the file system. 以下配置提供程序专用于特定文件类型:The following configuration providers are dedicated to specific file types:

INI 配置提供程序INI Configuration Provider

IniConfigurationProvider 在运行时从 INI 文件键值对加载配置。The IniConfigurationProvider loads configuration from INI file key-value pairs at runtime.

若要激活 INI 文件配置,请在 ConfigurationBuilder 的实例上调用 AddIniFile 扩展方法。To activate INI file configuration, call the AddIniFile extension method on an instance of ConfigurationBuilder.

冒号可用作 INI 文件配置中的节分隔符。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.
  • IFileProvider 用于访问该文件。The IFileProvider used to access the file.

构建主机时调用 ConfigureAppConfiguration 以指定应用的配置:Call ConfigureAppConfiguration when building the host to specify the app's configuration:

.ConfigureAppConfiguration((hostingContext, config) =>
{
    config.AddIniFile(
        "config.ini", optional: true, reloadOnChange: true);
})

INI 配置文件的通用示例: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

以前的配置文件使用 value 加载以下键:The previous configuration file loads the following keys with value:

  • section0:key0section0:key0
  • section0:key1section0:key1
  • section1:subsection:keysection1:subsection:key
  • section2:subsection0:keysection2:subsection0:key
  • section2:subsection1:keysection2:subsection1:key

JSON 配置提供程序JSON Configuration Provider

JsonConfigurationProvider 在运行时期间从 JSON 文件键值对加载配置。The JsonConfigurationProvider loads configuration from JSON file key-value pairs during runtime.

若要激活 JSON 文件配置,请在 ConfigurationBuilder 的实例上调用 AddJsonFile 扩展方法。To activate JSON file configuration, call the AddJsonFile extension method on an instance of ConfigurationBuilder.

重载允许指定:Overloads permit specifying:

  • 文件是否可选。Whether the file is optional.
  • 如果文件更改,是否重载配置。Whether the configuration is reloaded if the file changes.
  • IFileProvider 用于访问该文件。The IFileProvider used to access the file.

使用 CreateDefaultBuilder 初始化新的主机生成器时,会自动调用两次 AddJsonFileAddJsonFile is automatically called twice when a new host builder is initialized with CreateDefaultBuilder. 调用该方法来从以下文件加载配置:The method is called to load configuration from:

  • appsettings.json:先读取此文件。appsettings.json: This file is read first. 该文件的环境版本可以替代 appsettings.json 文件提供的值。The environment version of the file can override the values provided by the appsettings.json file.
  • appsettings.{Environment}.json:文件的环境版本是根据 IHostingEnvironment.EnvironmentName 加载的。appsettings.{Environment}.json: The environment version of the file is loaded based on the IHostingEnvironment.EnvironmentName.

有关详细信息,请参阅默认配置部分。For more information, see the Default configuration section.

此外,CreateDefaultBuilder 也会加载:CreateDefaultBuilder also loads:

首先建立 JSON 配置提供程序。The JSON Configuration Provider is established first. 因此,用户机密、环境变量和命令行参数会替代由 appsettings 文件设置的配置。Therefore, user secrets, environment variables, and command-line arguments override configuration set by the appsettings files.

构建主机时调用 ConfigureAppConfiguration 以指定除 appsettings.json 和 appsettings.{Environment}.json 以外的文件的应用配置: Call ConfigureAppConfiguration when building the host to specify the app's configuration for files other than appsettings.json and appsettings.{Environment}.json:

.ConfigureAppConfiguration((hostingContext, config) =>
{
    config.AddJsonFile(
        "config.json", optional: true, reloadOnChange: true);
})

示例Example

示例应用利用静态便捷方法 CreateDefaultBuilder 来生成主机,其中包括两个对 AddJsonFile 的调用:The sample app takes advantage of the static convenience method CreateDefaultBuilder to build the host, which includes two calls to AddJsonFile:

  • 第一次调用 AddJsonFile 会从 appsettings 加载配置:The first call to AddJsonFile loads configuration from appsettings.json:

    {
      "Logging": {
        "LogLevel": {
          "Default": "Warning"
        }
      },
      "AllowedHosts": "*"
    }
    
  • 第二次调用 AddJsonFile 会从 appsettings.{Environment}.json 加载配置。The second call to AddJsonFile loads configuration from appsettings.{Environment}.json. 对于示例应用中的 appsettings.Development.json,将加载以下文件:For appsettings.Development.json in the sample app, the following file is loaded:

    {
      "Logging": {
        "LogLevel": {
          "Default": "Debug",
          "System": "Information",
          "Microsoft": "Information"
        }
      }
    }
    
  1. 运行示例应用。Run the sample app. http://localhost:5000 打开应用的浏览器。Open a browser to the app at http://localhost:5000.
  2. 输出包含配置的键值对(由应用的环境而定)。The output contains key-value pairs for the configuration based on the app's environment. 在开发环境中运行应用时,键 Logging:LogLevel:Default 的日志级别为 DebugThe log level for the key Logging:LogLevel:Default is Debug when running the app in the Development environment.
  3. 再次在生产环境中运行示例应用:Run the sample app again in the Production environment:
    1. 打开 Properties/launchSettings.json 文件。Open the Properties/launchSettings.json file.
    2. ConfigurationSample 配置文件中,将 ASPNETCORE_ENVIRONMENT 环境变量的值更改为 ProductionIn the ConfigurationSample profile, change the value of the ASPNETCORE_ENVIRONMENT environment variable to Production.
    3. 保存文件,然后在命令外壳中使用 dotnet run 运行应用。Save the file and run the app with dotnet run in a command shell.
  4. appsettings.Development.json 中的设置不再替代 appsettings.json 中的设置 。The settings in the appsettings.Development.json no longer override the settings in appsettings.json. Logging:LogLevel:Default 的日志级别为 WarningThe log level for the key Logging:LogLevel:Default is Warning.

XML 配置提供程序XML Configuration Provider

XmlConfigurationProvider 在运行时从 XML 文件键值对加载配置。The XmlConfigurationProvider loads configuration from XML file key-value pairs at runtime.

若要激活 XML 文件配置,请在 ConfigurationBuilder 的实例上调用 AddXmlFile 扩展方法。To activate XML file configuration, call the AddXmlFile extension method on an instance of ConfigurationBuilder.

重载允许指定:Overloads permit specifying:

  • 文件是否可选。Whether the file is optional.
  • 如果文件更改,是否重载配置。Whether the configuration is reloaded if the file changes.
  • IFileProvider 用于访问该文件。The IFileProvider used to access the file.

创建配置键值对时,将忽略配置文件的根节点。The root node of the configuration file is ignored when the configuration key-value pairs are created. 不要在文件中指定文档类型定义 (DTD) 或命名空间。Don't specify a Document Type Definition (DTD) or namespace in the file.

构建主机时调用 ConfigureAppConfiguration 以指定应用的配置:Call ConfigureAppConfiguration when building the host to specify the app's configuration:

.ConfigureAppConfiguration((hostingContext, config) =>
{
    config.AddXmlFile(
        "config.xml", optional: true, reloadOnChange: true);
})

XML 配置文件可以为重复节使用不同的元素名称: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>

以前的配置文件使用 value 加载以下键:The previous configuration file loads the following keys with value:

  • section0:key0section0:key0
  • section0:key1section0:key1
  • section1:key0section1:key0
  • section1:key1section1:key1

如果使用 name 属性来区分元素,则使用相同元素名称的重复元素可以正常工作: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>

以前的配置文件使用 value 加载以下键:The previous configuration file loads the following keys with value:

  • section:section0:key:key0section:section0:key:key0
  • section:section0:key:key1section:section0:key:key1
  • section:section1:key:key0section:section1:key:key0
  • section:section1:key:key1section:section1:key: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>

以前的配置文件使用 value 加载以下键:The previous configuration file loads the following keys with value:

  • key:attributekey:attribute
  • section:key:attributesection:key:attribute

Key-per-file 配置提供程序Key-per-file Configuration Provider

KeyPerFileConfigurationProvider 使用目录的文件作为配置键值对。The KeyPerFileConfigurationProvider uses a directory's files as configuration key-value pairs. 该键是文件名。The key is the file name. 该值包含文件的内容。The value contains the file's contents. Key-per-file 配置提供程序用于 Docker 托管方案。The Key-per-file Configuration Provider is used in Docker hosting scenarios.

若要激活 Key-per-file 配置,请在 ConfigurationBuilder 的实例上调用 AddKeyPerFile 扩展方法。To activate key-per-file configuration, call the AddKeyPerFile extension method on an instance of ConfigurationBuilder. 文件的 directoryPath 必须是绝对路径。The directoryPath to the files must be an absolute path.

重载允许指定:Overloads permit specifying:

  • 配置源的 Action<KeyPerFileConfigurationSource> 委托。An Action<KeyPerFileConfigurationSource> 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. 例如,文件名 Logging__LogLevel__System 生成配置键 Logging:LogLevel:SystemFor example, the file name Logging__LogLevel__System produces the configuration key Logging:LogLevel:System.

构建主机时调用 ConfigureAppConfiguration 以指定应用的配置:Call ConfigureAppConfiguration when building the host to specify the app's configuration:

.ConfigureAppConfiguration((hostingContext, config) =>
{
    var path = Path.Combine(
        Directory.GetCurrentDirectory(), "path/to/files");
    config.AddKeyPerFile(directoryPath: path, optional: true);
})

内存配置提供程序Memory Configuration Provider

MemoryConfigurationProvider 使用内存中集合作为配置键值对。The MemoryConfigurationProvider uses an in-memory collection as configuration key-value pairs.

若要激活内存中集合配置,请在 ConfigurationBuilder 的实例上调用 AddInMemoryCollection 扩展方法。To activate in-memory collection configuration, call the AddInMemoryCollection extension method on an instance of ConfigurationBuilder.

可以使用 IEnumerable<KeyValuePair<String,String>> 初始化配置提供程序。The configuration provider can be initialized with an IEnumerable<KeyValuePair<String,String>>.

构建主机时调用 ConfigureAppConfiguration 以指定应用的配置。Call ConfigureAppConfiguration when building the host to specify the app's configuration.

在下面的示例中,创建了配置字典:In the following example, a configuration dictionary is created:

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

通过 AddInMemoryCollection 的调用使用字典,以提供配置:The dictionary is used with a call to AddInMemoryCollection to provide the configuration:

.ConfigureAppConfiguration((hostingContext, config) =>
{
    config.AddInMemoryCollection(_dict);
})

GetValueGetValue

ConfigurationBinder.GetValue<T> 从配置中提取一个具有指定键的值,并将它转换为指定的非集合类型。ConfigurationBinder.GetValue<T> extracts a single value from configuration with a specified key and converts it to the specified noncollection type. 重载接受默认值。An overload accepts a default value.

如下示例中:The following example:

  • 使用键 NumberKey 从配置中提取字符串值。Extracts the string value from configuration with the key NumberKey. 如果在配置键中找不到 NumberKey,则使用默认值 99If NumberKey isn't found in the configuration keys, the default value of 99 is used.
  • 键入值作为 intTypes the value as an int.
  • 存储 NumberConfig 属性中的值,以供页面使用。Stores the value in the NumberConfig property for use by the page.
public class IndexModel : PageModel
{
    public IndexModel(IConfiguration config)
    {
        _config = config;
    }

    public int NumberConfig { get; private set; }

    public void OnGet()
    {
        NumberConfig = _config.GetValue<int>("NumberKey", 99);
    }
}

GetSection、GetChildren 和 ExistsGetSection, GetChildren, and Exists

对于下面的示例,请考虑以下 JSON 文件。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:key0section0:key0
  • section0:key1section0:key1
  • section1:key0section1:key0
  • section1:key1section1:key1
  • section2:subsection0:key0section2:subsection0:key0
  • section2:subsection0:key1section2:subsection0:key1
  • section2:subsection1:key0section2:subsection1:key0
  • section2:subsection1:key1section2:subsection1:key1

GetSectionGetSection

IConfiguration.GetSection 使用指定的子节键提取配置子节。IConfiguration.GetSection extracts a configuration subsection with the specified subsection key.

若要返回仅包含 section1 中键值对的 IConfigurationSection,请调用 GetSection 并提供节名称:To return an IConfigurationSection containing only the key-value pairs in section1, call GetSection and supply the section name:

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

configSection 不具有值,只有密钥和路径。The configSection doesn't have a value, only a key and a path.

同样,若要获取 section2:subsection0 中键的值,请调用 GetSection 并提供节路径:Similarly, to obtain the values for keys in section2:subsection0, call GetSection and supply the section path:

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

GetSection 永远不会返回 nullGetSection never returns null. 如果找不到匹配的节,则返回空 IConfigurationSectionIf a matching section isn't found, an empty IConfigurationSection is returned.

GetSection 返回匹配的部分时,Value 未填充。When GetSection returns a matching section, Value isn't populated. 存在该部分时,返回一个 KeyPath 部分。A Key and Path are returned when the section exists.

GetChildrenGetChildren

section2 上调用 IConfiguration.GetChildren 会获得 IEnumerable<IConfigurationSection>,其中包括:A call to IConfiguration.GetChildren on section2 obtains an IEnumerable<IConfigurationSection> that includes:

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

var children = configSection.GetChildren();

存在Exists

使用 ConfigurationExtensions.Exists 确定配置节是否存在:Use ConfigurationExtensions.Exists to determine if a configuration section exists:

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

给定示例数据,sectionExistsfalse,因为配置数据中没有 section2:subsection2 节。Given the example data, sectionExists is false because there isn't a section2:subsection2 section in the configuration data.

绑定至对象图Bind to an object graph

Bind 能够绑定整个 POCO 对象图。Bind is capable of binding an entire POCO object graph. 与绑定简单对象一样,只绑定公共读取/写入属性。As with binding a simple object, only public read/write properties are bound.

该示例包含 TvShow 模型,其对象图包含 MetadataActors 类 (Models/TvShow.cs):The sample contains a TvShow model whose object graph includes Metadata and Actors classes (Models/TvShow.cs):

public class TvShow
{
    public Metadata Metadata { get; set; }
    public Actors Actors { get; set; }
    public string Legal { get; set; }
}

public class Metadata
{
    public string Series { get; set; }
    public string Title { get; set; }
    public DateTime AirDate { get; set; }
    public int Episodes { get; set; }
}

public class Actors
{
    public string Names { get; set; }
}

示例应用有一个包含配置数据的 tvshow.xml 文件:The sample app has a tvshow.xml file containing the configuration data:

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
  <tvshow>
    <metadata>
      <series>Dr. Who</series>
      <title>The Sun Makers</title>
      <airdate>11/26/1977</airdate>
      <episodes>4</episodes>
    </metadata>
    <actors>
      <names>Tom Baker, Louise Jameson, John Leeson</names>
    </actors>
    <legal>(c)1977 BBC https://www.bbc.co.uk/programmes/b006q2x0</legal>
  </tvshow>
</configuration>

使用 Bind 方法将配置绑定到整个 TvShow 对象图。Configuration is bound to the entire TvShow object graph with the Bind method. 将绑定实例分配给用于呈现的属性:The bound instance is assigned to a property for rendering:

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

ConfigurationBinder.Get<T> 绑定并返回指定的类型。ConfigurationBinder.Get<T> binds and returns the specified type. Get<T> 比使用 Bind 更方便。Get<T> is more convenient than using Bind. 以下代码演示了如何通过前述示例使用 Get<T>The following code shows how to use Get<T> with the preceding example:

TvShow = _config.GetSection("tvshow").Get<TvShow>();

将数组绑定至类Bind an array to a class

示例应用演示了本部分中介绍的概念。The sample app demonstrates the concepts explained in this section.

Bind 支持使用配置键中的数组索引将数组绑定到对象。The Bind supports binding arrays to objects using array indices in configuration keys. 公开数字键段(:0::1:、… :{n}:)的任何数组格式都能够与 POCO 类数组进行数组绑定。Any array format that exposes a numeric key segment (:0:, :1:, … :{n}:) is capable of array binding to a POCO class array.

备注

绑定是按约定提供的。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 | | :--- title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'
  • 'Identity''Identity'
  • 'Let's Encrypt''Let's Encrypt'
  • 'Razor''Razor'
  • 'SignalR' uid:'SignalR' uid:

-------: | :----: | | array:entries:0 | value0 | | array:entries:1 | value1 | | array:entries:2 | value2 | | array:entries:4 | value4 | | array:entries:5 | value5 |-------: | :----: | | array:entries:0 | value0 | | array:entries:1 | value1 | | array:entries:2 | value2 | | array:entries:4 | value4 | | array:entries:5 | value5 |

使用内存配置提供程序在示例应用中加载这些键和值:These keys and values are loaded in the sample app using the Memory Configuration Provider:

public class Program
{
    public static Dictionary<string, string> arrayDict = 
        new Dictionary<string, string>
        {
            {"array:entries:0", "value0"},
            {"array:entries:1", "value1"},
            {"array:entries:2", "value2"},
            {"array:entries:4", "value4"},
            {"array:entries:5", "value5"}
        };

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

    public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
        WebHost.CreateDefaultBuilder(args)
            .ConfigureAppConfiguration((hostingContext, config) =>
            {
                config.AddInMemoryCollection(arrayDict);
                config.AddJsonFile(
                    "json_array.json", optional: false, reloadOnChange: false);
                config.AddJsonFile(
                    "starship.json", optional: false, reloadOnChange: false);
                config.AddXmlFile(
                    "tvshow.xml", optional: false, reloadOnChange: false);
                config.AddEFConfiguration(
                    options => options.UseInMemoryDatabase("InMemoryDb"));
                config.AddCommandLine(args);
            })
            .UseStartup<Startup>();
}

该数组跳过索引 #3 的值。The array skips a value for index #3. 配置绑定程序无法绑定 null 值,也无法在绑定对象中创建 null 条目,这在演示将此数组绑定到对象的结果时变得清晰。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.

在示例应用中,POCO 类可用于保存绑定的配置数据:In the sample app, a POCO class is available to hold the bound configuration data:

public class ArrayExample
{
    public string[] Entries { get; set; }
}

将配置数据绑定至对象:The configuration data is bound to the object:

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

还可以使用 ConfigurationBinder.Get<T> 语法,这样会得到更精简的代码:ConfigurationBinder.Get<T> syntax can also be used, which results in more compact code:

ArrayExample = _config.GetSection("array").Get<ArrayExample>();

绑定对象(ArrayExample 的实例)从配置接收数组数据。The bound object, an instance of ArrayExample, receives the array data from configuration.

| ArrayExample.Entries 索引ArrayExample.Entries Index | ArrayExample.EntriesArrayExample.Entries Value | | :--- title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'
  • 'Identity''Identity'
  • 'Let's Encrypt''Let's Encrypt'
  • 'Razor''Razor'
  • 'SignalR' uid:'SignalR' uid:

-------------: | :--- title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:-------------: | :--- title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'
  • 'Identity''Identity'
  • 'Let's Encrypt''Let's Encrypt'
  • 'Razor''Razor'
  • 'SignalR' uid:'SignalR' uid:

-------------: | | 0 | value0 | | 1 | value1 | | 2 | value2 | | 3 | value4 | | 4 | value5 |-------------: | | 0 | value0 | | 1 | value1 | | 2 | value2 | | 3 | value4 | | 4 | value5 |

绑定对象中的索引 #3 保留 array:4 配置键的配置数据及其值 value4Index #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. 无法在配置数据中保留 null 值,并且当配置键中的数组跳过一个或多个索引时,不会在绑定对象中创建 null 值条目。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.

可以在由任何在配置中生成正确键值对的配置提供程序绑定到 ArrayExample 实例之前提供索引 #3 的缺失配置项。The missing configuration item for index #3 can be supplied before binding to the ArrayExample instance by any configuration provider that produces the correct key-value pair in configuration. 如果示例包含具有缺失键值对的其他 JSON 配置提供程序,则 ArrayExample.Entries 与完整配置数组相匹配:If the sample included an additional JSON Configuration Provider with the missing key-value pair, the ArrayExample.Entries matches the complete configuration array:

missing_value.json:missing_value.json:

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

ConfigureAppConfiguration中:In ConfigureAppConfiguration:

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

将表中所示的键值对加载到配置中。The key-value pair shown in the table is loaded into configuration.

| Key | “值”Value | | :--- title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'
  • 'Identity''Identity'
  • 'Let's Encrypt''Let's Encrypt'
  • 'Razor''Razor'
  • 'SignalR' uid:'SignalR' uid:

-------: | :----: | | array:entries:3 | value3 |-------: | :----: | | array:entries:3 | value3 |

如果在 JSON 配置提供程序包含索引 #3 的条目之后绑定 ArrayExample 类实例,则 ArrayExample.Entries 数组包含该值。If the ArrayExample class instance is bound after the JSON Configuration Provider includes the entry for index #3, the ArrayExample.Entries array includes the value.

| ArrayExample.Entries 索引ArrayExample.Entries Index | ArrayExample.EntriesArrayExample.Entries Value | | :--- title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'
  • 'Identity''Identity'
  • 'Let's Encrypt''Let's Encrypt'
  • 'Razor''Razor'
  • 'SignalR' uid:'SignalR' uid:

-------------: | :--- title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:-------------: | :--- title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'
  • 'Identity''Identity'
  • 'Let's Encrypt''Let's Encrypt'
  • 'Razor''Razor'
  • 'SignalR' uid:'SignalR' uid:

-------------: | | 0 | value0 | | 1 | value1 | | 2 | value2 | | 3 | value3 | | 4 | value4 | | 5 | value5 |-------------: | | 0 | value0 | | 1 | value1 | | 2 | value2 | | 3 | value3 | | 4 | value4 | | 5 | value5 |

JSON 数组处理JSON array processing

如果 JSON 文件包含数组,则会为具有从零开始的节索引的数组元素创建配置键。If a JSON file contains an array, configuration keys are created for the array elements with a zero-based section index. 在以下配置文件中,subsection 是一个数组:In the following configuration file, subsection is an array:

{
  "json_array": {
    "key": "valueA",
    "subsection": [
      "valueB",
      "valueC",
      "valueD"
    ]
  }
}

JSON 配置提供程序将配置数据读入以下键值对:The JSON Configuration Provider reads the configuration data into the following key-value pairs:

| Key | “值”Value | | --- title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'
  • 'Identity''Identity'
  • 'Let's Encrypt''Let's Encrypt'
  • 'Razor''Razor'
  • 'SignalR' uid:'SignalR' uid:

------------ | :----: | | json_array:key | valueA | | json_array:subsection:0 | valueB | | json_array:subsection:1 | valueC | | json_array:subsection:2 | valueD |------------ | :----: | | json_array:key | valueA | | json_array:subsection:0 | valueB | | json_array:subsection:1 | valueC | | json_array:subsection:2 | valueD |

在示例应用中,以下 POCO 类可用于绑定配置键值对:In the sample app, the following POCO class is available to bind the configuration key-value pairs:

public class JsonArrayExample
{
    public string Key { get; set; }
    public string[] Subsection { get; set; }
}

绑定后,JsonArrayExample.Key 保存值 valueAAfter binding, JsonArrayExample.Key holds the value valueA. 子节值存储在 POCO 数组属性 Subsection 中。The subsection values are stored in the POCO array property, Subsection.

| JsonArrayExample.Subsection 索引JsonArrayExample.Subsection Index | JsonArrayExample.SubsectionJsonArrayExample.Subsection Value | | :--- title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'
  • 'Identity''Identity'
  • 'Let's Encrypt''Let's Encrypt'
  • 'Razor''Razor'
  • 'SignalR' uid:'SignalR' uid:

-----------------: | :--- title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:-----------------: | :--- title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'

  • 'Identity''Identity'

  • 'Let's Encrypt''Let's Encrypt'

  • 'Razor''Razor'

  • 'SignalR' uid:'SignalR' uid:

title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:title: author: description: monikerRange: ms.author: ms.custom: ms.date: no-loc:

  • 'Blazor''Blazor'
  • 'Identity''Identity'
  • 'Let's Encrypt''Let's Encrypt'
  • 'Razor''Razor'
  • 'SignalR' uid:'SignalR' uid:

-----------------: | | 0 | valueB | | 1 | valueC | | 2 | valueD |-----------------: | | 0 | valueB | | 1 | valueC | | 2 | valueD |

自定义配置提供程序Custom configuration provider

该示例应用演示了如何使用实体框架 (EF) 创建从数据库读取配置键值对的基本配置提供程序。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:

  • EF 内存中数据库用于演示目的。The EF in-memory database is used for demonstration purposes. 若要使用需要连接字符串的数据库,请实现辅助 ConfigurationBuilder 以从另一个配置提供程序提供连接字符串。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.

定义用于在数据库中存储配置值的 EFConfigurationValue 实体。Define an EFConfigurationValue entity for storing configuration values in the database.

Models/EFConfigurationValue.csModels/EFConfigurationValue.cs:

public class EFConfigurationValue
{
    public string Id { get; set; }
    public string Value { get; set; }
}

添加 EFConfigurationContext 以存储和访问配置的值。Add an EFConfigurationContext to store and access the configured values.

EFConfigurationProvider/EFConfigurationContext.csEFConfigurationProvider/EFConfigurationContext.cs:

public class EFConfigurationContext : DbContext
{
    public EFConfigurationContext(DbContextOptions options) : base(options)
    {
    }

    public DbSet<EFConfigurationValue> Values { get; set; }
}

创建用于实现 IConfigurationSource 的类。Create a class that implements IConfigurationSource.

EFConfigurationProvider/EFConfigurationSource.csEFConfigurationProvider/EFConfigurationSource.cs:

public class EFConfigurationSource : IConfigurationSource
{
    private readonly Action<DbContextOptionsBuilder> _optionsAction;

    public EFConfigurationSource(Action<DbContextOptionsBuilder> optionsAction)
    {
        _optionsAction = optionsAction;
    }

    public IConfigurationProvider Build(IConfigurationBuilder builder)
    {
        return new EFConfigurationProvider(_optionsAction);
    }
}

通过从 ConfigurationProvider 继承来创建自定义配置提供程序。Create the custom configuration provider by inheriting from ConfigurationProvider. 当数据库为空时,配置提供程序将对其进行初始化。The configuration provider initializes the database when it's empty.

EFConfigurationProvider/EFConfigurationProvider.csEFConfigurationProvider/EFConfigurationProvider.cs:

public class EFConfigurationProvider : ConfigurationProvider
{
    public EFConfigurationProvider(Action<DbContextOptionsBuilder> optionsAction)
    {
        OptionsAction = optionsAction;
    }

    Action<DbContextOptionsBuilder> OptionsAction { get; }

    // Load config data from EF DB.
    public override void Load()
    {
        var builder = new DbContextOptionsBuilder<EFConfigurationContext>();

        OptionsAction(builder);

        using (var dbContext = new EFConfigurationContext(builder.Options))
        {
            dbContext.Database.EnsureCreated();

            Data = !dbContext.Values.Any()
                ? CreateAndSaveDefaultValues(dbContext)
                : dbContext.Values.ToDictionary(c => c.Id, c => c.Value);
        }
    }

    private static IDictionary<string, string> CreateAndSaveDefaultValues(
        EFConfigurationContext dbContext)
    {
        // Quotes (c)2005 Universal Pictures: Serenity
        // https://www.uphe.com/movies/serenity
        var configValues = 
            new Dictionary<string, string>(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;
    }
}

可以使用 AddEFConfiguration 扩展方法将配置源添加到 ConfigurationBuilderAn AddEFConfiguration extension method permits adding the configuration source to a ConfigurationBuilder.

Extensions/EntityFrameworkExtensions.cs:Extensions/EntityFrameworkExtensions.cs:

public static class EntityFrameworkExtensions
{
    public static IConfigurationBuilder AddEFConfiguration(
        this IConfigurationBuilder builder, 
        Action<DbContextOptionsBuilder> optionsAction)
    {
        return builder.Add(new EFConfigurationSource(optionsAction));
    }
}

下面的代码演示如何在 Program.cs 中使用自定义的 EFConfigurationProviderThe following code shows how to use the custom EFConfigurationProvider in Program.cs:

public class Program
{
    public static Dictionary<string, string> arrayDict = 
        new Dictionary<string, string>
        {
            {"array:entries:0", "value0"},
            {"array:entries:1", "value1"},
            {"array:entries:2", "value2"},
            {"array:entries:4", "value4"},
            {"array:entries:5", "value5"}
        };

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

    public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
        WebHost.CreateDefaultBuilder(args)
            .ConfigureAppConfiguration((hostingContext, config) =>
            {
                config.AddInMemoryCollection(arrayDict);
                config.AddJsonFile(
                    "json_array.json", optional: false, reloadOnChange: false);
                config.AddJsonFile(
                    "starship.json", optional: false, reloadOnChange: false);
                config.AddXmlFile(
                    "tvshow.xml", optional: false, reloadOnChange: false);
                config.AddEFConfiguration(
                    options => options.UseInMemoryDatabase("InMemoryDb"));
                config.AddCommandLine(args);
            })
            .UseStartup<Startup>();
}

在启动期间访问配置Access configuration during startup

IConfiguration 注入 Startup 构造函数以访问 Startup.ConfigureServices 中的配置值。Inject IConfiguration into the Startup constructor to access configuration values in Startup.ConfigureServices. 若要访问 Startup.Configure 中的配置,请将 IConfiguration 直接注入方法或使用构造函数中的实例: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.

在 Razor Pages 页面或 MVC 视图中访问配置Access configuration in a Razor Pages page or MVC view

若要访问 Razor Pages 页面或 MVC 视图中的配置设置,请为 Microsoft.Extensions.Configuration namespace 命名空间添加 using 指令C# 参考:using 指令)并将 IConfiguration 注入该页面或视图。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 IConfiguration into the page or view.

在 Razor Pages 页面中: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>

在 MVC 视图中: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

通过 IHostingStartup 实现,可在启动时从应用 Startup 类之外的外部程序集向应用添加增强功能。An IHostingStartup implementation allows adding enhancements to an app at startup from an external assembly outside of the app's Startup class. 有关详细信息,请参阅 <xref:fundamentals/configuration/platform-specific-configuration>。For more information, see <xref:fundamentals/configuration/platform-specific-configuration>.

其他资源Additional resources

  • <xref:fundamentals/configuration/options>