每个浏览器窗口或选项卡创建唯一会话变量

时间:2012-12-03 14:56:46

标签: asp.net vb.net global-variables webforms

创建基于.Net Session的变量时遇到轻微问题。

我知道我可以使用Session扩展程序并完成它,但我在单个桌面上查找多个浏览器(窗口或标签,IE)的情况。

目前,我在Web-App中声明了一个模块,当我打开两个单独的IE浏览器时,他们最初加载自定义PageRouting设计,正如预期的那样,但是一旦我用两个窗口进入下一步open,最后一个要打开的是用于其余应用程序的设计/逻辑。

Module.vb

Namespace classes
    Module Globals
        Public Brand As Brand
        Public Test As Test
        Public Results As Results
        Public Primary As String = "#FFFFFF"
        Public Secondary As String = "#FFFFFF"
        Public Terteruary As String = "#FFFFFF"

    End Module
End Namespace

在代码中,我将对象引用为Globals.BrandGlobals.Primary,但在任何一种情况下,同一桌面可以打开具有不同PageRouting地址的同一网站的情况,它假定最后打开浏览器窗口。

Brand&amp; Test变量在Session_Start的{​​{1}}事件中初始化。使用Globals.asax注释时,对这些对象的所有引用都是显式引用。 Globals.<variable>在网站执行期间首次使用时初始化。

问题

  1. 如何确保每个浏览器窗口都加载了自己独特的会话缓存以供网站使用?
  2. 更新 - 2012-12-03

    这样的设计怎么样?

    Results

    在主/内容页面级别实例化Class1?

    更新#2 - 2012-12-03

    修改了模块,让我知道这是否是一个可行的会话控制设置

    Public Class Class1
      private _sess as HTTPSessionState
      ...
      private readonly property Session as HttpSessionState
        Get
          if _sess is nothing then
            _sess = httpcontext.current.session
          end if
          return _sess
        End Get
      end property
      ...
      public property Primary as string
        Get
          return cstr(session("primary"))
        end get
        Set(value as string)
          session("primary") = value
        end set
      end property
      ...
    end class
    

    2012-12-10最终表格:

    Module.vb

    Module Globals
        'Dictionary Collection of type (SessionID:String, Quiz:classes.Quiz)
        Public Quizzes As Dictionary(Of String, classes.Quiz)
    
        Public Property Quiz(session As String) As Quiz
            Get
                Return Quizzes(session)
            End Get
            Set(value As Quiz)
                Quizzes(session) = value
            End Set
        End Property
    
    End Module
    

    的Web.config

    Module Globals
        'Get/Set a Quiz object into the SessionState.
        Public Property Quiz(sess As HttpSessionState) As Quiz
            Get
                Return CType(sess("quiz"), Quiz)
            End Get
            Set(value As Quiz)
                sess("quiz") = value
            End Set
        End Property
    
    End Module
    

    上述表单使用Property的索引器方面按预期工作。没有任何用户实例问题。另一方面,为了使其有效工作,用户必须关闭所有浏览器窗口并打开一个新窗口以清除会话

1 个答案:

答案 0 :(得分:1)

您遇到的问题是网络编程中非常常见的问题。模块的成员是静态 - 这意味着应用程序的整个AppDomain中都有一个实例。访问这些用户的每个用户都将获得相同的对象。

您可以使用您编写的getter属性来替换模块中的公共变量,以访问字典中的用户特定字段(编写此getter代码时请记住线程安全性)。

更简单的解决方案是使用Session。会话值存储在服务器端,并且是特定于用户的。获得客户端的唯一方法是会话密钥,如果您使用.Net身份验证,则很可能已经发送。

检查此来源:

How to get a public variable (in a Module) to NOT share value between users