.NET配置(app.config / web.config / settings.settings)

时间:2020-03-06 14:42:51  来源:igfitidea点击:

我有一个.NET应用程序,它具有用于Debug和Release构建的不同配置文件。例如。 debug app.config文件指向已启用调试的开发SQL Server,发布目标指向实时SQL Server。还有其他设置,其中一些在调试/发行版中有所不同。

我目前使用两个单独的配置文件(debug.app.config和release.app.config)。我在项目上有一个构建事件,它说如果这是发行版本,则将release.app.config复制到app.config,否则将debug.app.config复制到app.config。

问题在于该应用程序似乎是从settings.settings文件获取其设置的,所以我必须在Visual Studio中打开settings.settings,然后提示我设置已更改,因此我接受更改,保存settings.settings并重建以使其使用正确的设置。

是否有更好/推荐/首选的方法来达到类似的效果?或者同样,我是否完全解决了这个错误,是否有更好的方法?

解决方案

我现在的老板通过首先将开发人员级别(调试,阶段,实时等)放置在machine.config文件中来解决此问题。然后他们编写了代码以进行选择并使用正确的配置文件。部署应用程序后,使用错误的连接字符串解决了该问题。

他们最近才编写了一个中央Web服务,该服务从machine.config值中的值发送回正确的连接字符串。

这是最好的解决方案吗?可能不是,但是对他们有用。

在我看来,我们可以从Visual Studio 2005 Web部署项目中受益。

这样,我们可以告诉它根据构建配置来更新/修改web.config文件的各个部分。

请查看Scott Gu的这篇博客文章,以快速获得概述/示例。

这里有一个相关的问题:

改善构建过程

配置文件带有一种覆盖设置的方法:

<appSettings file="Local.config">

无需检入两个(或者多个)文件,而仅检入默认配置文件,然后在每台目标计算机上,放置一个Local.config,其中只有appSettings部分具有该特定计算机的替代项。

如果我们使用的是config节,则等效项为:

configSource="Local.config"

当然,最好从其他计算机制作所有Local.config文件的备份副本,并在某个位置检入它们,但不作为实际解决方案的一部分。每个开发人员都会在Local.config文件上放置一个"忽略",以便它不会被签入,这将覆盖其他所有人的文件。

(我们实际上不必将其称为" Local.config",这就是我所使用的)

从我阅读的内容来看,听起来好像我们在使用Visual Studio进行构建过程。我们是否考虑过使用MSBuild和Nant?

Nant的xml语法有点古怪,但是一旦我们理解了它,做我们提到的事情就变得很简单了。

<target name="build">
    <property name="config.type" value="Release" />

    <msbuild project="${filename}" target="Build" verbose="true" failonerror="true">
        <property name="Configuration" value="${config.type}" />
    </msbuild>

    <if test="${config.type == 'Debug'}">
        <copy file=${debug.app.config}" tofile="${app.config}" />
    </if>

    <if test="${config.type == 'Release'}">
        <copy file=${release.app.config}" tofile="${app.config}" />
    </if>

</target>

最有效的解决方案之一是使用WebDeploymentProject。
我的网站中有2/3个不同的web.config文件,并且在发布时,根据所选的配置模式(发行/登台/等...),我将在Web.Release.config上进行复制并将其重命名为Web。在AfterBuild事件中进行配置,并删除不需要的内容(例如Web.Staging.config)。

<Target Name="AfterBuild">
    <!--Web.config -->
    <Copy Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' " SourceFiles="$(SourceWebPhysicalPath)\Web.Release.config" DestinationFiles="$(OutputPath)\Web.config" />
    <Copy Condition=" '$(Configuration)|$(Platform)' == 'Staging|AnyCPU' " SourceFiles="$(SourceWebPhysicalPath)\Web.Staging.config" DestinationFiles="$(OutputPath)\Web.config" />
    <!--Delete extra files -->
    <Delete Files="$(OutputPath)\Web.Release.config" />
    <Delete Files="$(OutputPath)\Web.Staging.config" />
    <Delete Files="@(ProjFiles)" />
  </Target>

我们曾经使用过Web Deployment项目,但此后已迁移到NAnt。当前没有分支和复制不同的设置文件,我们当前将配置值直接嵌入到构建脚本中,并通过xmlpoke任务将它们注入到我们的配置文件中:

<xmlpoke
    file="${stagingTarget}/web.config"
    xpath="/configuration/system.web/compilation/@debug"
    value="true"
  />

无论哪种情况,配置文件都可以具有我们想要的任何开发人员值,并且它们可以在开发环境中正常工作而不会破坏生产系统。我们发现开发人员在进行测试时不太可能随意更改构建脚本变量,因此意外的错误配置比我们尝试过的其他技术少见,尽管仍然有必要在过程的早期添加每个var默认情况下,dev值不会推送到prod。

