• ASP.NET和ASP.NETCore多环境配置对比


    前言

    多环境配置应该都很熟悉了,最为常见的环境便是DebugRelease,例如下图是新建的一个asp.net项目,配置文件展开共有三个文件组成
    image.png
    有些开发者从来没了解过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>
    

    微软为了让我们使用它,把不仅给出示例,还配上详细的注释,看过注释和示例大概就该知道如何进行配置,覆盖Web.config中的配置。
    下面展示下最为常用的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 生产环境-->
      <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
    按照上面的配置,本地发布程序试试效果。
    image.png
    发布成功后,打开发布后生成的Web.config文件,我们发现开发环境下Web.config中对应的值被替换了,这样开发和生产配置分别配置在不同文件,不需要频繁修改配置文件切换配置了。
    image.png

    如何增加额外的环境配置

    有时候Debug和Release两个环境还不能满足我们的需要,需要增加更多的环境配置。
    打开菜单生成-->配置管理器,新建一个TEST1环境
    image.png
    然后右键Web.config选择添加配置转换(第四个)
    image.png
    会自动生成一个Web.TEST1.config文件,非常的人性化,然后我们在该文件配置一些参数。
    image.png
    更改发布的配置,进行发布。
    image.png
    打开发布成功后的Web.config文件
    image.png
    效果与预期一致。

    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
    其中以下部分比较值得注意
    image.png
    划重点:后来添加的配置提供程序会替代之前的密钥设置
    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配置文件的原理。

    开发阶段的多环境

    如何传参修改环境变量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没区别。
    image.png

    发布阶段的实现多环境配置

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

    image.png
    也可以在程序启动时通过命令行传参设置环境值。
    但是这两种我都感觉不方便,我们希望程序根据不同的环境发布好以后,只需要直接执行就好,而不是需要进行额外的配置或传参。

    EnvironmentName 属性

    在项目的工程文件中有EnvironmentName属性,可以指定当前EnvironmentName值,添加如下代码
    image.png
    然后编译后的,直接运行,就能够读取到appsettings.TEST.json配置文件。
    这配置不会覆盖launchSettings.json中指定的环境值,但在影响发布后的EnvironmentName值,从而可以改变实现发布后默认的EnvironmentName值。
    那这样设置后,岂不是发布后的EnvironmentName值只能是Test,如果要发布其他环境还要每次发布前修改这个值,那不是很麻烦吗?
    没错如果没有点其他手段,那这真是多此一举啊,请看下图。
    image.png
    懂了吧,我们只需要多配置一个PublishProfile发布文件,指定不同的配置项,然后结合Condition条件来控制EnvironmentName
    image.png
    至此,完美实现根据不同环境选择不同的发布文件,进行发布项目,目标机器不需要做任何配置,直接运行就是我们想要的效果。
    总结虽然ASP.NET和ASP.NETCore实现多环境的方式不同,但是最后发布时我们可以做到一样的效果,所有的配置都是一次性的,发布时指定对应的PublishProfile即可。


    __EOF__

  • 本文作者: Gui.H
  • 本文链接: https://www.cnblogs.com/springhgui/p/16154573.html
  • 关于博主: 评论和私信会在第一时间回复。或者直接私信我。
  • 版权声明: 本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
  • 声援博主: 如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。
  • 相关阅读:
    Java 8 新特性解读及应用实践
    对抗微信如何要把网页都变成快应用
    26栈和队列-简单实践
    Flask 学习-19.配置管理flask_sqlalchemy 和 flask_migrate
    Spark 离线开发框架设计与实现
    使用webpack打包ts代码的配置实现和相关说明
    神经网络物联网未来现状和趋势及看法
    [标准sql] 内连接和外连接的区别
    城市旅游景点信息交流平台的设计与实现 毕业设计-附源码290915
    雷军的演讲以及产品发布
  • 原文地址:https://www.cnblogs.com/springhgui/p/16154573.html