配置,是应用程序很重要的组成部分,常常用于提供信息,像第三方应用登录钥匙、上传格式与大小限制等等。
ASP.NET Core提供一系列配置提供程序读取配置文件或配置项信息。
ASP.NET Core项目启动时默认加载的配置有:
- 命令行参数
- 环境变量
- appsettings.json、appsettings.Environment.json、appsettings.Production.json等
【示例代码下载】
常用的配置提供程序
ASP.NET Core常用的配置Provider有:
- CommandLineConfigurationProvider(命令行配置)
- EnvironmentVariablesConfigurationProvider(环境变量配置)
- FileConfigurationProvider(文件配置)
命令行配置
命令行配置Provider通过读取应用启动时的命令行参数来设置配置项。
默认情况下,在命令行上设置的配置值会替换通过所有其他配置提供程序设置的配置值。
支持的命令格式
- 无前缀的key=value模式
- 双中横线模式--key=value或--key value
- 正斜杠模式 /key=value或/key value
注:等号分隔符和空格分隔符不能混用
命令替换模式
- 必须以单划线(-)或双划线(--)开头
- 映射字典不能包含重复Key
注:使用单划线时,代表需要替换的占位符,必须进行替换,不然会报错。
配置位置
{
"profiles": {
"ConfigurationProviderSample.ConsoleApp": {
"commandName": "Project",
"commandLineArgs": "MyKey1=cmd --MyKey3=cmd /MyKey6=cmd --k1=k3",
"environmentVariables": {
"MyKey2": "situation"
}
}
}
}
在launchSettings.json文件里的profiles.[项目名].commandLineArgs属性。
代码示例:
class Program
{
static void Main(string[] args)
{
IConfigurationBuilder builder = new ConfigurationBuilder();
// 加载命令行参数
builder.AddCommandLine(args);
//// 替换参数,注意要去命令行参数那里把双划线--k1改成单划线-k1,并且要注释上面一句代码。
//var mapper = new Dictionary<string, string>() { { "-k1", "MyKey7" } };
//builder.AddCommandLine(args, mapper);
var configurationRoot = builder.Build();
Console.WriteLine($"MyKey1:{configurationRoot["MyKey1"]}");
Console.ReadKey();
}
}
输出结果:
环境变量配置
环境变量配置,通过读取操作系统的环境变量参数来设置配置项。
适用场景
- 在Docker中运行
- 在Kubernetes中运行
- 需要设置ASP.NET Core的一些内置特殊配置时
特性
- 对于配置的分层键,支持用双下划线(__)代替冒号(:)。在Linux中是支持冒号(:)
- 支持根据前缀加载
代码示例:
class Program
{
static void Main(string[] args)
{
IConfigurationBuilder builder = new ConfigurationBuilder();
// 分层键
builder.AddEnvironmentVariables();
var configurationRoot = builder.Build();
Console.WriteLine($"MyKey2:{configurationRoot["MyKey2"]}");
var section = configurationRoot.GetSection("SECTION1");
Console.WriteLine($"MyKey2:{section["MyKey2"]}");
// 支持多重分层
var section2 = configurationRoot.GetSection("SECTION1:SECTION2");
Console.WriteLine($"MyKey2:{section2["MyKey2"]}");
Console.ReadKey();
//// 前缀过滤
//builder.AddEnvironmentVariables("PREFIX_");
//var configurationRoot = builder.Build();
//Console.WriteLine($"MyKey2:{configurationRoot["MyKey2"]}");
//Console.ReadKey();
}
}
文件配置
常用的文件格式有:ini、json和xml。
特性
- 指定文件可选、必选。
- 指定是否监听文件的变更。
示例代码:
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("appsettings.json");
// 演示指定文件可选
config.AddJsonFile("appsettings.Development.json", true);
// 演示指定文件变更
config.AddJsonFile("appsettings.Production.json", false, true);
})
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
});
}
注:最终配置项的值跟文件加载的顺序有关。
配置优先级
当同时使用命令行配置、环境变量配置、文件配置,并且有相同配置项名字时,如何判断使用哪个配置项。
使用ASP.NET Core项目的默认模板,通过修改文件launchSettings.json的commandLineArgs和environmentVariables
"ConfigurationProviderSample": {
"commandName": "Project",
"commandLineArgs": "MyKey1=cmd --MyKey3=cmd /MyKey6=cmd --k1=k3",
"launchBrowser": true,
"applicationUrl": "http://localhost:5000",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development",
"MyKey2": "situation",
"SECTION1__MyKey2": "hello world",
"SECTION1__SECTION2__MyKey2": "hi world",
"PREFIX_MyKey2": "hello world"
}
}
另外,appsettings.json如下:
{
"MyKey1": "appsettings.json",
"MyKey2": "appsettings.json",
"MyKey3": "appsettings.json",
"MyKey4": "appsettings.json",
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
},
"AllowedHosts": "*"
}
结果如下:
通过上述结果可知,当同时使用命令行配置、环境变量配置、文件配置时,优先级是:命令行 > 环境变量 > 文件。
如何使用配置
上面介绍了如何加载配置,下面介绍如何在ASP.NET Core中使用配置。下面介绍三种常用的方式:
- 在Startup中使用配置
- 在Razor Pages中使用配置
- 在MVC视图中使用配置
在Startup中使用配置
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();
});
}
}
在Razor Pages中使用配置
通过inject语法注入配置对象IConfiguration。
@page
@model Test5Model
@using Microsoft.Extensions.Configuration
@inject IConfiguration Configuration
Configuration value for 'MyKey': @Configuration["MyKey"]
在Startup.ConfigureServices中配置MyOptions。
public void ConfigureServices(IServiceCollection services)
{
services.Configure<MyOptions>(Configuration.GetSection("MyOptions"));
services.AddRazorPages();
}
通过inject注入。
@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视图中使用配置
方式与Razor Pages类似。
@using Microsoft.Extensions.Configuration
@inject IConfiguration Configuration
Configuration value for 'MyKey': @Configuration["MyKey"]
public void ConfigureServices(IServiceCollection services)
{
services.Configure<MyOptions>(myOptions =>
{
myOptions.Option1 = "Value configured in delegate";
myOptions.Option2 = 500;
});
services.AddRazorPages();
}
可通过Model类注入配置来初始化。
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}
" +
$"Option2: {_optionsDelegate.Value.Option2}");
}
}