【问题标题】:How to make sure we publish production to the prod server and test to the test server如何确保我们将生产发布到产品服务器并测试到测试服务器
【发布时间】:2009-05-29 08:30:44
【问题描述】:

我的 Web.Config 文件中有一个条目,指示我所在的连接字符串和垃圾环境:

<add key="AppEnv" value ="2" /> <!--(0 = Dev, 1 = test, 2 = prod)--> 

我正在寻找一种在发布时提醒开发人员的方法,以确保他们已检查此键/值,以便他们不会将“测试”发布到“产品”服务器,反之亦然.

谢谢

【问题讨论】:

    标签: asp.net web-config publishing


    【解决方案1】:

    我已经提出了我自己的(可能是非常规的)解决方案来解决这个问题。我们为许多不同的客户开发了许多不同的 Web 项目,并且由于我们在多个 web.config 文件中遇到的所有问题,或者在发布前需要进行编辑,因此将它们全部迁移到这种方法。

    基本上,我们让我们的应用根据传入的 URL 告诉我们它在哪个环境下运行。我们在第一个请求时对其进行初始化,并将其存储在应用程序生命周期的内存中。通过这种方式,我们可以将每个环境特定的配置值存储在同一个配置文件中,并使用 Development、Staging、Production 等对其进行限定。任何在环境之间没有差异的设置都不需要限定。

    首先是一个示例 web.config:

    <appSettings>
        <add key="DevelopmentHost" value="dev.trackmyhours.com" />
        <add key="StagingHost" value="staging.trackmyhours.com" />
        <add key="ProductionHost" value="www.trackmyhours.com" />
      </appSettings>
    
      <connectionStrings>
        <clear />
        <add name="DevelopmentConnectionString" connectionString="your dev conn string" providerName="System.Data.SqlClient" />
        <add name="StagingConnectionString" connectionString="your staging conn string (mine is typically same as staging)" providerName="System.Data.SqlClient" />
        <add name="ProductionConnectionString" connectionString="your production conn string" providerName="System.Data.SqlClient" />
      </connectionStrings>
    

    接下来我们有一个“App”类,它使我们能够访问我们的“Site”类,但是您可以按照您认为合适的方式构建您的类。

    Public Class App
    
        Private Shared _Site As New Site
        Public Shared ReadOnly Property Site() As Site
            Get
                Return _Site
            End Get
        End Property
    
    End Class
    

    Imports System.Configuration
    Imports System.Web
    
    Public Class Site
    
        Public Enum EnvironmentType
            Development
            Staging
            Production
        End Enum
    
        Friend Sub New()
    
            If HttpContext.Current IsNot Nothing Then
    
                Dim URL = HttpContext.Current.Request.Url.DnsSafeHost
    
                Select Case URL
                    Case ConfigurationManager.AppSettings("DevelopmentHost"), "localhost"
                        _Environment = EnvironmentType.Development
                    Case ConfigurationManager.AppSettings("StagingHost")
                        _Environment = EnvironmentType.Staging
                    Case ConfigurationManager.AppSettings("ProductionHost")
                        _Environment = EnvironmentType.Production
                End Select
    
            Else
                'probably getting called from a winforms/console app, or unit tests
                _Environment = EnvironmentType.Staging
    
            End If
    
            _ConnectionString = ConfigurationManager.ConnectionStrings(_Environment.ToString & "ConnectionString").ConnectionString
    
        End Sub
    
    
        Private _Environment As EnvironmentType
        Public Property Environment() As EnvironmentType
            Get
                Return _Environment
            End Get
            Set(ByVal value As EnvironmentType)
                _Environment = value
    
                _ConnectionString = ConfigurationManager.ConnectionStrings(_Environment.ToString & "ConnectionString").ConnectionString
    
            End Set
        End Property
    
        Private _ConnectionString As String
        Public ReadOnly Property ConnectionString() As String
            Get
                Return _ConnectionString
            End Get
        End Property
    
    End Class
    

    我们将类放入 Biz Object 类库中。我们刚刚决定不必确定每个请求的环境,因为它在应用程序的生命周期内确实无法更改。此外,这允许我们在库中的代码或后面的代码中从 ANYWHERE 引用 App.Site.Environment。如果您需要在代码中添加一些条件逻辑,这也很有帮助 - 例如在 dev/staging 中运行时不向真实的人发送电子邮件。

    最后一件事 - 对于我们的 Linq2SQL 或 EF Data/ObjectContexts,我们不会将连接字符串存储在文件中,而是重载构造函数,以便我们可以像这样提供正确的环境连接字符串:

    Partial Class SampleDataContext
        Sub New()
            MyBase.New(App.Site.ConnectionString)
        End Sub
    End Class
    

    【讨论】:

      【解决方案2】:

      这是一个解决方案:在源代码控制下将该文件存储为“Web.Config.in”。

      在每台服务器(开发、测试、暂存、生产)上,将Web.Config.in 复制到Web.Config,并仔细编辑AppEnv 值。

      在从一个环境到下一个环境的每次后续推送中,排除 Web.Config 文件。也就是说,不要覆盖该特定文件。例如,编写运行 rsync --exclude WebConfig 的部署脚本。

      【讨论】:

        【解决方案3】:

        如果网站未处于生产模式,我会在页面顶部以粗体红色字母显示该网站处于何种模式。

        我还有一个诊断页面,其中列出了正在运行的服务器以及它连接到的数据库。

        您还可以在每个数据库中放置一个查找表,以确保您连接到正确的标志。 (在 Test DB 中将其标记为 1 并检查 Application_Start 值是否匹配)

        【讨论】:

          【解决方案4】:

          每当有一个过程总是需要不止一个步骤时,我知道我至少有一半的时间会搞砸它。因此,我喜欢 MSBuild。

          MSBuild 的盒子中有很多有用的任务,例如AspNetCompiler task,这似乎是一步编译/发布操作。

          还有几个项目为各种目的聚合了大量“自定义”MSBuild 任务。 MSBuild Community Tasks Project 有一个 XmlMassUpdate 任务,可用于对 xml 格式的文件进行多项更改。换句话说,非常适合更新 web.config 文件。

          我找到了一个将 XmlMassUpdate 任务与 Web 部署项目 here 结合使用的示例。

          【讨论】:

            【解决方案5】:

            一个不断出现的永恒问题!我猜几乎所有认真的 ASP.NET 开发人员都曾在某些方面对此表示反对。

            对于 ASP.NET 4.0,有一些帮助 - 改进的 Web 部署选项将提供一个称为“web.config 转换”的功能。

            查看此主题的 Channel 9 video - 尚未找到任何体面的书面参考资料...

            马克

            【讨论】:

              【解决方案6】:

              我将在测试和生产中不同的所有密钥放入一个全新的 .config 文件中。我将测试设置放在测试上,将生产设置放在生产上,并且从不将此文件从测试复制到生产。然后,在您的常规 web.config 中,您可以像这样指定这个新的 .config 文件:

              <appSettings file="ExternalWeb.config>
                  .... common keys go here
              </appSettings>
              

              在测试服务器上,“external.config”将包含特定于该服务器的值,在生产中,它将具有 prod 值。这允许您在两台服务器之间复制整个 web.config,而无需手动更改文件。

              【讨论】:

                【解决方案7】:

                我认为将连接字符串存储在 web.config 中是不好的做法,而是在我的网站之外的一个常见的已知位置(如

                )创建一个单独的配置文件

                C:\xxxx\config.xml

                然后我将所有与机器相关的设置存储在那里。因此,在我的实时服务器上,我有我的实时设置,在测试数据库的测试服务器连接字符串和我的开发机器上,我有我的本地设置。然后,这些设置也可以在该服务器上的所有网站和 .net 应用程序中继续使用。当数据库发生变化时,只有一个地方需要更新。

                完美!

                【讨论】:

                  【解决方案8】:

                  将您的 Web.Config 设置为“只读”,因此在发布到这些服务器时不会被覆盖。

                  权衡是您必须手动维护每台服务器上的 web.config,并且您的发布将声称失败,因为它无法覆盖远程服务器上的 web.config;但恕我直言,这比每次上传时都修改配置更可取

                  【讨论】:

                    猜你喜欢
                    • 1970-01-01
                    • 2012-09-27
                    • 2013-04-11
                    • 1970-01-01
                    • 2020-03-30
                    • 1970-01-01
                    • 2014-07-16
                    • 1970-01-01
                    • 1970-01-01
                    相关资源
                    最近更新 更多