代码之家  ›  专栏  ›  技术社区  ›  CodingWithSpike

在部署环境之间管理复杂的web.config文件

  •  53
  • CodingWithSpike  · 技术社区  · 16 年前

    有人知道有什么好的管理工具吗 Web.Config 不同构建/部署环境之间的文件?

    例如,我有一个WCF项目,在开发中我不想启用SSL,但我确实希望在生产中启用它。我想要不同的日志设置,不同的数据库连接字符串,不同的错误处理,不同的文件路径…甚至一些不同的UnityFramework绑定(为单元测试而不是实际的部署对象连接模拟)。

    维护 Web.CONFIG 这是一个难题,因为添加新的Web服务意味着编辑多个文件并保持它们的同步。

    我也注意到,如果你和 Web.CONFIG 如果您试图使用“添加项目”向导为WCF添加新的Web服务,例如,它必须修改web.config以添加端点,并且无法再对其进行分析,那么用手太多的话,Visual Studio将窒息。因此,我必须小心不要使现有web.config失效。

    我还想用一些regex来做替换,然后创建一个新的 Web.CONFIG 在预生成命令中。这似乎是目前最好的选择…

    还有其他想法吗?这似乎是一个非常常见的问题,因为 Web.CONFIG 开发和生产部署之间可能永远不会相同。


    更新:

    我决定编写一个快速控制台应用程序,它将把给定目录中的所有XML文件合并到一个目录中,并且只包含基于名称的某些文件。

    所以我可以在一个目录中:

    WebCopyTALL

    <configuration>
      <configSections>
        ...
      </configSections>
      <system.web>
        ...
      </system.web>
    </configuration>
    

    连接字符串调试

    <configuration>
      <connectionStrings>
        <add name="connstr" connectionString="...dev..." />
      </connectionStrings>
    </configuration>
    

    连接字符串释放

    <configuration>
      <connectionStrings>
        <add name="connstr" connectionString="...prod..." />
      </connectionStrings>
    </configuration>
    

    然后运行我的命令行工具,并传入配置(调试、发布、自定义…) 它会合并所有以 _All" or _<配置>`。

    所以现在我有80%的web.config在一个 WebConfig_All 文件,以及每个构建配置在单独文件中的20%自定义内容。然后,我可以在VisualStudio中或从Nant或任何我想要的地方作为预构建任务运行我的命令行工具…

    我还使我的XML合并逻辑足够好,可以处理如下内容:

    <x>
      <y a="1">
        <z a="1"/>
      </y>
    </x>
    

    合并

    <x>
      <y a="1">
        <z a="2"/>
      </y>
      <y a="2"/>
    </x>
    

    结果:

    <x>
      <y a="1">
        <z a="1"/>
        <z a="2"/>
      </y>
      <y a="2"/>
    </x>
    

    到目前为止看起来不错…:)


    跟进:

    此主题现在有点旧,因此我想指出VisualStudio 2010内置了一个要执行web.config转换的功能: http://msdn.microsoft.com/en-us/vstudio/Video/ff801895

    当然,在典型的微软模式中,只有50%的方式实现任何特性,它只适用于使用WebDeploy的Web项目。有一个插件可以在其他项目中启用转换,位于此处: http://www.hanselman.com/blog/SlowCheetahWebconfigTransformationSyntaxNowGeneralizedForAnyXMLConfigurationFile.aspx

    你也可以使用类似的工具 BuildMaster 管理配置文件(连同构建、测试、数据库脚本等…)

    11 回复  |  直到 8 年前
        1
  •  20
  •   Dan    16 年前

    我们将所有特定于区域的设置拆分为自己的配置文件。在Web应用程序的根目录下,我们创建一个配置文件夹,并将特定于区域的设置放在那里。因此,在config根目录下的任何文件都将被获取。

    我们的web.config看起来像:

    .
    .
    .
    <appSettings configSource="config\appSettings.config"/>
    <nlog configSource="config\nlog.config"/>
    <applicationSettings>
        <MyApp.UI.Properties.Settings configSource="config\Settings.APGUI.config"/>
        <MyApp.BusinessServices.Properties.Settings configSource="config\Settings.Business.config"/>
        <MyApp.Auditing.Properties.Settings configSource="config\Settings.Auditing.config"/>
    </applicationSettings>
    .
    .
    .
    

    因此,如果我们部署到发布区域,那么构建工具将只需要执行一个操作,用相应区域文件夹中的文件替换config根目录中的文件。文件结构如下:

    添加:这是源代码管理结构的外观,部署的应用程序只具有config dir,没有子文件夹或课程。

    \Root
       web.config    
       \Config    
           appsettings.config    
           services.config    
           logging.config    
           \release    
              appsettings.config    
              services.config    
              logging.config    
           \debug
              appsettings.config    
              services.config    
              logging.config
    

    它非常干净,并由任何自动构建工具(复制/替换文件)支持。好的副作用是开发人员可以创建不同的风格,并将它们保持在源代码控制之下,而不会影响“真实”的配置。

        2
  •  7
  •   JeremyWeir    16 年前

    您希望在msbuildCommunityTasks中执行xmlMassUpdate任务(执行您试图对XML控制台应用程序执行的操作)

    http://msbuildtasks.tigris.org/

    像这样用

      <XmlMassUpdate Condition=" '@(ConfigTemplateFile)'!='' And '@(ConfigSubstitutionsFile)'!=''"
        ContentFile="@(ConfigTemplateFile)"
        SubstitutionsFile="@(ConfigSubstitutionsFile)"
        MergedFile="@(ConfigFile)"
        ContentRoot="/configuration"
        SubstitutionsRoot="/configuration/substitutions/$(Configuration)"/>
    
        3
  •  7
  •   cgreeno    16 年前

    可以使用生成事件来管理Web配置。 Hanselman 有一篇关于它的好文章。

    基本上,您在解决方案中拥有所有不同的web.config,然后创建(一些)新的构建类型。根据运行的生成类型,将在引用的生成类型上复制web.config!

        4
  •  4
  •   Cohen    16 年前

    我用 method explained by Scott Hanselman (他解释得比我能复制的好得多,所以请遵循链接:) 它对我来说很管用…

        5
  •  4
  •   Graham Ambrose    16 年前

    我使用这个工具: xmlpreprocess

    我们为部署脚本合并的每个环境维护单独的“属性”文件。

        6
  •  2
  •   Pedro    16 年前

    我喜欢使用生成任务 automate 更改所需环境的配置文件。

        7
  •  2
  •   mathieu    16 年前

    我们在配置文件中使用标记,这些标记在构建时被替换以反映预期的部署环境。我的灵感来自 Lavablast blog

    最好只管理一个模板配置文件。

    缺点是你不能轻易地定制“部分”。

        8
  •  2
  •   S.Dav    8 年前

    以前的问题,但由于它在谷歌搜索中的排名很高,我认为添加 web.config transformation syntax ,那 has been available since VS2010 . 使用此工具,您可以为不同的版本(调试/发布)使用不同的web.config文件。

    以下是关于如何具有两个连接字符串的简短摘要-一个用于开发(调试模式),一个用于生产(发布模式):

    1-在web.config文件中设置开发连接字符串。应该看起来像这样:

     <connectionStrings>
        <add name="myConnectionString"  connectionString="Data Source=TestDBServer; (etc...)" />
      </connectionStrings>
    

    2-展开web.config文件并打开web.release.config

    web.config

    3 -使用 Replace function 将连接字符串替换为要用于生产的连接字符串。你可以使用 xdt:Locator="Match(name)" 属性以将其与此示例中的连接字符串(myConnectionString)的名称匹配:

    <connectionStrings>
        <add name="myConnectionString"  xdt:Transform="Replace" xdt:Locator="Match(name)" 
             connectionString="Data Source=ProdDBServer; (etc...)" />
      </connectionStrings>
    

    4-通过右键单击web.release.config文件并选择,预览将在版本生成期间使用的web.config文件的转换。 预览转换 .

    enter image description here

        9
  •  1
  •   Jeff Martin    16 年前

    如您所提到的,我通常使用多个web.config。这可能是一个痛苦,但它是减轻文件比较工具,如beyonecomapare2或kdiff…

        10
  •  0
  •   CodingWithSpike    16 年前

    烦恼:

    我在第一次更新中提到了我的小命令行应用程序来合并XML文档…为了做到这一点,我只使用了xmldocument,最后只使用了.save()将其保存到一个文件流中。

    不幸的是,这些节点实际上并不是按任何特定的顺序排列的,而且很明显,.net 要求 <configSections>元素是文档的第一个子元素。

    我以为所有这些花哨的工具都能使程序设计变得生动 更容易的 ?

        11
  •  0
  •   tmaj    8 年前

    我最喜欢的两种方法是:

    a.保留目标计算机上的设置*—例如,在Azure中,您可以设置应用程序设置和连接字符串,这些设置和连接字符串将覆盖web.config中的值。(*或目标机器定义,如果基础结构配置是动态的)。

    b.使构建/部署工具(TeamCity、Octopus Deploy等,vs Team Services)作为构建和/或部署的一部分注入特定于环境的值。现代工具支持加密敏感设置。

    推荐文章