任何人都有任何关于处理环境之间web.config设置差异的好建议吗?我考虑在我们的源代码管理系统中创建一个'config'文件夹,但在Web层次结构之外,并让部署过程复制相应的配置文件(web.dev.config,web.staging.config,web.production.config) )部署后进入Web文件夹。我还看过有关如何在应用程序启动时以编程方式更改配置设置(WCF端点,连接字符串等)的帖子。
这里的最佳做法是什么,以及每个人对这些或其他方法有哪些经验?
2010年9月更新
值得注意的是,Visual Studio 2010通过web.config transforms添加了此功能。当您使用构建配置管理器(Build | Configuration Manager ...)为项目创建不同的配置(例如,Debug,Dev,Staging和Release)时,VS会将web。*。config文件添加到解决方案中。默认的web.config包含您将用于调试的基准设置。 web.release.config,web.staging.config等包含XSLT转换,每当您基于活动构建配置发布项目时将应用这些转换。
答案 0 :(得分:17)
我的方法是拥有多个配置文件。我在web.config文件中放置了所有与环境无关的东西(即,如果dev,staging或production无关紧要)。任何特定于环境的东西(即数据库连接信息,日志记录,调试设置等)我都放入了特定于环境的local.config文件中。然后,您可以使用configSource(http://weblogs.asp.net/fmarguerie/archive/2007/04/26/using-configsource-to-split-configuration-files.aspx)
在web.config中包含local.config设置然后可以将Web.config检入源代码管理。请勿检入local.config文件 - 这会强制您在部署脚本中部署正确的文件。
答案 1 :(得分:15)
使用新的VS,您可以使用Web配置转换。
在此处阅读更多内容:http://msdn.microsoft.com/en-us/library/dd465326.aspx
答案 2 :(得分:9)
我使用CruiseControl.NET / NAnt,NAnt有一个XMLPoke任务,允许您在构建时使用XPath查询并更改任何配置设置。
因此,在我的每个构建目标(DEV,UAT,STAGING等)中,我设置了一堆属性,然后调用主构建目标。主构建目标获取所有属性的值,并将它们XMLPokes引入配置和构建。
答案 3 :(得分:8)
我见过并使用过的一种方法是在web.config中设置密钥,以便按名称区分计算机。
例如:
<add key="comp1.Environment" value="DEV"/>
<add key="compdb1.Environment" value="PROD"/>
<add key="compstage.Environment" value="STAGE"/>
显然comp1,compdb1是实际的计算机名称。
然后你会设置类似的东西:
<add key="KeyName,DEV" value="DevEnvironmentValue"/>
在您的代码中,您需要检查运行应用程序的环境,然后获取相应的密钥,例如。
private string GetKeyValue() {
string machineName = String.Concat(System.Environment.MachineName, ".Environment");
string environment = ConfigurationManager.AppSettings[machineName];
string key = String.Concat("KeyName", ",", environment);
string keyValue = ConfigurationManager.AppSettings[key];
return keyValue;
}
答案 4 :(得分:3)
有一个名为Web Deployment project的项目类型,可以从Microsoft免费获得,它允许您完全这样做。您可以替换web.config的各个部分,具体取决于您的解决方案配置(调试,发布等)。我们使用它超过一年,并且运行良好。它适用于VS2005和VS2008。
希望这会有所帮助
答案 5 :(得分:3)
虽然其他一些答案可能更合适,但我会在2007年再添加Matt Berseth rolled his own method ...
总之,他保留了专有文本文件中环境之间不同的所有值,并在构建过程中使用自定义工具将值合并到.config文件中。
在对该帖子的评论中,Doron Yaacoby也评论道:
“MSBuild社区中有一项任务 可以实现这一目标的任务(以及更多) 对你来说,这叫做 XmlMassUpdate。 Ive written about it in my blog“
答案 6 :(得分:3)
以下是如何添加可在VS2012中为您的部署环境自定义的不同配置
在此之后,您需要使用特定于TEST环境的一些转换来修改web.TEST.config
答案 7 :(得分:1)
您需要安装环境,而不是构建一个环境。在现实世界中,您必须安装在QA中测试的内容,不允许重建。至少在我的世界里就是这样。
答案 8 :(得分:0)
Easy way to have that is having an Enumeration , then having a switch statement based on the server name ( if its stable name ) .
Call GetURIPath() where ever you require to fetch details , here I given the examples for url's used
public class StaticData
{
public enum enumEnvironment
{
envNONE = 0,
envLOC = 1,
envDEV = 2,
envTEST = 3,
envPROD = 4
}
private static enumEnvironment GetCurrentEnv()
{
if (ConfigurationManager.GetSection("DBSettingsGroup/DBSettings") == null && ConfigurationManager.GetSection("DBSettings") == null)
{
return enumEnvironment.envLOC;
}
else
{
NameValueCollection NVCollection = new NameValueCollection();
NVCollection = (NameValueCollection)ConfigurationManager.GetSection("DBSettingsGroup/DBSettings");
if(NVCollection == null)
{
NVCollection = (NameValueCollection)ConfigurationManager.GetSection("DBSettings");
}
string sEnv = NVCollection.GetValues("serverrole").ToString();
switch (sEnv.ToUpper())
{
case "DEV-ISOLATED":
return enumEnvironment.envDEV;
case "DEVELOPMENT":
return enumEnvironment.envDEV;
case "TEST":
return enumEnvironment.envTEST;
case "PRODUCTION":
return enumEnvironment.envPROD;
default:
return enumEnvironment.envNONE;
}
}
}
public static string GetURIPath()
{
switch (GetCurrentEnv())
{
case enumEnvironment.envPROD:
return "http://produrl/yourapp/api/";
case enumEnvironment.envTEST:
return "http://testurl/yourapp/api/";
case enumEnvironment.envDEV:
return "http://devurl/yourapp/api/";
default:
return "http://localhost/yourapp/api/";
}
}
}