![](/img/trans.png)
[英]web.config not app.config being published to xxx.dll.config in Visual Studio 2015
[英]Developer specific app.config/web.config files in Visual Studio
我们使用的系统结合了此页面上的几个现有答案,并借鉴了 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.default文件的 .config 文件版本。 因此,一个新的源代码树看起来像这样:
尽管如此,对于开发人员来说并没有什么用处,因为对于 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 文件中的值对于新安装可能不完全正确,但它们是一个合理的起点。
最终,每个开发人员最终得到的是一个配置文件文件夹,如下所示:
这可能看起来有点令人费解,但绝对比开发人员相互踩踏的麻烦要好。
在您的 Web.config 中使用来自其他文件的源
<configuration>
<connectionStrings configSource="ConnectionStrings.config" />
...
</configuration>
将 web.config 保留在版本控制中,不要为 ConnectionStrings.config 执行此操作。 现在所有开发人员都有一个用于连接字符串的文件。
您可以对所有本地相关的设置执行此操作。
这是 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
设置为 True 的原因。 这一点其实是值得商榷的。
2) 为项目中的每个开发者创建一个名为Web.[developer windows login].config
的文件。 (例如在以下屏幕截图中,我有两个名为 smo 和 smo2 的开发人员):
这些文件(每个开发人员 1 个)可以/应该是源代码控制的。 它们不应被标记为依赖于主 Web.config,因为我们希望能够单独检出它们。
此文件中的每一个都代表一个要应用于主 Web.Config 文件的转换。 此处描述了转换语法: Web 应用程序项目部署的 Web.config 转换语法。 我们重用 Visual Studio 自带的这个很酷的 Xml 文件转换任务。 此任务的目的是合并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 和一个转换文件。
可以对 App.config(不是 web)文件采取类似的方法,但我没有进一步详细说明。
我们使用 machine.config 来避免环境之间的 web.config 存在差异。
忽略该文件如何,因此它永远不会被签入? 我遇到了类似的问题,并将 web.config 添加到 Subversion 的忽略列表中。
但是在 TFS 中,它有点困难,请参阅有关如何执行此操作的帖子。
您可以应对的一种方法是拥有一个标记化系统并使用 rake 脚本来更改值。
一种更基本的方法可能是为 web.config 中的所有 AppSettings 设置一个 AppSettings.config 文件的链接(类似于连接),即
<appSettings configSource="_configs/AppSettings.config" />
然后有一个文件夹,每个开发人员在子文件夹(即/_configs/dave/)中有一个版本。 然后,当开发人员处理他们自己的代码时,他们会从子文件夹复制到链接文件夹的根目录。
您需要确保您传达对这些文件的更改(除非您标记化)。 如果您将 AppSettings.config 文件置于源代码管理之外,并且只签入开发人员的各个文件夹(所有这些文件夹),那么他们将被迫复制正确的文件夹。
我更喜欢标记化,但如果这只是一个快速解决方案,那么启动和运行可能会更加困难。
忽略这些文件并有一个 Commom_Web.Config 和 Common_App.Config。 使用具有构建任务的持续集成构建服务器,将这两个重命名为正常名称,以便构建服务器可以完成其工作。
我们有同样的问题,我们正在做的是
假设您使用的是 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 始终具有生产设置。 您可以将默认配置存储在某个源代码控制文件夹中,并让新用户从那里获取它们。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.