〇、前言
日常开发中,程序的环境切换是相当频繁的了,如果不同环境中的某些参数不同,那就需要每次编辑之前手动进行修改,比较麻烦,效率低下。
本文将以 .NET Core WebAPI 项目的配置方法为例,分步骤实现根据环境变量的配置参数,自动读取对应配置文件中的特殊参数值,从而达到 Development、Staging、Production 三种环境的无感部署。.
一、配置文件
程序一般默认只有一个配置文件:appsettings.Development.json。
需要手动添加另外两个:appsettings.Staging.json、appsettings.Production.json。
原配置文件中,默认只有一个节点:Logging,如下:
{"Logging": {"LogLevel": {"Default": "Information","Microsoft": "Warning","Microsoft.Hosting.Lifetime": "Information"}}}
需要手动添加一个与 Logging 同级的节点,名称自定义,如下示例:
{"Logging": {"LogLevel": {"Default": "Information","Microsoft": "Warning","Microsoft.Hosting.Lifetime": "Information"}},"MyPara": {"myparavalue": "测试文本","myparavalue2": [{"key": "111","value": "v111"},{"key": "222","value": "v222"},{"key": "333","value": "v333"}]}}
注意,三个配置文件中需要加上完全一样的参数名称,然后根据环境不同配置不同的值。
二、程序读取配置
1. 配置文件信息读取实现
接下来就是在程序中配置读取了,在控制器的构造函数添加环境判断,然后取出配置文件中新增节点的值备用。
以下实例,包含了读取 字符值、列表值 两种:
using Microsoft.AspNetCore.Hosting;using Microsoft.Extensions.Configuration;[Route("api/[controller]/[action]")][ApiController]public class SystemConfigController : ControllerBase // SystemConfig{public static IConfigurationRoot configurationRoot = null;// 示例只有两个字段,就用字典 Dictionary 来演示了,若字段较多时,可用实体对象 listpublic static Dictionary<string, string> keyValuePairs = new Dictionary<string, string>();public SystemConfigController(IWebHostEnvironment env){try{configurationRoot = AppConfigure.GetConfigurationRoot(env.ContentRootPath, env.EnvironmentName);if (keyValuePairs.Count == 0) // 仅首次加载时读取{string flag = string.Empty;int i = 0;while (flag != null){var keyinfo = configurationRoot[$"MyConfigPara:myparavalue2:{i}:key"];var valueinfo = configurationRoot[$"MyConfigPara:myparavalue2:{i}:value"];if (keyinfo != null && valueinfo != null){keyValuePairs.Add(keyinfo, valueinfo); // 加入字典i++;}elseflag = null;}}}catch (Exception ex){// 日志框架记录日志}}public void TestAction(){// 读取配置文件具体值string myparavalue = configurationRoot["MyPara:myparavalue"];}}
配置文件读取帮助类:AppConfigure.cs。
using Microsoft.Extensions.Configuration;using System.Collections.Concurrent;public static class AppConfigure{// 缓存字典private static readonly ConcurrentDictionary<string, IConfigurationRoot> _cacheDict;static AppConfigure(){_cacheDict = new ConcurrentDictionary<string, IConfigurationRoot>();}// 传入 JSON 文件夹路径与当前的环境变量值public static IConfigurationRoot GetConfigurationRoot(string jsonDir, string environmentName = null){// 设置缓存的 KEYvar cacheKey = $"{jsonDir}#{environmentName}";// 添加默认的 JSON 配置var builder = new ConfigurationBuilder().SetBasePath(jsonDir).AddJsonFile("appsettings.json", optional: true, reloadOnChange: true);// 根据环境变量添加相应的 JSON 配置文件if (!string.IsNullOrEmpty(environmentName)){builder = builder.AddJsonFile($"appsettings.{environmentName}.json", optional: true, reloadOnChange: true);}// 返回构建成功的 IConfigurationRoot 对象return builder.Build();}}
2. 关于本机测试
可以通过修改项目的初始设置文件(文件夹下 Properties-->launchSettings.json)修改当前的运行环境,也可以在项目属性的“Debug”中修改,效果是一样的,如下:
{"$schema": "http://json.schemastore.org/launchsettings.json","iisSettings": {"windowsAuthentication": false,"anonymousAuthentication": true,"iisExpress": {"applicationUrl": "http://localhost:40493","sslPort": 44360}},"profiles": {"IIS Express": {"commandName": "IISExpress","launchBrowser": true,"launchUrl": "weatherforecast","environmentVariables": {"ASPNETCORE_ENVIRONMENT": "Development" // 修改切换运行环境:Development、Production、Staging}},"Finance.ReconciliationPlatform": {"commandName": "Project","dotnetRunMessages": "true","launchBrowser": true,"launchUrl": "weatherforecast","applicationUrl": "https://localhost:5001;http://localhost:5000","environmentVariables": {"ASPNETCORE_ENVIRONMENT": "Development"}}}}

注意:launchSettings.json 文件,仅用于本地开发计算机,不会被编译发布到生产环境,因此不能存储重要信息。
三、Windows 服务器配置
最后就是配置 Windows 服务器的环境变量了,用来标识程序运行的环境。
如下图,根据需要配置不同的环境变量:
-
ASPNETCORE_ENVIRONMENT:Development
-
ASPNETCORE_ENVIRONMENT:Staging
-
ASPNETCORE_ENVIRONMENT:Production
注意:此方法配置的是服务器的环境变量,针对的是整台机器的环境类型,若需求是在同一台机器上配置多类型的程序,请参考后边章节。

至此,就配置完成了。
四、如何在同一台服务器 部署 两种不同环境 的服务?
1、修改 Startup.cs 代码,固定运行环境
通过在 Startup.cs 文件的 Configure() 方法中,赋值环境名称(EnvironmentName),以实现灵活控制程序的环境。
public void Configure(IApplicationBuilder app, IWebHostEnvironment env){env.EnvironmentName = "Production";if (env.IsProduction()) // true{// 。。。}}
2、通过 IIS 配置服务的环境变量
通过 IIS 配置环境变量,也是区分生效范围的:
-
若直接在根目录的“配置编辑器”中配置,则其下的服务将是同一环境类型;(后续更新服务后值不变)
-
若针对单个服务的“配置编辑器”配置,则仅针对当前服务。(缺点:每次服务更新后,需重新配置)
注意,针对服务的环境配置优先级,高于根目录的配置。继承来的环境配置无法修改,要配置其他的环境,需要新增。
如下配置步骤:
(配置管理器 --> 根据路径查找 system.webServer/aspNetCore --> system.webServer/aspNetCore --> 编辑项ASPNETCORE_ENVIRONMENT填入指定的环境值Production、Staging、Development)

项路径中另加服务名称的就是在当前服务新增的,另外一个则是从根目录继承来的,当前新增的优先级较高。