【问题标题】:Handling web.config differences across multiple machines when using version control使用版本控制时处理跨多台机器的 web.config 差异
【发布时间】:2009-06-19 10:05:16
【问题描述】:

我相信每个人都必须处理这些情况,我们检查我们的源代码控制解决方案,每台开发机器都有自己的资源用于调试、构建和测试。..

最常见的是:

  • Web 服务器 (IIS)
  • 数据库 (SQL)

web服务器很容易处理,每台dev机器都会有自己的proj.user文件来指定不同的调试信息。

但是应用程序的连接字符串存储在 web.config 中(受源代码控制),理想情况下,我们不希望 web.config 被“感知”,因此必须在我们委派它们的地方执行配置部分到其他配置文件(不在 sc 下)不是最好的解决方案..

asp.net (.net?) 已经支持具有 web.config 继承的模型,这将是一个理想的场景。但是这只适用于目录。

如果我们能有那就太好了

  • web.config
  • web.machine.config

当然,我愿意就人们如何解决这个问题提出更好的建议。

喜欢..也许有:

  • web.base.config
  • web.machine.config

并且有一个通过合并它们来创建 web.config 的构建脚本?

提前致谢, 斯蒂芬。


编辑

看起来下一个 vs 可能有办法处理这个问题:

http://blogs.msdn.com/webdevtools/archive/2009/05/04/web-deployment-web-config-transformation.aspx


编辑编辑

今天可以通过 xml 大规模更新来实现:

http://blogs.microsoft.co.il/blogs/dorony/archive/2008/01/18/easy-configuration-deployment-with-msbuild-and-the-xmlmassupdate-task.aspx


编辑编辑编辑

这当然可以通过一个简单的 xslt 构建任务和一个复制所有内容并拦截某些属性的小转换来完成。只是尝试了概念验证,这将为我们节省很多挫折,但转换文件可能更多超过人们愿意接受的程度。

基本上我们将 Web.base.config 存储在版本控制中,并通过转换运行它以在构建事件上生成 Web.config。

似乎 vs2010 会在拥有一个更友好的版本方面真正有所帮助。

【问题讨论】:

  • 在我的项目中,我有一个受版本控制的 web.svn.config,而 web.config 不是,因为每个开发人员都需要有自己的配置文件。对开发人员 web.config 的更改(除了连接字符串)被手动复制到基于 svn 的配置中。我不知道有什么工具可以合并到 web.configs。
  • 这基本上是我们今天所做的,只是我们在源代码控制中使用 web.config.. 尽量避免环境差异,并且有一个丑陋的系统,只要有环境设置,我们就会保留每个开发人员设置那里注释掉了..因此,您从 web.config 更改中做的第一件事就是找到您的特定设置并取消注释它们.. 这似乎与您的方案没有什么不同,只是稍微相反.. 这是有问题的,随着应用程序的发展,它可能需要越来越多的更改,这对开发人员来说是一个严重的拖累。

标签: version-control xslt msbuild web-config


【解决方案1】:

我有时使用的一种方法是将特定于环境的部分分解为单独的配置文件,这些文件通常被排除在部署之外(第一次或结构发生变化时除外):

连接字符串示例: 在 web.config 中:

<connectionStrings configSource="connections.config"></connectionStrings>

connections.config 文件(通常不包含在部署中;因此未更改):

<?xml version="1.0"?>
<connectionStrings>
    <add name="connectionName" connectionString="[connection string goes here]"/>
</connectionStrings>

就像我们已经创建了信息的“封装”,并且可以轻松处理源代码控制、部署等问题。

【讨论】:

  • 这当然是比我们目前做的更好的方法,但仍然存在一些问题,例如 - 使用我们的服务定位器,基本配置可能会注册 100 个服务......并且每台开发机器可能想要覆盖也许其中只有 5 个.. 必须委派整个配置部分意味着每个开发人员都有一份注册了其特定更改的 100 个服务的副本.. 如果基本配置发生更改(以添加更多服务),开发人员需要请注意.. 我正在寻找可以删除尽可能多的“GAH!”的东西。尽可能多的时间,这就是为什么配置继承会是完美的......*继续*
  • .. 另外,如果转换概念足够丰富,可以让我们执行类似 xpath 的过滤器以在需要时覆盖非常特定的部分,那么转换概念应该也能正常工作。 -机器配置部分对我们来说绝对没问题。
【解决方案2】:

虽然肯定有很多解决方案,但它们都没有真正让您对生成的配置进行大量控制,我在编辑中提到的一种解决方案可以让您获得大量控制,但需要付出一定的开销编写一个 xslt 文件,使用 xslt 构建任务来使用来自源代码管理的模板 web.config/app.config(我个人命名为 web.base.config/app.base.config),并使用 xslt 文件进行转换构建时版本控制的配置文件,并生成 web.config/app.config。

这是xslt build task 的示例(尽管您可能希望将其编写为您自己的编码标准),以及一个普通的 xslt 转换示例,它将更改连接字符串的值并复制配置:

