Visual Studio 中开发人员特定的 app.config/web.config 文件

发布于 2024-09-19 08:35:16 字数 426 浏览 8 评论 0原文

我们有几个 .NET 项目,我们将某些设置存储在配置文件中。

现在,每个开发人员都有自己的配置文件,这些配置文件略有不同(连接到本地数据库的连接字符串不同,不同的 WCF 端点等)

目前,我们倾向于检查 app/web.config 文件并修改它们以满足我们的需求。

这会导致许多问题,因为从 TFS

你如何处理这样的情况?或者说你根本没有这个问题?

We have several .NET projects where we store certain settings in configuration files.

Now each developer will have their own configuration files that differ a little (different connection strings to connect to local databases, different WCF endpoints, etc.)

At the moment we tend to check out app/web.config files and modify them to suit our needs.

This leads to many problems since from time to time someone will check in their own settings or loose custom configuration when getting latest version from TFS.

How do you deal with situations like this? Or don't you have this problem at all?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(9

七分※倦醒 2024-09-26 08:35:16

我们使用的系统结合了本页上的几个现有答案,并借鉴了 Scott Hanselman 的建议

简而言之,我们所做的就是拥有一个通用的 app.config / web.config,并将大部分特定设置放在各个文件中,正如此处其他答案所建议的那样。例如,对于我们的 SMTP 设置,app.config 包含

<system.net>
  <mailSettings>
    <smtp configSource="config\smtp.config" />
  </mailSettings>
</system.net>

此文件位于源代码管理中。然而,像这样的单个文件却并非如此:

<?xml version="1.0" encoding="utf-8" ?>
<smtp deliveryMethod="Network">
  <network host="127.0.0.1" port="25" defaultCredentials="false" password="" userName ="" />
</smtp>

但这并不是故事的结局。新的开发人员或新的源安装怎么样?大部分配置不再位于源代码管理中,手动构建所需的所有 .config 文件非常痛苦。我更喜欢拥有至少可以立即编译的源代码。

因此,我们确实在源代码管理中保留了 .config 文件的一个版本,名为 .config.default 文件。因此,新的源代码树如下所示:

alt text

不过,对开发人员来说实际上没有任何用处,因为对于 Visual Studio 来说它们只是毫无意义的文本文件。因此,批处理文件 copy_default_config.bat 负责从 .config.default 文件创建一组初始 .config 文件:

@echo off
@REM Makes copies of all .default files without the .default extension, only if it doesn't already exist. Does the same recursively through all child folders.
for /r %%f in (*.default) do (
    if not exist "%%~pnf" (echo Copying %%~pnf.default to %%~pnf & copy "%%f" "%%~pnf" /y)
)
echo Done.

该脚本可以安全地重新运行,因为已经拥有其.config 文件不会覆盖它们。因此,可以想象,可以将此批处理文件作为预构建事件运行。 .default 文件中的值对于新安装可能不完全正确,但它们是一个合理的起点。

最终每个开发人员最终得到的是一个配置文件的文件夹,如下所示:

alt text

它可能看起来有点虽然很复杂,但这绝对比开发人员互相踩脚趾的麻烦要好。

We use a system that combines several of the existing answers on this page, plus draws on this suggestion by Scott Hanselman.

In short, what we did was to have a common app.config / web.config, and to have most of the specific settings in individual files, as suggested by other answers here. e.g. for our SMTP settings, the app.config contains

<system.net>
  <mailSettings>
    <smtp configSource="config\smtp.config" />
  </mailSettings>
</system.net>

This file is in source control. However, the individual files, like this, are not:

<?xml version="1.0" encoding="utf-8" ?>
<smtp deliveryMethod="Network">
  <network host="127.0.0.1" port="25" defaultCredentials="false" password="" userName ="" />
</smtp>

That's not quite where the story ends though. What about new developers, or a fresh source installation? The bulk of the configuration is no longer in source control, and it's a pain to manually build all of the .config files they need. I prefer to have source that will at least compile right out of the box.

Therefore we do keep a version of the .config files in source control, named .config.default files. A fresh source tree therefore looks like this:

alt text

