前言

多环境配置应该都很熟悉了,最为常见的便是DebugRelease,例如下图是新建的一个asp.net项目,配置文件展开共有三个文件组成



据我所知,大多公司从来没编辑过Web.Debug.configWeb.Release.config,一个Web.config文件改来改去来切换不同的配置,十分麻烦。

asp.net下的多环境配置

哪怕你随手双击打开Web.Debug.configWeb.Release.config任何一个,看看里面的注释。

Web.Debug.config
<?xml version="1.0" encoding="utf-8"?>

<!-- 有关使用 Web.config 转换的详细信息,请访问 https://go.microsoft.com/fwlink/?LinkId=301874 -->

<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
<!--
在下例中,“SetAttributes”转换将更改
“connectionString”的值,仅在“Match”定位器找到值为“MyDB”的
特性“name”时使用“ReleaseSQLServer”。 <connectionStrings>
<add name="MyDB"
connectionString="Data Source=ReleaseSQLServer;Initial Catalog=MyReleaseDB;Integrated Security=True"
xdt:Transform="SetAttributes" xdt:Locator="Match(name)"/>
</connectionStrings>
-->
<system.web>
<!--
在以下示例中,"Replace" 转换将替换 Web.config 文件的
整个 <customErrors> 节。
请注意,由于在 <system.web> 节点下只有一个
customErrors 节,因此无需使用 "xdt:Locator" 属性。 <customErrors defaultRedirect="GenericError.htm"
mode="RemoteOnly" xdt:Transform="Replace">
<error statusCode="500" redirect="InternalError.htm"/>
</customErrors>
-->
</system.web>
</configuration>

微软为了让你使用它,把不仅给出实例,还配上详细的注释。

下面再展示下最为常用的appSettings如何配置

Web.config // 开发环境
  <appSettings>
<add key="webpages:Version" value="3.0.0.0" />
<add key="webpages:Enabled" value="false" />
<add key="ClientValidationEnabled" value="true" />
<add key="UnobtrusiveJavaScriptEnabled" value="true" /> <add key="MyKey" value="Myvalue" />
</appSettings>
Web.Release.config // Release环境
  <appSettings>
<add key="webpages:Version" value="3.0.0.0" />
<add key="webpages:Enabled" value="false" />
<add key="ClientValidationEnabled" value="true" />
<add key="UnobtrusiveJavaScriptEnabled" value="true" /> <add key="MyKey" value="Releasvalue" xdt:Transform="Replace" xdt:Locator="Match(key)" />
</appSettings>

经过这样的配置后,本机开发时读取到MyKey的值为Myvalue,发布生产环境时值为Releasvalue

按照上面的配置,本地发布一下试试。



发布成功后,打开发布后的Web.config文件,我们发现开发环境下Web.config中对应的值被替换了。

如何增加额外的环境配置

有时候Debug和Release两个环境还不能满足我们的需要,需要增加更多的环境配置。

打开菜单生成-->配置管理器,新建一个TEST1环境



然后右键Web.config选择添加配置转换(第四个)



会自动生成一个Web.TEST1.config文件,添加一个该环境下的配置用来覆盖开发配置



更改发布的配置



打开发布成功后的Web.config文件



效果与预期一致。

aspnetcore下的多环境配置

aspnetcore中的配置文件被appsettings.json所取代,.NET Core中的配置是使用一个或多个配置提供程序执行的。 配置提供程序使用各种配置源从键值对读取配置数据:

什么是配置提供程序

下表显示了 .NET Core 应用可用的配置提供程序。

提供程序 通过以下对象提供配置
Azure 应用配置提供程序 Azure 应用程序配置
Azure Key Vault 配置提供程序 Azure Key Vault
命令行配置提供程序 命令行参数
自定义配置提供程序 自定义源
环境变量配置提供程序 环境变量
文件配置提供程序 JSON、XML 和 INI 文件
Key-per-file 配置提供程序 目录文件
内存配置提供程序 内存中集合
应用机密(机密管理器) 用户配置文件目录中的文件

详细内容参考 .NET 中的配置

https://docs.microsoft.com/zh-cn/dotnet/core/extensions/configuration

其中以下部分比较值得注意



划重点:后来添加的配置提供程序会替代之前的密钥设置

appsettings.Development.jsonappsettings.json后加载,则后加载的会覆盖先加载配置的值,没毛病!

多环境配置文件时如何加载

为了彻底弄清楚底层加载逻辑,下载源码一探究竟。

builder.ConfigureAppConfiguration((hostingContext, config) =>
{
var env = hostingContext.HostingEnvironment; config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: true); if (env.IsDevelopment())
{
if (!string.IsNullOrEmpty(env.ApplicationName))
{
var appAssembly = Assembly.Load(new AssemblyName(env.ApplicationName));
if (appAssembly != null)
{
config.AddUserSecrets(appAssembly, optional: true);
}
}
} config.AddEnvironmentVariables(); if (args != null)
{
config.AddCommandLine(args);
}
})

