I have an application that is used by many people from many different workstations. In this app, there are various user details being stored in the session when the user logs in. These details are first stored within the global.asax file:
Sub Begin(ByVal sender As Object, ByVal e As EventArgs) Handles Me.AcquireRequestState
(various code that gets user details)
HttpContext.Current.Session("ID") = UserID
End Sub
I created a class file to more easily reference the session variables, call the Portal class. It looks like this (Portal.vb):
Public Class Portal
Public Class User
Public Shared ID As Integer = HttpContext.Current.Session("ID")
End Class
End Class
In my application, on say, the default page (Default.aspx), I am referencing the user ID to do various things:
Sub Page_Load() Handles Me.Load
Dim ID As Integer = Portal.User.ID
(Do stuff with the ID)
End Sub
The problem that is happening is that, when someone logs in the first time for the day, the ID seen in the Default.aspx code is that of the first user. But when the next person logs in, on a completely different work station, the ID seen in the Default.aspx code is still that of the first user. I have confirmed that there is no issue with what IDs are being assigned to users. I know for a fact that the global.asax file is putting the correct IDs in the session. I have confirmed this by checking session("ID").
For some reason, when accessing the session in the Class file (Portal.vb), the session being referenced is always that of the first person. Does anyone know how this is possible?
CodePudding user response:
Public Shared ID As Integer = HttpContext.Current.Session("ID")
This initializes the ID
variable, once, with the value of the current session ID. Your code never updates this value in the User
class. So you always get the session id of the first user.
To fix it, make it a method or a property that queries and returns the current session id.
CodePudding user response:
I was able to figure it out, for the most part.
TLDR (Too Long, Didn’t Read) answer: I needed to have the class properties utilize a Getter in a way I wasn’t familiar with.
Long Answer:
So in the Portal.vb class file, I first had class ‘fields’:
Public Shared ReadOnly UserID as Integer = HttpContext.Current.Session(“UserID”)
I chose fields over properties because I wanted these class values to be un-editable (ReadOnly), and class properties can’t be made un-editable (or so I thought). In other words, the following code is not allowed:
Public Shared Const Property UserID as Integer = HttpContext.Current.Session(“UserID”)
The compiler doesn’t allow you to make the property constant (Const), nor does it allow read-only (ReadOnly), saying it doesn’t allow read-only auto-implementations of properties. I thought that, perhaps, there was an issue between class fields and class properties so I tried converting all the fields to properties, leaving out the “Const” bit, just to see if it would work:
Public Shared Property UserID As Integer = HttpContext.Current.Session(“UserID”)
It had no effect.
"Omajid" suggested, above, that the class value was being set once and never being updated. This would, in a way, explain the behavior. I didn’t understand exactly how that would be as I thought that any time the class value is referenced, the code associated with it would execute, pulling the value from the session each time. So then I thought that perhaps there is something different with how a Getter/Setter would work. So I tried setting up the class properties with a Getter/Setter as I understood how to do it:
Private _userid As Integer = HttpContext.Current.Session(“UserID”)
Public Property UserID() As Integer
Get
Return _userid
End Get
Set(value As Integer)
_userid = value
End Set
End Property
This again had no effect. And, Ironically enough, Visual Studio itself suggested that I should use an ‘auto property’, which simplified the whole code block to:
Public Property UserID() As Integer = HttpContext.Current.Session("UserID")
This had no effect. This is why I don’t really ever setup Getter/Setters; they don’t really seem necessary for the most part, since in VB there is this short-hand way.
A co-worker of mine sent me this article:
How to access session variables from any class in ASP.NET?
It had an example in it that had a different arrangement of a Getter, which made me think I could do something similar. So I setup the class property like this:
Public Shared ReadOnly Property UserID As Boolean
Get
Return HttpContext.Current.Session("UserID")
End Get
End Property
Bingo. This did the trick. It achieved both things I wanted: It updated the value for each user, and I was allowed to make the property read-only (ReadOnly) because there was no Set method.
So what I learned here is that class fields/properties are set once upon construction and not set again. And in order to have a class property update each time it is referenced, it needs to be done through a Get method.
Since the real reason behind this question is that I needed to get the user's details to update to their own and not reference someone else's when calling the Portal class, this is the solution. That said, one bit that still hasn’t been answered: How is it that class properties that are set in one user’s session are accessible by another user in another session? This, to me, seems like a huge security risk. But perhaps that’s only because I don’t understand the process.