在开发,登台和生产环境之间区分web.config

时间:2009-09-10 15:58:06

标签: asp.net deployment configuration web-config

任何人都有任何关于处理环境之间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转换,每当您基于活动构建配置发布项目时将应用这些转换。

9 个答案:

答案 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中为您的部署环境自定义的不同配置

  1. 右键单击解决方案并选择配置管理器
  2. 单击“配置管理器”按钮
  3. 在“配置”列下,选择针对项目的组合框 您要添加配置并选择
  4. 使用名称如TEST和复制设置创建新配置 从发布并选中创建新解决方案配置复选框
  5. 右键单击Web.config
  6. 添加配置转换
  7. 然后你得到一个额外的web.config例如web.TEST.config
  8. 在此之后,您需要使用特定于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/";
        }
    }

}