ASP.NET Core
中的应用配置基于配置提供程序建立的键值对。 配置提供程序将配置数据从各种配置源读取到键值对:
选项模式是本主题中描述的配置概念的扩展。 选项使用类来表示相关设置的组。 有关使用选项模式的详细信息,请参阅 ASP.NET Core 中的选项模式
。
这三个包均包括在 Microsoft.AspNetCore.App 元包
中。
在配置并启动应用之前,配置并启动主机。 主机负责应用程序启动和生存期管理。 应用和主机均使用本主题中所述的配置提供程序进行配置。 主机配置键值对成为应用的全局配置的一部分。 有关在构建主机时如何使用配置提供程序以及配置源如何影响主机配置的详细信息,请参阅 ASP.NET Core 中的 Web 主机和通用主机
。
基于 ASP.NET Core dotnet new
模板的 Web 应用在生成主机时会调用 CreateDefaultBuilder
。 CreateDefaultBuilder
为应用提供默认配置。
环境变量配置提供程序
,通过前缀为 ASPNETCORE_
(例如,ASPNETCORE_ENVIRONMENT
)的环境变量提供。命令行配置提供程序
,通过命令行参数提供。文件配置提供程序
,通过 appsettings.json
提供。文件配置提供程序
,通过 appsettings.{Environment}.json
提供。Development
环境中运行时的机密管理器
。环境变量配置提供程序
,通过环境变量提供。命令行配置提供程序
,通过命令行参数提供。本主题后面将介绍配置提供程序。 有关主机和 CreateDefaultBuilder
的更多信息,请参阅 ASP.NET Core Web 主机
。
采用以下最佳实践:
详细了解如何使用多个环境
和管理使用 Secret Manager 的开发中的应用机密的安全存储
(包括使用环境变量存储敏感数据的建议)。 Secret Manager 使用文件配置提供程序将用户机密存储在本地系统上的 JSON 文件中。 本主题后面将介绍文件配置提供程序。
Azure Key Vault 是安全存储应用机密的一种选择。 有关更多信息,请参见在 ASP.NET Core 中的 azure 密钥保管库配置提供程序
。
配置 API 能够通过在配置键中使用分隔符来展平分层数据以保持分层配置数据。
在以下 JSON 文件中,两个节的结构化层次结构中存在四个键:
{
"section0": {
"key0": "value",
"key1": "value"
},
"section1": {
"key0": "value",
"key1": "value"
}
}
将文件读入配置时,将创建唯一键以保持配置源的原始分层数据结构。 使用冒号 (:
) 展平节和键以保持原始结构:
GetSection
和 GetChildren
方法可用于隔离各个节和配置数据中某节的子节。 稍后将在GetSection、GetChildren 和 Exists
中介绍这些方法。GetSection
在Microsoft.Extensions.Configuration 包中,后者在 Microsoft.AspNetCore.App 元包
中。
在应用启动时,将按照指定的配置提供程序的顺序读取配置源。
应用启动后,在更改基础设置文件时,文件配置提供程序可以重载配置。 本主题后面将介绍文件配置提供程序。
应用的依赖关系注入 (DI)
容器中提供了IConfiguration
。配置提供程序不能使用 DI,因为主机在设置这些提供程序时 DI 不可用。
配置键采用以下约定:
ConnectionString
和 connectionstring
被视为等效键。:
) 适用于所有平台。__
),并可以将其转换为冒号。--
(两个破折号)作为分隔符。 将机密加载到应用的配置中时,必须提供代码以用冒号替换破折号。ConfigurationBinder
支持使用配置键中的数组索引将数组绑定到对象。 数组绑定将在将数组绑定到类
部分中进行介绍。配置值采用以下约定:
NULL
值不能存储在配置中或绑定到对象。下表显示了 ASP.NET Core
应用可用的配置提供程序。
提供程序 | 通过以下对象提供配置… |
---|---|
Azure Key Vault 配置提供程序(安全主题) | Azure Key Vault |
命令行配置提供程序 | 命令行参数 |
自定义配置提供程序 | 自定义源 |
环境变量配置提供程序 | 环境变量 |
文件配置提供程序 | 文件(INI、JSON、XML) |
Key-per-file 配置提供程序 | 目录文件 |
内存配置提供程序 | 内存中集合 |
用户机密 (Secret Manager)(安全主题) | 用户配置文件目录中的文件 |
按照启动时指定的配置提供程序的顺序读取配置源。 本主题中所述的配置提供程序按字母顺序进行介绍,而不是按代码排列顺序进行介绍。 代码中的配置提供程序应以特定顺序排列以符合基础配置源的优先级。
配置提供程序的典型顺序为:
appsettings.json、appsettings.{Environment}.json
,其中 {Environment}
是应用的当前托管环境)Secret Manager
)(仅限开发环境中)通常的做法是将命令行配置提供程序置于一系列提供程序的末尾,以允许命令行参数替代由其他提供程序设置的配置。
在使用 CreateDefaultBuilder
初始化新的 WebHostBuilder
时,将使用此提供程序序列。 有关详细信息,请参阅Web 主机:设置主机
。
ConfigureAppConfiguration
构建主机时调用 ConfigureAppConfiguration
以指定应用的配置提供程序以及 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.SetBasePath(Directory.GetCurrentDirectory());
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>();
}
CommandLineConfigurationProvider
在运行时从命令行参数键值对加载配置。
要激活命令行配置,请在 ConfigurationBuilder
的实例上调用 AddCommandLine
扩展方法。
使用 CreateDefaultBuilder
初始化新的WebHostBuilder
时会自动调用 AddCommandLine
。 有关详细信息,请参阅Web 主机:设置主机
。
此外,CreateDefaultBuilder
也会加载:
appsettings.json
和 appsettings.{Environment}.json
的可选配置。用户机密 (Secret Manager)
(在开发环境中)。CreateDefaultBuilder
最后添加命令行配置提供程序。 在运行时传递的命令行参数会替代由其他提供程序设置的配置。
CreateDefaultBuilder
在构造主机时起作用。 因此,CreateDefaultBuilder
激活的命令行配置可能会影响主机的配置方式。
构建主机时调用 ConfigureAppConfiguration
以指定应用的配置。
CreateDefaultBuilder
已经调用了 AddCommandLine
。 如果需要提供应用配置并仍然能够使用命令行参数覆盖该配置,请在ConfigureAppConfiguration
中调用应用的其他提供程序并最后调用 AddCommandLine
。
public class Program
{
public static void Main(string[] args)
{
CreateWebHostBuilder(args).Build().Run();
}
public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.ConfigureAppConfiguration((hostingContext, config) =>
{
// Call other providers here and call AddCommandLine last.
config.AddCommandLine(args);
})
.UseStartup<Startup>();
}
直接创建 WebHostBuilder
时,请使用以下配置调用UseConfiguration
:
var config = new ConfigurationBuilder()
// Call additional providers here as needed.
// Call AddCommandLine last to allow arguments to override other configuration.
.AddCommandLine(args)
.Build();
var host = new WebHostBuilder()
.UseConfiguration(config)
.UseKestrel()
.UseStartup<Startup>();
示例
2.x 示例应用利用静态便捷方法 CreateDefaultBuilder
来构建主机,其中包括对 AddCommandLine
的调用。
dotnet run
命令提供命令行参数 dotnet run CommandLineKey=CommandLineValue
。http://localhost:5000
打开应用的浏览器。dotnet run
的配置命令行参数的键值对。该值必须后跟一个等号 (=
),否则当值后跟一个空格时,键必须具有前缀(--
或 /
)。 如果使用等号(例如,CommandLineKey=
),则该值可以为 null
。
键前缀 | 示例 |
---|---|
无前缀 | CommandLineKey1=value1 |
双划线 (-- ) |
--CommandLineKey2=value2 , --CommandLineKey2 value2 |
正斜杠 (/ ) |
/CommandLineKey3=value3 , /CommandLineKey3 value3 |
在同一命令中,不要将使用等号的命令行参数键值对与使用空格的键值对混合使用。
示例命令:
dotnet run CommandLineKey1=value1 --CommandLineKey2=value2 /CommandLineKey3=value3
dotnet run --CommandLineKey1 value1 /CommandLineKey2 value2
dotnet run CommandLineKey1= CommandLineKey2=value2
交换映射支持键名替换逻辑。 使用ConfigurationBuilder
手动构建配置时,可以为 AddCommandLine
方法提供交换替换字典。
当使用交换映射字典时,会检查字典中是否有与命令行参数提供的键匹配的键。 如果在字典中找到命令行键,则传回字典值(键替换)以将键值对设置为应用的配置。 对任何具有单划线 (-
) 前缀的命令行键而言,交换映射都是必需的。
交换映射字典键规则:
-
) 或双划线 (--
) 开头。构建主机时调用 ConfigureAppConfiguration
以指定应用的配置:
public class Program
{
public static readonly Dictionary<string, string> _switchMappings =
new Dictionary<string, string>
{
{ "-CLKey1", "CommandLineKey1" },
{ "-CLKey2", "CommandLineKey2" }
};
public static void Main(string[] args)
{
CreateWebHostBuilder(args).Build().Run();
}
// Do not pass the args to CreateDefaultBuilder
public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
WebHost.CreateDefaultBuilder()
.ConfigureAppConfiguration((hostingContext, config) =>
{
config.AddCommandLine(args, _switchMappings);
})
.UseStartup<Startup>();
}
如前面的示例所示,当使用交换映射时,对 CreateDefaultBuilder
的调用不应传递参数。 CreateDefaultBuilder
方法的 AddCommandLine
调用不包括映射的交换,并且无法将交换映射字典传递给 CreateDefaultBuilder
。 如果参数包含映射的交换并传递给 CreateDefaultBuilder
,则其 AddCommandLine
提供程序无法使用 FormatException
进行初始化。 解决方案不是将参数传递给 CreateDefaultBuilder
,而是允许 ConfigurationBuilder
方法的 AddCommandLine
方法处理参数和交换映射字典。
创建交换映射字典后,它将包含下表所示的数据。
键 | 值 |
---|---|
-CLKey1 |
CommandLineKey1 |
-CLKey2 |
CommandLineKey2 |
如果在启动应用时使用了交换映射的键,则配置将接收字典提供的密钥上的配置值:
dotnet run -CLKey1=value1 -CLKey2=value2
运行上述命令后,配置包含下表中显示的值。
键 | 值 |
---|---|
CommandLineKey1 |
value1 |
CommandLineKey2 |
value2 |
EnvironmentVariablesConfigurationProvider
在运行时从环境变量键值对加载配置。
要激活环境变量配置,请在 ConfigurationBuilder
的实例上调用AddEnvironmentVariables
扩展方法。
在环境变量中使用分层键时,冒号分隔符 (:
) 可能无法适用于所有平台。 所有平台均支持采用双下划线 (__
),并可以用冒号替换。
借助 Azure 应用服务,用户可以在 Azure 门户中设置使用环境变量配置提供程序替代应用配置的环境变量。 有关详细信息,请参阅Azure 应用:使用 Azure 门户替代应用配置
。
初始化一个新的 WebHostBuilder
时,对于前缀为 ASPNETCORE_
的环境变量,会自动调用 AddEnvironmentVariables
。 有关详细信息,请参阅 Web 主机:设置主机
。
此外,CreateDefaultBuilder
也会加载:
AddEnvironmentVariables
。用户机密 (Secret Manager)
(在开发环境中)。环境变量配置提供程序是在配置已根据用户机密和 appsettings
文件建立后调用。 在此位置调用提供程序允许在运行时读取的环境变量替代由用户机密和 appsettings
文件设置的配置。
构建主机时调用ConfigureAppConfiguration
以指定应用的配置。
如果需要从其他环境变量提供应用配置,请在ConfigureAppConfiguration
中调用应用的其他提供程序,并使用前缀调用 AddEnvironmentVariables
。
public class Program
{
public static void Main(string[] args)
{
CreateWebHostBuilder(args).Build().Run();
}
public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.ConfigureAppConfiguration((hostingContext, config) =>
{
// Call additional providers here as needed.
// Call AddEnvironmentVariables last if you need to allow environment
// variables to override values from other providers.
config.AddEnvironmentVariables(prefix: "PREFIX_");
})
.UseStartup<Startup>();
}
直接创建 WebHostBuilder
时,请使用以下配置调用UseConfiguration
:
var config = new ConfigurationBuilder()
.AddEnvironmentVariables()
.Build();
var host = new WebHostBuilder()
.UseConfiguration(config)
.UseKestrel()
.UseStartup<Startup>();
示例
2.x 示例应用利用静态便捷方法 CreateDefaultBuilder
来构建主机,其中包括对 AddEnvironmentVariables
的调用。
http://localhost:5000
打开应用的浏览器。ENVIRONMENT
的键值对。 该值反映了应用运行的环境,在本地运行时通常为 Development
。为了使应用呈现的环境变量列表简短,应用将环境变量筛选为以下列内容开头的变量:
如果希望公开应用可用的所有环境变量,请将 Pages/Index.cshtml.cs
中的 FilteredConfiguration
更改为以下内容:
FilteredConfiguration = _config.AsEnumerable();
为 AddEnvironmentVariables
方法提供前缀时,将筛选加载到应用的配置中的环境变量。 例如,要筛选前缀 CUSTOM_
上的环境变量,请将前缀提供给配置提供程序:
var config = new ConfigurationBuilder()
.AddEnvironmentVariables("CUSTOM_")
.Build();
创建配置键值对时,将去除前缀。
静态便捷方法 CreateDefaultBuilder
创建一个WebHostBuilder
以建立应用的主机。 创建 WebHostBuilder
时,它会在前缀为 ASPNETCORE_
的环境变量中找到其主机配置。
连接字符串前缀
针对为应用环境配置 Azure 连接字符串所涉及的四个连接字符串环境变量,配置 API 具有特殊的处理规则。 如果没有向 AddEnvironmentVariables
提供前缀,则具有表中所示前缀的环境变量将加载到应用中。
连接字符串前缀 | 提供程序 |
---|---|
CUSTOMCONNSTR_ |
自定义提供程序 |
MYSQLCONNSTR_ |
MySQL |
SQLAZURECONNSTR_ |
Azure SQL 数据库 |
SQLCONNSTR_ |
SQL Server |
当发现环境变量并使用表中所示的四个前缀中的任何一个加载到配置中时:
ConnectionStrings
) 来创建配置键。CUSTOMCONNSTR_
除外,它没有声明的提供程序)。环境变量键 | 转换的配置键 | 提供程序配置条目 |
---|---|---|
CUSTOMCONNSTR_ |
ConnectionStrings: |
配置条目未创建。 |
MYSQLCONNSTR_ |
ConnectionStrings: |
键:ConnectionStrings: :值: MySql.Data.MySqlClient |
SQLAZURECONNSTR_ |
ConnectionStrings: |
键:ConnectionStrings: :值: System.Data.SqlClient |
SQLCONNSTR_ |
ConnectionStrings: |
键:ConnectionStrings: :值: System.Data.SqlClient |
FileConfigurationProvider
是从文件系统加载配置的基类。 以下配置提供程序专用于特定文件类型:
IniConfigurationProvider
在运行时从 INI 文件键值对加载配置。
若要激活 INI 文件配置,请在 ConfigurationBuilder
的实例上调用AddIniFile
扩展方法。
冒号可用作 INI 文件配置中的节分隔符。
重载允许指定:
IFileProvider
用于访问该文件。构建主机时调用 ConfigureAppConfiguration
以指定应用的配置:
public class Program
{
public static void Main(string[] args)
{
CreateWebHostBuilder(args).Build().Run();
}
public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.ConfigureAppConfiguration((hostingContext, config) =>
{
config.SetBasePath(Directory.GetCurrentDirectory());
config.AddIniFile("config.ini", optional: true, reloadOnChange: true);
})
.UseStartup<Startup>();
}
基路径使用 SetBasePath
设置。 SetBasePath
在 Microsoft.Extensions.Configuration.FileExtensions 包中,后者在 Microsoft.AspNetCore.App
元包中。
直接创建 WebHostBuilder
时,请使用以下配置调用 UseConfiguration
:
var config = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddIniFile("config.ini", optional: true, reloadOnChange: true)
.Build();
var host = new WebHostBuilder()
.UseConfiguration(config)
.UseKestrel()
.UseStartup<Startup>();
基路径使用 SetBasePath
设置。 SetBasePath
在 Microsoft.Extensions.Configuration.FileExtensions 包中,后者在 Microsoft.AspNetCore.App
元包中。
INI 配置文件的通用示例:
[section0]
key0=value
key1=value
[section1]
subsection:key=value
[section2:subsection0]
key=value
[section2:subsection1]
key=value
以前的配置文件使用 value
加载以下键:
JsonConfigurationProvider
在运行时期间从 JSON 文件键值对加载配置。
若要激活 JSON 文件配置,请在ConfigurationBuilder
的实例上调用AddJsonFile
扩展方法。
重载允许指定:
IFileProvider
用于访问该文件。使用 CreateDefaultBuilder
初始化新的 WebHostBuilder
时,会自动调用 AddJsonFile
两次。 调用该方法来从以下文件加载配置:
appsettings.json
文件提供的值。IHostingEnvironment.EnvironmentName
加载文件的环境版本。有关详细信息,请参阅 Web 主机:设置主机
。
此外,CreateDefaultBuilder
也会加载:
用户机密 (Secret Manager)
(在开发环境中)。首先建立 JSON 配置提供程序。 因此,用户机密、环境变量和命令行参数会替代由 appsettings
文件设置的配置。
构建主机时调用 ConfigureAppConfiguration
以指定除 appsettings.json
和 appsettings.{Environment}.json
以外的文件的应用配置:
public class Program
{
public static void Main(string[] args)
{
CreateWebHostBuilder(args).Build().Run();
}
public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.ConfigureAppConfiguration((hostingContext, config) =>
{
config.SetBasePath(Directory.GetCurrentDirectory());
config.AddJsonFile("config.json", optional: true, reloadOnChange: true);
})
.UseStartup<Startup>();
}
基路径使用 SetBasePath
设置。 SetBasePath
在 Microsoft.Extensions.Configuration.FileExtensions 包中,后者在Microsoft.AspNetCore.App 元包
中。
直接创建 WebHostBuilder
时,请使用以下配置调用 UseConfiguration
:
var config = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("config.json", optional: true, reloadOnChange: true)
.Build();
var host = new WebHostBuilder()
.UseConfiguration(config)
.UseKestrel()
.UseStartup<Startup>();
基路径使用 SetBasePath
设置。 SetBasePath
在 Microsoft.Extensions.Configuration.FileExtensions 包中,后者在 Microsoft.AspNetCore.App 元包
中。
示例
2.x 示例应用利用静态便捷方法 CreateDefaultBuilder
来构建主机,其中包括对 AddJsonFile
的两次调用。 配置从 appsettings.json
和 appsettings.{Environment}.json
进行加载。
http://localhost:5000
打开应用的浏览器。:
) 作为分层分隔符。键 | 开发值 | 生产值 |
---|---|---|
Logging:LogLevel:System | 信息 | 信息 |
Logging:LogLevel:Microsoft | 信息 | 信息 |
Logging:LogLevel:Default | 调试 | Error |
AllowedHosts | * | * |
XmlConfigurationProvider
在运行时从 XML
文件键值对加载配置。
若要激活 XML 文件配置,请在 ConfigurationBuilder
的实例上调用 AddXmlFile
扩展方法。
重载允许指定:
IFileProvider
用于访问该文件。创建配置键值对时,将忽略配置文件的根节点。 不要在文件中指定文档类型定义 (DTD) 或命名空间。
构建主机时调用 ConfigureAppConfiguration
以指定应用的配置:
public class Program
{
public static void Main(string[] args)
{
CreateWebHostBuilder(args).Build().Run();
}
public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.ConfigureAppConfiguration((hostingContext, config) =>
{
config.SetBasePath(Directory.GetCurrentDirectory());
config.AddXmlFile("config.xml", optional: true, reloadOnChange: true);
})
.UseStartup<Startup>();
}
基路径使用 SetBasePath
设置。 SetBasePath
在 Microsoft.Extensions.Configuration.FileExtensions 包中,后者在Microsoft.AspNetCore.App 元包
中。
直接创建 WebHostBuilder
时,请使用以下配置调用UseConfiguration
:
var config = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddXmlFile("config.xml", optional: true, reloadOnChange: true)
.Build();
var host = new WebHostBuilder()
.UseConfiguration(config)
.UseKestrel()
.UseStartup<Startup>();
基路径使用 SetBasePath
设置。 SetBasePath
在 Microsoft.Extensions.Configuration.FileExtensions 包中,后者在 Microsoft.AspNetCore.App 元包
中。
XML 配置文件可以为重复节使用不同的元素名称:
<configuration>
<section0>
<key0>valuekey0>
<key1>valuekey1>
section0>
<section1>
<key0>valuekey0>
<key1>valuekey1>
section1>
configuration>
以前的配置文件使用 value
加载以下键:
如果使用 name
属性来区分元素,则使用相同元素名称的重复元素可以正常工作:
<configuration>
<section name="section0">
<key name="key0">valuekey>
<key name="key1">valuekey>
section>
<section name="section1">
<key name="key0">valuekey>
<key name="key1">valuekey>
section>
configuration>
以前的配置文件使用 value
加载以下键:
属性可用于提供值:
<configuration>
<key attribute="value" />
<section>
<key attribute="value" />
section>
configuration>
以前的配置文件使用 value
加载以下键:
KeyPerFileConfigurationProvider
使用目录的文件作为配置键值对。 该键是文件名。 该值包含文件的内容。 Key-per-file
配置提供程序用于 Docker
托管方案。
若要激活 Key-per-file
配置,请在 ConfigurationBuilder
的实例上调用 AddKeyPerFile
扩展方法。 文件的 directoryPath
必须是绝对路径。
重载允许指定:
Action
委托。双下划线字符 (__
) 用作文件名中的配置键分隔符。 例如,文件名 Logging__LogLevel__System
生成配置键 Logging:LogLevel:System
。
构建主机时调用 ConfigureAppConfiguration
以指定应用的配置:
public class Program
{
public static void Main(string[] args)
{
CreateWebHostBuilder(args).Build().Run();
}
public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.ConfigureAppConfiguration((hostingContext, config) =>
{
config.SetBasePath(Directory.GetCurrentDirectory());
var path = Path.Combine(Directory.GetCurrentDirectory(), "path/to/files");
config.AddKeyPerFile(directoryPath: path, optional: true);
})
.UseStartup<Startup>();
}
基路径使用 SetBasePath
设置。 SetBasePath
在 Microsoft.Extensions.Configuration.FileExtensions 包中,后者在 Microsoft.AspNetCore.App 元包
中。
直接创建 WebHostBuilder
时,请使用以下配置调用 UseConfiguration
:
var path = Path.Combine(Directory.GetCurrentDirectory(), "path/to/files");
var config = new ConfigurationBuilder()
.AddKeyPerFile(directoryPath: path, optional: true)
.Build();
var host = new WebHostBuilder()
.UseConfiguration(config)
.UseKestrel()
.UseStartup<Startup>();
MemoryConfigurationProvider
使用内存中集合作为配置键值对。
若要激活内存中集合配置,请在 ConfigurationBuilder
的实例上调用 AddInMemoryCollection
扩展方法。
可以使用 IEnumerable
初始化配置提供程序。
构建主机时调用 ConfigureAppConfiguration
以指定应用的配置:
public class Program
{
public static readonly Dictionary<string, string> _dict =
new Dictionary<string, string>
{
{"MemoryCollectionKey1", "value1"},
{"MemoryCollectionKey2", "value2"}
};
public static void Main(string[] args)
{
CreateWebHostBuilder(args).Build().Run();
}
public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.ConfigureAppConfiguration((hostingContext, config) =>
{
config.AddInMemoryCollection(_dict);
})
.UseStartup<Startup>();
}
直接创建 WebHostBuilder
时,请使用以下配置调用 UseConfiguration
:
var dict = new Dictionary<string, string>
{
{"MemoryCollectionKey1", "value1"},
{"MemoryCollectionKey2", "value2"}
};
var config = new ConfigurationBuilder()
.AddInMemoryCollection(dict)
.Build();
var host = new WebHostBuilder()
.UseConfiguration(config)
.UseKestrel()
.UseStartup<Startup>();
ConfigurationBinder.GetValue
从具有指定键的配置中提取一个值,并将其转换为指定类型。 如果未找到该键,则过载允许你提供默认值。
以下示例使用键 NumberKey
从配置中提取字符串值,键入该值作为 int
,并将值存储在变量 intValue
中。 如果在配置键中找不到 NumberKey
,则 intValue
会接收 99
的默认值:
var intValue = config.GetValue<int>("NumberKey", 99);
GetSection、GetChildren
和 Exists
对于下面的示例,请考虑以下 JSON 文件。 在两个节中找到四个键,其中一个包含一对子节:
{
"section0": {
"key0": "value",
"key1": "value"
},
"section1": {
"key0": "value",
"key1": "value"
},
"section2": {
"subsection0" : {
"key0": "value",
"key1": "value"
},
"subsection1" : {
"key0": "value",
"key1": "value"
}
}
}
将文件读入配置时,会创建以下唯一的分层键来保存配置值:
IConfiguration.GetSection
使用指定的子节键提取配置子节。 GetSection
在 Microsoft.Extensions.Configuration 包中,后者在 Microsoft.AspNetCore.App 元包
中。
若要返回仅包含 section1
中键值对的 IConfigurationSection
,请调用 GetSection
并提供节名称:
var configSection = _config.GetSection("section1");
configSection
不具有值,只有密钥和路径。
同样,若要获取 section2:subsection0
中键的值,请调用 GetSection
并提供节路径:
var configSection = _config.GetSection("section2:subsection0");
GetSection
永远不会返回 null
。 如果找不到匹配的节,则返回空 IConfigurationSection
。
当 GetSection
返回匹配的部分时,Value
未填充。 存在该部分时,返回一个 Key
和 Path
部分。
在 section2
上调用 IConfiguration.GetChildren
会获得 IEnumerable
,其中包括:
subsection0
subsection1
var configSection = _config.GetSection("section2");
var children = configSection.GetChildren();
使用 ConfigurationExtensions.Exists
确定配置节是否存在:
var sectionExists = _config.GetSection("section2:subsection2").Exists();
给定示例数据,sectionExists
为 false
,因为配置数据中没有 section2:subsection2
节。
可以使用选项模式将配置绑定到表示相关设置组的类。 有关更多信息,请参见ASP.NET Core 中的选项模式
。
配置值作为字符串返回,但调用 Bind
可以构造 POCO 对象。 Bind
在 Microsoft.Extensions.Configuration.Binder 包中,后者在 Microsoft.AspNetCore.App 元包
中。
示例应用包含 Starship
模型 (Models/Starship.cs):
public class Starship
{
public string Name { get; set; }
public string Registry { get; set; }
public string Class { get; set; }
public decimal Length { get; set; }
public bool Commissioned { get; set; }
}
当示例应用使用 JSON 配置提供程序加载配置时,starship.json 文件的 starship
节会创建配置:
{
"starship": {
"name": "USS Enterprise",
"registry": "NCC-1701",
"class": "Constitution",
"length": 304.8,
"commissioned": false
},
"trademark": "Paramount Pictures Corp. http://www.paramount.com"
}
创建以下配置键值对:
键 | 值 |
---|---|
starship:name | USS Enterprise |
starship:registry | NCC-1701 |
starship:class | Constitution |
starship:length | 304.8 |
starship:commissioned | False |
trademark | Paramount Pictures Corp. http://www.paramount.com |
示例应用使用 starship
键调用 GetSection
。 starship
键值对是独立的。 在子节传入 Starship
类的实例时调用 Bind
方法。 绑定实例值后,将实例分配给用于呈现的属性:
var starship = new Starship();
_config.GetSection("starship").Bind(starship);
Starship = starship;
GetSection
在 Microsoft.Extensions.Configuration 包中,后者在Microsoft.AspNetCore.App 元包
中。
Bind
能够绑定整个 POCO 对象图。 Bind
在 Microsoft.Extensions.Configuration.Binder 包中,后者在Microsoft.AspNetCore.App 元包
中。
该示例包含 TvShow
模型,其对象图包含 Metadata
和 Actors
类 (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 文件:
<configuration>
<tvshow>
<metadata>
<series>Dr. Whoseries>
<title>The Sun Makerstitle>
<airdate>11/26/1977airdate>
<episodes>4episodes>
metadata>
<actors>
<names>Tom Baker, Louise Jameson, John Leesonnames>
actors>
<legal>(c)1977 BBC https://www.bbc.co.uk/programmes/b006q2x0legal>
tvshow>
configuration>
使用 Bind
方法将配置绑定到整个 TvShow
对象图。 将绑定实例分配给用于呈现的属性:
var tvShow = new TvShow();
_config.GetSection("tvshow").Bind(tvShow);
TvShow = tvShow;
ConfigurationBinder.Get
绑定并返回指定类型。 Get
比使用 Bind
更方便。 以下代码显示如何将 Get
与前面的示例一起使用,该示例允许将绑定实例直接分配给用于呈现的属性:
TvShow = _config.GetSection("tvshow").Get<TvShow>();
Get
在 Microsoft.Extensions.Configuration.Binder 包中,后者在Microsoft.AspNetCore.App 元包
中。 ASP.NET Core 1.1 或更高版本中提供了 Get
。 GetSection
在 Microsoft.Extensions.Configuration 包中,后者在Microsoft.AspNetCore.App 元包
中。
示例应用演示了本部分中介绍的概念。
Bind
支持使用配置键中的数组索引将数组绑定到对象。 公开数字键段(:0:
、:1:
、… :{n}:
)的任何数组格式都能够与 POCO 类数组进行数组绑定。 Bind
在 Microsoft.Extensions.Configuration.Binder 包中,后者在 Microsoft.AspNetCore.App 元包
中。
备注
绑定是按约定提供的。 不需要自定义配置提供程序实现数组绑定。
内存中数组处理
请考虑下表中所示的配置键和值。
键 | 值 |
---|---|
array:entries:0 | value0 |
array:entries:1 | value1 |
array:entries:2 | value2 |
array:entries:4 | value4 |
array:entries:5 | value5 |
使用内存配置提供程序在示例应用中加载这些键和值:
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.SetBasePath(Directory.GetCurrentDirectory());
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
的值。 配置绑定程序无法绑定 null 值,也无法在绑定对象中创建 null 条目,这在演示将此数组绑定到对象的结果时变得清晰。
在示例应用中,POCO
类可用于保存绑定的配置数据:
public class ArrayExample
{
public string[] Entries { get; set; }
}
将配置数据绑定至对象:
var arrayExample = new ArrayExample();
_config.GetSection("array").Bind(arrayExample);
GetSection
在 Microsoft.Extensions.Configuration 包中,后者在Microsoft.AspNetCore.App 元包
中。
还可以使用 ConfigurationBinder.Get
语法,从而产生更精简的代码:
ArrayExample = _config.GetSection("array").Get<ArrayExample>();
绑定对象(ArrayExample
的实例)从配置接收数组数据。
ArrayExample.Entries 索引 |
ArrayExample.Entries 值 |
---|---|
0 | value0 |
1 | value1 |
2 | value2 |
3 | value4 |
4 | value5 |
绑定对象中的索引 #3
保留 array:4
配置键的配置数据及其值 value4
。 当绑定包含数组的配置数据时,配置键中的数组索引仅用于在创建对象时迭代配置数据。 无法在配置数据中保留 null 值,并且当配置键中的数组跳过一个或多个索引时,不会在绑定对象中创建 null 值条目。
可以在由任何在配置中生成正确键值对的配置提供程序绑定到 ArrayExample
实例之前提供索引 #3
的缺失配置项。 如果示例包含具有缺失键值对的其他 JSON 配置提供程序,则 ArrayExample.Entries
与完整配置数组相匹配:
missing_value.json:
{
"array:entries:3": "value3"
}
在 ConfigureAppConfiguration
中:
config.AddJsonFile("missing_value.json", optional: false, reloadOnChange: false);
将表中所示的键值对加载到配置中。
键 | 值 |
---|---|
array:entries:3 | value3 |
如果在 JSON 配置提供程序包含索引 #3
的条目之后绑定 ArrayExample
类实例,则 ArrayExample.Entries
数组包含该值。
ArrayExample.Entries 索引 |
ArrayExample.Entries 值 |
---|---|
0 | value0 |
1 | value1 |
2 | value2 |
3 | value3 |
4 | value4 |
5 | value5 |
JSON 数组处理
如果 JSON 文件包含数组,则会为具有从零开始的节索引的数组元素创建配置键。 在以下配置文件中,subsection
是一个数组:
{
"json_array": {
"key": "valueA",
"subsection": [
"valueB",
"valueC",
"valueD"
]
}
}
JSON 配置提供程序将配置数据读入以下键值对:
键 | 值 |
---|---|
json_array:key | valueA |
json_array:subsection:0 | valueB |
json_array:subsection:1 | valueC |
json_array:subsection:2 | valueD |
在示例应用中,以下 POCO
类可用于绑定配置键值对:
public class JsonArrayExample
{
public string Key { get; set; }
public string[] Subsection { get; set; }
}
绑定后,JsonArrayExample.Key
保存值 valueA
。 子节值存储在 POCO
数组属性 Subsection
中。
JsonArrayExample.Subsection 索引 |
JsonArrayExample.Subsection 值 |
---|---|
0 | valueB |
1 | valueC |
2 | valueD |
该示例应用演示了如何使用实体框架 (EF)
创建从数据库读取配置键值对的基本配置提供程序。
提供程序具有以下特征:
ConfigurationBuilder
以从另一个配置提供程序提供连接字符串。定义用于在数据库中存储配置值的 EFConfigurationValue
实体。
Models/EFConfigurationValue.cs:
public class EFConfigurationValue
{
public string Id { get; set; }
public string Value { get; set; }
}
添加 EFConfigurationContext
以存储和访问配置的值。
EFConfigurationProvider/EFConfigurationContext.cs:
public class EFConfigurationContext : DbContext
{
public EFConfigurationContext(DbContextOptions options) : base(options)
{
}
public DbSet<EFConfigurationValue> Values { get; set; }
}
创建用于实现 xref:Microsoft.Extensions.Configuration.IConfigurationSource 的类。
EFConfigurationProvider/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
继承来创建自定义配置提供程序。 当数据库为空时,配置提供程序将对其进行初始化。
EFConfigurationProvider/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>
{
{ "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
扩展方法将配置源添加到 ConfigurationBuilder
。
Extensions/EntityFrameworkExtensions.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);
}
}
下面的代码演示如何在 Program.cs
中使用自定义的 EFConfigurationProvider
:
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.SetBasePath(Directory.GetCurrentDirectory());
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>();
}
将 IConfiguration
注入 Startup
构造函数以访问 Startup.ConfigureServices
中的配置值。 若要访问 Startup.Configure
中的配置,请将 IConfiguration
直接注入方法或使用构造函数中的实例:
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"];
}
}
有关使用启动便捷方法访问配置的示例,请参阅应用启动:便捷方法
。
若要访问 Razor Pages 页或 MVC 视图中的配置设置,请为Microsoft.Extensions.Configuration 命名空间
添加using 指令
(C# 参考:using 指令
)并将 IConfiguration
注入页面或视图。
在 Razor 页面页中:
@page
@model IndexModel
@using Microsoft.Extensions.Configuration
@inject IConfiguration Configuration
<html lang="en">
<head>
<title>Index Pagetitle>
head>
<body>
<h1>Access configuration in a Razor Pages pageh1>
<p>Configuration value for 'key': @Configuration["key"]p>
body>
html>
在 MVC 视图中:
@using Microsoft.Extensions.Configuration
@inject IConfiguration Configuration
<html lang="en">
<head>
<title>Index Viewtitle>
head>
<body>
<h1>Access configuration in an MVC viewh1>
<p>Configuration value for 'key': @Configuration["key"]p>
body>
html>
通过 IHostingStartup
实现,可在启动时从应用 Startup
类之外的外部程序集向应用添加增强功能。 有关更多信息,请参见在 ASP.NET Core 中使用承载启动程序集
。