<?xml version="1.0" encoding="utf-8"?>  
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl">  
  <xsl:output method="xml" indent="yes"/>  

  <!-- Copy all. -->  
  <xsl:template match="@* | node()">  
      <xsl:copy>  
          <xsl:apply-templates select="@* | node()"/>  
      </xsl:copy>  
  </xsl:template>  

  <!-- Swap connection string. -->
  <xsl:template match="/configuration/connectionStrings/add[@name='my_connection_string_name']">
    <xsl:copy>
      <xsl:apply-templates select="@* | node()"/>
      <xsl:attribute name="connectionString">my replacement connection string value</xsl:attribute>
    </xsl:copy>  
  </xsl:template>

</xsl:stylesheet> 

这是一个平庸的例子,但您可以想象您可以完全转换以前在基于继承的场景中难以解决的整个部分。

【讨论】:

  • 这确实有效,但它有一个缺点。您无法干净地对 web.config 进行版本化。这意味着您错过了 VS 对该文件所做的任何魔术。想到 WCF 配置,VS 神奇地将大量默认配置信息添加到 app/web 配置中。理想情况下,这种转换将发生在运行时,而不是编译时。
  • 真是太棒了!就 System.Configuration API 的怪异和 XML 命名空间无意识而言,使用 XSLT 成为最佳解决方案之一。不过会先尝试 XDT。
【解决方案3】:

VS 2010 将为您提供大量控制来管理各种配置的 web.config 文件...Please check out

【讨论】:

    【解决方案4】:

    应用程序的配置可以分为两类。

    1. 特定应用
    2. 特定于部署

    应用程序特定配置包括缓存实现、业务规则实现等内容,并将应用于应用程序的每个部署。这应该进入 web.config 文件,该文件是应用程序目录结构的一部分,并被检查到源代码管理中。

    特定于部署的配置包括连接字符串、超时时间等,并且可能因部署而异。这应该作为部署中涉及的 IIS 实例配置的一部分输入,并由相关机器的任何备份策略保留。

    据我所知,这正是 web.config 文件的分层特性旨在处理的内容。

    这种安排的好处是……

    1. 无需担心哪个开发者版本的设置最终会进入源代码管理,因为它们都不会。
    2. 每个部署都使用相同的二进制文件,因此部署问题更可能涉及部署配置。
    3. 后续部署不需要更改特定于部署的配置,因为它们已经到位。

    【讨论】:

    • 感谢 belugabob,是的,我同意配置数据包含恒定的应用程序部分和环境部分.. web.config 文件的继承模型设计得更适合分组应用程序(服务器上的应用程序和应用程序)在网站中)可以共享环境设置,而不是作为调试功能。正如我所说,我很想利用 web.config 继承模型,但是.. 怎么样?我有两个地方可以进行更改:整个 iis 机器..(不好,每台开发机器可能在多个项目上工作,iis 不只专注于一个).. web.config .. 继续
    • .. 我无法更改 web.config ,因为那是在源代码控制下.. 我能想到的最接近的方法是在站点下配置一个目录(或应用程序目录) ,在其中粘贴一个 web.config 以覆盖设置-并在其中粘贴诸如 URL 重写之类的东西以将请求路由回根目录,同时保持在当前应用程序的上下文中..甚至不确定这是否可能..
    • 将设置放在 iis 机器上应该没有问题,因为您可以通过将“命名空间”应用于属性来避免应用程序之间的冲突。称它们为“AppName.properties.settings.connectionString”,它们都可以愉快地共存。
    • 并不总是可能的,记住这不仅仅是关于连接字符串或应用程序设置。在我的第三次编辑中,我已经注意到今天使用 xslt 转换如何实现这一点 - 只要它工作得很好您可以忍受编写一些 xslt .. 这比配置继承更好,因为您可以定位例如 - 只需更改单个属性值等,而不必覆盖整个部分。
    【解决方案5】:

    我们不在 web.config 中存储环境设置。 它们存储在数据库中。

    这使我们能够进行 xcopy 部署,并将 web.config 文件存储在我们的版本控制系统中。

    通过一个注册表项访问数据库。

    【讨论】:

    • 我认为这会对应用程序产生相当大的影响,例如 - 我们可能希望每台机器配置我们的服务定位器略有不同..所有这些都需要我们让我们的应用程序意识到需要去并通过其配置文件从数据库中查找设置.. vs config,而且这将是有问题的,因为它不能很好地解决我们的基本“应用”配置问题,并覆盖“机器”配置设置。
    • 当然,我很明白。对我们来说,我们为每个开发人员提供不同的数据库,然后为开发、测试和实时提供一个通用的数据库。由于一切都是从一开始就这样设计的,这很好,但要转换成那样需要相当多的工作。
    【解决方案6】:

    您所描述的内容听起来很像使用 Machine.config 文件来存储连接字符串。我还没有看到提到过,所以你试过吗?看起来您也可以使用位于 Machine.config 旁边的全局 Web.config。

    几个链接:

    ASP.NET Configuration File Hierarchy and Inheritance

    Difference between Web.config and Machine.config

    【讨论】:

    • 它很好,但它的机器范围设置,鉴于我们有多种解决方案,它不会真正起作用。
    猜你喜欢
    • 2018-10-30
    • 1970-01-01
    • 2021-12-03
    • 2019-05-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-01
    • 1970-01-01
    相关资源
    最近更新 更多