1

是的,有很多关于这个问题的帖子,我已经尝试了其中许多建议,但没有一个有效。请不要告诉我这已经被问过了。

我被要求更新与数据库交互的内部网站。它最初是在 VS 2003 中创建的,我们无法再访问它,因此需要将项目升级到 VS 2012。我还有最后一个问题要解决。该站点的原始设计者使用以下代码块来设置环境,以便可以连接到正确的数据库:

Sub Application_Start(ByVal sender As Object, ByVal e As EventArgs)
    ' Fires when the application is started
    Select Case LCase(HttpContext.Current.Request.ServerVariables("SERVER_NAME"))
        Case "localhost", "development_domain"
            DB_Environment = "DEVELOPMENT"

        Case "staging_ip", "staging_domain"
            DB_Environment = "STAGING"

        Case "external_prod_domain", "external_prod_ip", "internal_prod_domain"
            DB_Environment = "PRODUCTION"
    End Select
End Sub

各种环境正在升级到 IIS 7.5。这意味着该站点现在在开发环境中崩溃,因为 IIS 7 及更高版本不再支持 HttpContext.Current。

许多建议的修复都谈到了将功能移至 Application_BeginRequest 方法。我对每次发出请求时都触发它并不感兴趣,因为它是不必要的,而且它似乎会导致应用程序出现问题。

我的部分问题是我无法尝试一些建议,因为它们是用 C# 编码的(我非常熟悉),而应用程序是用 VB 编码的(我不太熟悉)。

谁能指出我如何在不使用 HttpContext.Current 方法的情况下检索要保存在 DB_Environment 变量中的域的正确方向?

4

4 回答 4

1
if (System.Environment.MachineName == "xxx")

虽然,这样做的首选方法是拥有一个基本的 web.config 文件,并为您的不同环境创建 XLST 转换,这些转换会根据您发布项目的方式更改值。例如,我们有 web.config、web.release.config、web.debug.config 和 web.staging.config。对于每个环境,我们有不同的缓存、输出缓存、调试属性、连接字符串、电子邮件服务器设置等值,并且它们都在发布时被换掉。

Sub Application_Start(ByVal sender As Object, ByVal e As EventArgs)
    ' Fires when the application is started
    Select Case LCase(System.Environment.MachineName)
        Case "localhost", "development_domain"
            DB_Environment = "DEVELOPMENT"

        Case "staging_ip", "staging_domain"
            DB_Environment = "STAGING"

        Case "external_prod_domain", "external_prod_ip", "internal_prod_domain"
            DB_Environment = "PRODUCTION"
    End Select
End Sub

您将需要找出各种机器的名称而不是请求的 URL 才能使其正常工作,但这可能是升级旧代码的最快修复方法。

于 2013-06-13T22:05:45.047 回答
0

将您的代码移动到抽象中。有那个代码查询HttpContext.Current.Application["DbEncironment"],如果它不存在就存储它并返回。这样它会在第一次访问时被设置,并在所有其他时间读取。

Public Class DbEnvironment

    Public Function Shared GetEnvironment() As String

        Dim e = HttpContext.Current.Application["DbEnvironment"]

        If (e = Nothing) Then
            Select Case LCase(HttpContext.Current.Request.ServerVariables("SERVER_NAME"))

                Case "localhost", "development_domain"
                    e = "DEVELOPMENT"

                Case "staging_ip", "staging_domain"
                    e = "STAGING"

                Case "external_prod_domain", "external_prod_ip", "internal_prod_domain"
                    e = "PRODUCTION"
           End Select

           HttpContext.Current.Application["DbEnvironment"] = e
        End If

        Return e

    End Function

End Class

现在您需要访问您的环境调用

DbEnvironment.GetEnvironment()

它会一直有效。如果这更符合您的风格,您也可以将其设为属性。

于 2013-06-13T22:06:56.050 回答
0

DB_Environment 参数在应用程序中的使用率如何?如果它不是太广泛,我建议更改系统以利用web.config transforms。通过这样做,您基本上可以将您的数据库连接字符串/应用程序设置变量替换为对其“正常”名称(ConnectionSting、MagicPath 等)的调用,然后您可以通过 web.debug.config、web 维护这些值.release.config 等文件。

这样做的好处是您可以将您的应用程序视为一个应用程序,而不是一个“环境 X 应用程序”,一个错误的配置(或服务器的命名)可能会搞砸事情并且真的很难维护。

如果您真的需要“破解”,您可以在 web.config 中添加一个名为“Environment”的 AppSettings 键,利用转换,然后简单地从那里读取上面列出的方法(在 1 行或 2 行中完成)。这样,您仍然可以维护您的环境设置,而无需花哨的编码。

于 2013-06-13T22:45:42.637 回答
0

首先要澄清一点:HttpContext.Current在 IIS 7 中仍然可用,只是不可用,Application_Start因为不一定有来自外部用户的传入请求导致事件触发。

现在,问题:

您没有显示如何DB_Environment定义,但我怀疑它只是一个标准属性,即

Public Property DB_Environment As String

如果是这种情况,您可以通过将 DB_Environment 更改为具有支持成员变量的只读属性来轻松无缝地解决您的问题,然后如果尚未设置支持存储属性,则执行初始配置。在这个设计中,它只会在需要的时候被初始化,并且应该只在外部用户发出请求时才需要,从而保证了HttpContext。

这是建议的设计:

Private m_DB_Environment As String = Nothing
Public ReadOnly Property DB_Environment As String
   Get
       ' If we haven't retrieved the setting yet and there is a current context, 
       ' retrieve the appropriate setting
       If m_DB_Environment Is Nothing AndAlso HttpContext.Current IsNot Nothing Then
          Select Case LCase(HttpContext.Current.Request.ServerVariables("SERVER_NAME"))
              Case "localhost", "development_domain"
                  m_DB_Environment = "DEVELOPMENT"

              Case "staging_ip", "staging_domain"
                  m_DB_Environment = "STAGING"

              Case "external_prod_domain", "external_prod_ip", "internal_prod_domain"
                  m_DB_Environment = "PRODUCTION"
          End Select
       End If

       Return m_DB_Environment
   End Get
End Property
于 2013-06-13T22:51:08.297 回答