Still, not really any use to the developer, since to Visual Studio they're just meaningless text files. Hence the batch file, copy_default_config.bat, takes care of creating an initial set of .config files from the .config.default files:

@echo off
@REM Makes copies of all .default files without the .default extension, only if it doesn't already exist. Does the same recursively through all child folders.
for /r %%f in (*.default) do (
    if not exist "%%~pnf" (echo Copying %%~pnf.default to %%~pnf & copy "%%f" "%%~pnf" /y)
)
echo Done.

The script is safely re-runnable, in that developers who already have their .config files will not have them overwritten. Therefore, one could conceivably run this batch file as a pre-build event. The values in the .default files may not be exactly correct for a new install, but they're a reasonable starting point.

Ultimately what each developer ends up with is a folder of config files that looks something like this:

alt text

It may seem a little convoluted, but it's definitely preferable to the hassle of developers stepping on each other's toes.

够钟 2024-09-26 08:35:16

在您的 Web.config 中使用来自其他文件的源代码

<configuration>
    <connectionStrings configSource="ConnectionStrings.config" />
...
</configuration>

将 web.config 保留在版本控制中,并且不要对 ConnectionStrings.config 执行此操作。
现在,所有开发人员都拥有一个用于连接字符串的文件。

您可以对所有本地相关设置执行此操作。

In your Web.config use source from other files

<configuration>
    <connectionStrings configSource="ConnectionStrings.config" />
...
</configuration>

Keep the web.config in version control and don't do it for ConnectionStrings.config.
Now all developers have one file for the connection string.

You can do this for all the settings that are local dependant.

舂唻埖巳落 2024-09-26 08:35:16

下面是针对 web.config 文件和 Visual Studio 2010 的解决方案:

1) 手动编辑 Web 应用程序 .csproj 文件以添加 AfterBuild 目标,如下所示:

  <Project>
   ...
    <Target Name="AfterBuild">
      <Copy SourceFiles="web.config" DestinationFiles="obj\$(Configuration)\tempweb.config" />
      <TransformXml Source="obj\$(Configuration)\tempweb.config"
                  Transform="web.$(USERNAME).config"
                  Destination="obj\$(Configuration)\tempweb2.config" />
      <ReadLinesFromFile File="obj\$(Configuration)\tempweb2.config"><Output TaskParameter="Lines" ItemName="TransformedWebConfig"/></ReadLinesFromFile>
      <ReadLinesFromFile File="web.config"><Output TaskParameter="Lines" ItemName="UnTransformedWebConfig"/></ReadLinesFromFile>
      <Copy Condition=" @(UnTransformedWebConfig) != @(TransformedWebConfig) " SourceFiles="obj\$(Configuration)\tempweb2.config" DestinationFiles="web.config" OverwriteReadOnlyFiles="True" />
    </Target>
  </Project>

该目标将转换与以下内容对应的 Web.config 文件:当前开发人员已登录 - 因此是 $(USERNAME) 变量 - 以及 1) 中创建的相应文件。
仅当内容在每次构建时发生更改(以避免重新启动)时,它才会替换本地 Web.config,即使本地 Web.config 受源代码控制,这就是 OverwriteReadOnlyFiles 设置为真的。这一点其实是值得商榷的。

2) 为项目中的每个开发人员创建一个名为 Web.[developer windows login].config 的文件。 (例如,在下面的屏幕截图中,我有两个名为 smo 和 smo2 的开发人员):

在此处输入图像描述

这些文件(每个 1 个)开发人员)可以/应该进行源代码控制。它们不应该被标记为依赖于主 Web.config,因为我们希望能够单独检查它们。

每个文件都代表一个应用于主 Web.Config 文件的转换。
转换语法如下所述:Web 应用程序项目部署的 Web.config 转换语法。我们重用了这个很酷的 Xml 文件转换任务,它是 Visual Studio 中开箱即用的。此任务的目的是合并 Xml 元素和属性,而不是覆盖整个文件。

例如,下面是一个示例 web.[dev login].config,它更改名为“MyDB”的连接字符串,而不考虑 Web.config 文件的其余部分:

