Having a slight problem with creating a .Net Session based variable.
I know i can just use the Session extension and be done with it but i am looking more for a Multiple Browser (either Window or Tab, for IE) situation on a single desktop.
Currently, i have a Module declared in the Web-App and when i open up two individual Windows of IE they initially load the custom PageRouting design, as expected but once i go to the next step with both windows open, the last one to be opened is the design/logic used for the rest of the application.
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
In code, i reference the objects as Globals.Brand or Globals.Primary but in either case a situation where the same desktop could open up the same website with different PageRouting address, it assumes the last opened browser window.
The Brand & Test variables are initialized in the Session_Start event in Globals.asax. All references to these objects are explicit references using Globals.<variable> annotation when used. Results is initialized on first use during the execution of the website.
Question
- How do i make sure that each individual browser window is loaded with its own unique session cache for use with the site?
Updated – 2012-12-03
What about a design like this?
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
With Class1 being instantiated at the Master/Content page level?
Update #2 – 2012-12-03
Modified the module, let me know if this is a viable session control setup
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
Final Form 2012-12-10:
Module.vb
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
Web.config
<system.web>
...
<sessionState mode="InProc" cookieless="UseCookies"
regenerateExpiredSessionId="true" timeout="20"
cookieName="ASPNET_Quiz" />
...
</system.web>
The above form worked as expected utilizing the indexer aspect of a Property. Havent had any user instance problems. One side note, is that in order for this to work effectively the user must close all browser windows and open a new window for the session to clear out
The problem you are coming across is a very common one in web programming. A Module’s members are static – meaning there is one instance of them across the entire AppDomain of your application. Every user that accesses these will get the same object.
You could possibly replace the public variable in your module with a property whose getter you write to access a user-specific field in a dictionary (please remember thread safety when writing this getter code).
The much easier solution would be to use the Session. Session values are stored server-side and are user specific. The only thing that get’s sent client side is the session key, and if you are using .Net authentication, this is likely already getting sent.
Check this source:
How to get a public variable (in a Module) to NOT share value between users