默认的WebHostBuilder,用环境变量env.EnvironmentName拼接的文件就是默认加载的Json境配置文件。

也就解释了为什么开发阶段会加载appsettings.Development.json配置文件了。

VS本地开发时如何切换环境

如何传参修改环境变量EnvironmentName值是问题的关键,若能修改想要的值,然后创建对应名称的配置文件即可。

在web根目录存在一个文件:Properties/launchSettings.json

其中有一个配置环境变量的配置

"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
},

本地开发时只需要创建多个启动配置,分别设置不同的ASPNETCORE_ENVIRONMENT即可进行切换了,修改后的launchSettings.json

// launchSettings.json
{
"iisSettings": {
"windowsAuthentication": false,
"anonymousAuthentication": true,
"iisExpress": {
"applicationUrl": "http://localhost:2364",
"sslPort": 44302
}
},
"profiles": {
"Web1": {
"commandName": "Project",
"launchBrowser": true,
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
},
"applicationUrl": "https://localhost:7006;http://localhost:5006",
"dotnetRunMessages": true
},
"Web1:Test": {
"commandName": "Project",
"launchBrowser": true,
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "TEST"
},
"applicationUrl": "https://localhost:7006;http://localhost:5006",
"dotnetRunMessages": true
}
}
}

Web1Web1:Test启动选项便会同步显示在VS启动选项中,切换为Web1:Test再运行程序,就会加载appsettings.TEST.json,效果和appsettings.Development.json没区别。

如何在发布时应用不同的配置文件

在上文中我们学会了在本地配置多个不同环境配置进行开发,那如果需要发布的生产环境也有很多种配置,那如何让程序自动加载不同的配置文件呢,毕竟launchSettings.json文件只是在开发时搭配VS用的,既然launchSettings.json可以配置环境变量,没了它我们手动创建环境变量应该也可以。在操作系统添加环境变量如:



也可以在程序启动时通过命令行传参设置环境值。

但是这两种我都感觉不方便,我们希望程序根据不同的环境发布好以后,只需要直接执行就好,而不是需要进行额外的配置或传参。

EnvironmentName 属性

在项目的工程文件中有EnvironmentName属性,可以指定当前EnvironmentName值,添加如下代码



然后编译后的,直接运行,就能够读取到appsettings.TEST.json配置文件。

这配置不会覆盖launchSettings.json中指定的环境值,但在影响发布后的EnvironmentName值,从而可以改变实现发布后默认的EnvironmentName值。

那这样设置后,岂不是发布后的EnvironmentName值只能是Test,如果要发布其他环境还要每次发布前修改这个值,那不是很麻烦吗?

没错如果没有点其他手段,那这真是多此一举啊,请看下图。



懂了吧,我们只需要多配置一个PublishProfile发布文件,指定不同的配置项,然后结合Condition条件来控制EnvironmentName



至此,完美实现根据不同环境选择不同的发布文件,进行发布项目,目标机器不需要做任何配置,直接运行就是我们想要的效果。

总结虽然ASP.NET和ASP.NETCore实现多环境的方式不同,但是最后发布时我们可以做到一样的效果,所有的配置都是一次性的,发布时指定对应的PublishProfile即可。

最新文章

  1. Ubuntu 14.04 编译安装 husky
  2. Making the Grade(POJ3666)
  3. Java Gradle入门指南之简介、安装与任务管理
  4. background常用属性
  5. C++-new操作符
  6. Linux/Unix 桌面趣事:文字模式下的 ASCII 艺术与注释绘画
  7. 【shell】read
  8. PHP与Java使用des加密通讯
  9. CSS3实现时间表
  10. IFieldEdit Interface 接口
  11. excel计算后列填充
  12. jQuery基本过滤选择器
  13. Akka Serialization
  14. Oracle问题之字符集问题,登陆sqlplus出现问号
  15. 使用guava变形数据结构
  16. Java获取请求主机真实ip
  17. mybatis多表关联
  18. Unity中HideInInspector和SerializeField以及Serializable
  19. bzoj1088 P2327 [SCOI2005]扫雷
  20. kbmMW均衡负载与容灾(3)(转载红鱼儿)

热门文章

  1. KVM 虚拟化基本知识,virtio工作原理
  2. DC-2
  3. const char * 组合理解
  4. Material Design with the Android Design Support Library
  5. mysql join 底层原理
  6. 服务端处理 Watcher 实现 ?
  7. char型变量中能不能存贮一个中文汉字?为什么?
  8. Memcache 与 Redis 的区别都有哪些?
  9. Java 中,DOM 和 SAX 解析器有什么不同?
  10. 打败算法 —— 环形链表 II