<?xml version="1.0"?>
<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
    <connectionStrings>
      <add name="MyDB" 
        connectionString="Data Source=ReleaseSQLServer;Initial Catalog=MyReleaseDB;Integrated Security=True" 
        xdt:Transform="SetAttributes" xdt:Locator="Match(name)" />
    </connectionStrings>
</configuration>

现在,此解决方案并不完美因为:

  • 构建后,开发人员可能在本地拥有与源代码控制系统不同的 Web.Config,
  • 当从源代码控制系统获取新的 Web.Config 时,开发人员可能必须强制本地写入,
  • 开发人员不应签出/签入主 Web。配置。它应该保留给少数人。

但至少,您只需维护一个唯一的主 web.config 以及每个开发人员一个转换文件。

对于 App.config(不是 Web)文件可以采取类似的方法,但我没有进一步详细说明。

Here a solution for web.config files and Visual Studio 2010:

1) Edit manually your web application .csproj file to add an AfterBuild Target like this:

  <Project>
   ...
    <Target Name="AfterBuild">
      <Copy SourceFiles="web.config" DestinationFiles="obj\$(Configuration)\tempweb.config" />
      <TransformXml Source="obj\$(Configuration)\tempweb.config"
                  Transform="web.$(USERNAME).config"
                  Destination="obj\$(Configuration)\tempweb2.config" />
      <ReadLinesFromFile File="obj\$(Configuration)\tempweb2.config"><Output TaskParameter="Lines" ItemName="TransformedWebConfig"/></ReadLinesFromFile>
      <ReadLinesFromFile File="web.config"><Output TaskParameter="Lines" ItemName="UnTransformedWebConfig"/></ReadLinesFromFile>
      <Copy Condition=" @(UnTransformedWebConfig) != @(TransformedWebConfig) " SourceFiles="obj\$(Configuration)\tempweb2.config" DestinationFiles="web.config" OverwriteReadOnlyFiles="True" />
    </Target>
  </Project>

This target will transform the Web.config file corresponding to the current developer logged in - hence the $(USERNAME) variable -, with the corresponding file created in 1).
It will replace the local Web.config only if the content has changed (to avoid restart) at each build, even if the local Web.config is source controlled, that's why there is the OverwriteReadOnlyFiles is set to True. This point in fact is arguable.

2) Create a file named Web.[developer windows login].config for each developer in the project. (for example in the following screenshots I have two developers named smo and smo2):

enter image description here

These files (1 per developer) can/should be source-controlled. They should not be marked as dependent on the main Web.config because we want to be able to check them out individually.

Each of this file represent a transformation to apply to the main Web.Config file.
The transformation syntax is described here: Web.config Transformation Syntax for Web Application Project Deployment. We reuse this cool Xml file transformation task that comes out-of-the-box with Visual Studio. The purpose of this task is merge Xml elements and attributes instead of overwriting the whole file.

For example, here is a sample web.[dev login].config that changes a connection string named 'MyDB', regardless of the rest of the Web.config file:

<?xml version="1.0"?>
<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
    <connectionStrings>
      <add name="MyDB" 
        connectionString="Data Source=ReleaseSQLServer;Initial Catalog=MyReleaseDB;Integrated Security=True" 
        xdt:Transform="SetAttributes" xdt:Locator="Match(name)" />
    </connectionStrings>
</configuration>

Now, this solution is not perfect because:

  • after building, developers may have a different Web.Config locally than in the source control system
  • they may have to force local write when getting a new Web.Config from the source control system
  • developers should not check out/in the main web.config. It should be reserved to few people.

But at least, you only have to maintain a unique main web.config plus one transformation file per developer.

A similar approach could be taken for App.config (not web) files but I did not elaborate further.

孤凫 2024-09-26 08:35:16

我们使用 machine.config 来避免环境之间的 web.config 存在差异。

We are using machine.config to avoid having differences in web.config between the environments.

海之角 2024-09-26 08:35:16

忽略该文件,使其永远不会被签入怎么样?我遇到了类似的问题,并将 web.config 添加到 Subversion 的忽略列表中。