我们将在这里找到另一种解决方案:在ASP.NET中的开发/ UAT /产品环境之间切换配置的最佳方法?使用XSLT转换为web.config。

在使用NAnt方面也有一些很好的例子。

跨环境的任何配置都应存储在计算机级别,而不是应用程序级别。 (有关配置级别的更多信息。)

这些是我通常在计算机级别存储的配置元素的种类:

  • 应用程序设置
  • 连接字符串
  • 零售=真
  • Smtp设定
  • 健康监测
  • 托管环境
  • 机器钥匙

当每个环境(开发人员,集成,测试,阶段,实时)在c:\ Windows \ Microsoft.NET \ Framework64 \ v2.0.50727 \ CONFIG目录中都有其自己的唯一设置时,则可以在环境之间升级应用程序代码而无需任何操作构建后的修改。

显然,计算机级CONFIG目录的内容在与应用程序不同的存储库或者不同的文件夹结构中受版本控制。我们可以通过智能使用configSource使.config文件对源代码的控制更加友好。

我已经在超过25个不同公司的200多个ASP.NET应用程序上进行了7年的研究。 (不是在吹牛,只是想让我们知道,我从未见过这种方法行不通的情况。)

像我们一样,我还设置了" multi" app.config,例如app.configDEV,app.configTEST,app.config.LOCAL。我看到了一些很好的建议,但是,如果我们喜欢它的工作方式,请添加以下内容:

我有一个
&lt;appSettings>
&lt;添加键=" Env"值=" [本地]" />

对于每个应用程序,我将其添加到标题栏中的UI中:
来自ConfigurationManager.AppSettings.Get(" Env");

我只是将配置重命名为我要定位的配置(我有一个包含8个应用程序的项目,其中有许多数据库/ wcf配置针对4个事件)。为了将clickonce部署到每个部署中,我在项目中更改了4个空缺。 (这我想自动化)

我唯一的陷阱是记住在更改后"清除所有内容",因为手动重命名后旧配置被"卡住"了。 (我认为这将解决setting.setting问题)。

我发现这真的很好用(有一天,我将有时间看看MSBuild / NAnt)

我们的proj存在相同的问题,我们必须维护dev,qa,uat和prod的配置。这是我们遵循的内容(仅在我们熟悉MSBuild的情况下适用):

将MSBuild与MSBuild社区任务扩展一起使用。它包括" XmlMassUpdate"任务,一旦我们为其指定了正确的节点,便可以"批量更新"任何XML文件中的条目。

实施:

1)我们需要一个配置文件,其中将包含dev env条目;这是我们解决方案中的配置文件。

2)我们需要有一个'Substitutions.xml'文件,该文件仅包含每个环境的不同条目(主要是appSettings和ConnectionStrings)。跨环境未更改的条目无需放在此文件中。它们可以存在于解决方案的web.config文件中,而不会被任务触及

3)在构建文件中,只需调用XML批量更新任务并提供正确的环境作为参数即可。

<!-- Actual Config File -->
    <appSettings>
        <add key="ApplicationName" value="NameInDev"/>
        <add key="ThisDoesNotChange" value="Do not put in substitution file" />
    </appSettings>

    <!-- Substitutions.xml -->
    <configuration xmlns:xmu="urn:msbuildcommunitytasks-xmlmassupdate">
      <substitutions>
        <QA>
           <appSettings>
            <add xmu:key="key" key="ApplicationName" value="NameInQA"/>
           </appSettings>            
        </QA>
        <Prod>
          <appSettings>
            <add xmu:key="key" key="ApplicationName" value="NameInProd"/>
          </appSettings>            
        </Prod>
     </substitutions>
    </configuration>

<!-- Build.xml file-->

    <Target Name="UpdateConfigSections">
            <XmlMassUpdate ContentFile="Path\of\copy\of\latest web.config" SubstitutionsFile="path\of\substitutionFile" ContentRoot="/configuration" SubstitutionsRoot="/configuration/substitutions/$(Environment)" />
        </Target>

请参见下面的示例:

根据环境,将" $ Environment"替换为" QA"或者" Prod"。我们正在建立。请注意,我们应该处理配置文件的副本,而不要处理实际的配置文件本身,以避免任何可能的不可恢复的错误。

只需运行构建文件,然后将更新的配置文件移至部署环境即可!

有关更好的概述,请阅读以下内容:

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

这可能对某些处理Settings.settings和App.config的人有所帮助:在编辑Visual Studio(在我的情况下为Visual Studio 2008)的Settings.settings网格中的任何值时,请注意"属性"窗格中的GenerateDefaultValueInCode属性。

如果将GenerateDefaultValueInCode设置为True(此处为默认值,则为True!),则默认值将编译到EXE(或者DLL)中,当我们在纯文本编辑器中将其打开时,可以将其嵌入文件中。

段落数量不匹配