但在 TFS 中,这有点困难,请参阅这篇文章< /a> 关于如何做到这一点。

How about ignoring the file, so it never gets checked in? I've run into a similar issue and have added web.config to the ignore list in Subversion.

In TFS though, it's a little bit harder, see this post on how to do it.

夢归不見 2024-09-26 08:35:16

您可以应对的一种方法是拥有一个代币化系统并使用 rake 脚本来更改值。

一个更基本的方法可能是为 web.config 中的所有 AppSettings 提供一个指向 AppSettings.config 文件的链接(与连接类似),即

<appSettings configSource="_configs/AppSettings.config" />

然后有一个文件夹,每个开发人员在子文件夹中都有一个版本(即 /_configs /戴夫/)。然后,当开发人员处理自己的代码时,他们会从子文件夹复制到链接文件夹的根目录。

您需要确保传达对这些文件的更改(除非您标记化)。如果您将 AppSettings.config 文件置于源代码控制之外,并且仅签入开发人员的各个文件夹(所有文件夹),那么他们将被迫复制正确的文件夹。

我更喜欢标记化,但如果这只是一个快速修复,那么启动和运行可能会更困难。

One way you could cope is to have a tokenised system and use a rake script to change the values.

A more rudimentary method could be to have a link to an AppSettings.config file for all AppSettings in your web.config (similar with connections) i.e.

<appSettings configSource="_configs/AppSettings.config" />

Then have a folder with each of your developers have a version in a sub folder (i.e. /_configs/dave/). Then when a developer is working on their own code they copy from the sub folder to the root of the linked folder.

You will need to make sure you communicate changes to these files (unless you tokenise). If you keep the AppSettings.config file out of source control and only check in the devs individual folders (all of them) then they will be forced to copy the correct one.

I prefer tokenisation but can be tougher to get up and running if this is only meant to be a quick fix.

看轻我的陪伴 2024-09-26 08:35:16

忽略这些文件并拥有 Commom_Web.Config 和 Common_App.Config。使用带有构建任务的持续集成构建服务器,将这两个任务重命名为正常名称,以便构建服务器可以完成其工作。

Ignore the files and have a Commom_Web.Config and Common_App.Config. Using a continuous integration build server with build tasks which rename these two to normal names so that the build server can do its job.

柒七 2024-09-26 08:35:16

我们有同样的问题,我们正在做的是

  • 使用测试服务器/生产值检查 web.config
  • 开发人员转到 Windows 资源管理器并更改文件的只读模式
  • 编辑配置以适合他们的环境。
  • 仅当部署值更改或添加或删除任何配置条目时,才会签入 web.config。
  • 这需要为每个配置条目提供大量注释,因为每个开发人员都需要对其进行更改

We have the same problem and what we are doing is

  • Check in the web.config with testserver / production values
  • Developer goes to windows explorer and change the read only mode of the file
  • Edit the config to suit to their environment.
  • Check in into the web.config happens only when deployment values changes or any config entry is added or deleted.
  • This needs a good amount of comment for each config entry as it needs to be changed by each dev
从此见与不见 2024-09-26 08:35:16

假设您使用的是 Visual Studio,为什么不使用不同的解决方案配置?
例如:您可以拥有使用 Web.config.debug 的调试配置和使用 Web.config.release 的发布配置。 Web.config.debug 应该具有类似于

<appSettings file="C:/Standard_Path_To_Configs/Standard_Name_For_Config.config"> 

文件 Standard_Name_For_Config.config 的内容,该文件获取所有个人开发人员设置,而 Web.config.release 始终具有生产设置。
您可以将默认配置存储在某些源代码管理文件夹中,并让新用户从那里获取它们。

Assuming you are using Visual Studio, why don't you use different Solution Configurations?
For example: you can have a Debug config which uses Web.config.debug and a Release config which uses Web.config.release. Web.config.debug should have something like

<appSettings file="C:/Standard_Path_To_Configs/Standard_Name_For_Config.config"> 

with the file Standard_Name_For_Config.config that gots all the personal developer settings, while the Web.config.release always has the production settings.
You can store default configs in some source controlled folder and make a new user take them from there.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文