Search code examples
asp.netvb.netvariablesmoduleuserid

How to store User ID of Logged in User in ASP.net VB.net


I am trying to store the UserId or/and UserName of the user. This is used to record user ID against any changes they make to data, insert, updates and deletes etc.

I have created a module and in that module added a Public variable vUserID. Here Lei the problem.

User A logs in and his id vUserID = 'A'. Another user (User B), the other side of the world logs in User 'B' and that vUserID then = 'B'. So now anything User A does gets recorded as he is User 'B', or that is how I understand it, as a Public variable will be accessible from anyone who logs in.

I understand the problem, or I think I do, please correct me if not, but what I am struggling with is the solution. I have tried to use a Protected and Protected Friend but these do not seem to be accessible throughout the program(website) when a user is logged in.

For completeness I get the User details by the following code which seems to work fine:

    Dim mu As System.Web.Security.MembershipUser = System.Web.Security.Membership.GetUser()
    Module1.vUserID = mu.ProviderUserKey.ToString()

Solution

  • Well, the issue is that you have ONE web server.

    And the web server (for the most part) will process ONE web page at a time.

    So, when a user clicks a button on a web page, before they click on a button, the web page is sitting on their desktop computer. it is NOT on the web server.

    (and more important, all the code variables (code behind) are GONE! They do not exist yet!).

    So, think of a web server as ONE computer. And say 5 users are going to use YOUR computer to edit a word document.

    The first user sits down, opens word document, types in some text, and then closes word!

    The next user sits down, opens word document, types in some text, and then closes word!

    Remember, you don't have a computer for each user, but have ONE computer - the web server, and it has to "some how" service all users.

    So, all the web server can do, is "process" a web page, one that is sitting on each end users computer (running the browser).

    So, you have this:

    enter image description here

    And you do NOT have this:

    enter image description here

    In other words, the web page is NOT sitting "loaded" on the web server. it is out of scope.

    Think of when you call a sub, use some variables in that sub, when you return/exit from that sub, ALL VARIABLES are gone!! (out of scope).

    You MUST think of web pages like that sub - when you exit, they are gone, don't exist anymore.

    So, you don't have this:

    enter image description here

    the web page is NOT in memory on the server, it is NOT loaded.

    Thus, you don't have this either:

    enter image description here

    So, with above in mind, lets create a super simple web page to show this:

    We will have a simple string variable, called MyZooVar.

    We will put a button and label on the web page to set this varible.

    we will then put another button on the form to show the value of the variable.

    So, this:

            <asp:Button ID="cmdSetZoo" runat="server" Text="set varable to zoo" />
            <asp:Label ID="Label1" runat="server" Text=""></asp:Label>
    
            <br />
            <br />
            <asp:Button ID="cmdGetZoo" runat="server" Text="get value of var zoo" />
            <asp:Label ID="Label2" runat="server" Text="Label"></asp:Label>
    

    and the code behind is this:

    Public MyZooVar As String
    
    
    Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
    
    End Sub
    
    Protected Sub cmdSetZoo_Click(sender As Object, e As EventArgs) Handles cmdSetZoo.Click
    
        ' set value to variable MyZoovar
    
        MyZooVar = "Hello how are you!"
    
        Label1.Text = "Value of MyZooVar = " & MyZooVar
    
    End Sub
    
    Protected Sub cmdGetZoo_Click(sender As Object, e As EventArgs) Handles cmdGetZoo.Click
    
        ' get/show value of zoo var
    
        Label2.Text = "Value of MyZoovar = " & MyZooVar
    
    End Sub
    

    Note VERY close in above, the MyZooVar - we defined it at the top of module, so all buttons and code can use that MyZooVar.

    So, we will click the first button, this code:

        ' set value to variable MyZoovar
    
        MyZooVar = "Hello how are you!"
    
        Label1.Text = "Value of MyZooVar = " & MyZooVar
    

    And then we have a 2nd button, and this code:

    Protected Sub cmdGetZoo_Click(sender As Object, e As EventArgs) Handles cmdGetZoo.Click
    
        ' get/show value of zoo var
    
        Label2.Text = "Value of MyZoovar = " & MyZooVar
    
    End Sub
    

    what will happen when we run?

    We see this:

    enter image description here

    So, in above, this is what occured:

    we START with this:

    enter image description here

    You click a button, YOUR web page (not the 20 other users) is sent to the web server.

    the page travels up to server,

    You now have this:

    enter image description here

    Now and THEN your code behind runs. When done, your code behind MUST finish, else the page stays stuck up on the server side. When done, the whole page page makes the trip down back to the browser. And THEN the page is re-displayed and THEN any js code can run.

    So when done? Your page makes the trip back down to the browser like this:

    enter image description here

    Note on the server side? Your web code (and MORE important variables) and EVERYTHING is disposed.

    We now have this again:

    enter image description here

    Note HOW THE WEB PAGE IS NOT on the web server!!!!

    the web server is waiting now for ANY post-back of a web page from ANY user, not just you the one user!!!!

    So, now that I clicked the button to set the variable MyZooVar?

    What happens if I click on the 2nd button, this code:

    Protected Sub cmdGetZoo_Click(sender As Object, e As EventArgs) Handles cmdGetZoo.Click
    
        ' get/show value of zoo var
    
        Label2.Text = "Value of MyZoovar = " & MyZooVar
    
    End Sub
    

    Well, the whole process starts over again!!!

    We will find that the variable MyZooVar is gone, out of scope, and does not have our value!!!

    So, the "term" for the above is what we call "state-less".

    In other words, your code behind can't assume, hope, pray that the varibles in the web page will persit.

    Now you can hope/pray/try to put some variables in a global code module, but as you found out, they are shared amoung all users. But WORSE, the web server will often say, hey, I don't need that memory, I'm just sitting here waiting for someone to click a button and send me THEIR web page.

    As a result, not only will you find those so called global variables in that public code module shared between all users, you find that they OFTEN will not even stay in memory all that long. So, your code "sort of works" to try and use some global variables, but you find they OFTEN go out of scope, and will not even stay in memory.

    So, web based software is VERY different then desktop software.

    One big difference is that for desktop software, each user, each workstation has their OWN copy of the code.

    With a web server, you have ONE web server, ONE computer, and it sole job is to process incoming web pages (that occurs due to a page post-back).

    the process of a simple button click, whole web page travel up to web server, page is processed, and then whole page is send back to user? We call this a round trip.

    So, you really do not have global variables in a web based application. You can try to use some, but as noted, they will be the same for all users, but MUCH worse, is they tend to go out of scope, and can be disposed (go away) at any old time - you have no control over this, and thus you simple can't adopt global variables in a web based system - they are "off limits", and the above so called round tripping, and that you have ONE computer and ONE web site that somehow has to service many users - not just you!!

    So, in your case?

    Why do you need to store/save the user ID in some variable?

    You "already" are able to get the user id with the code you shared:

    You can use this:

    dim UserID    as integer
    UserID = Membership.GetUser().ProviderUserKey
    

    So, since you can get the "user" id any old time with above ProviderUserKey, then no need exists to try and "save" the user id into some global variable, but as you found out, you can't rely, or even design your software based around a concept of global variables.

    However, you can if you wish place values into what we call "session".

    Session is in effect global to the ONE user, and it DOES persist between those so called round trips.

    so, you could do this:

     Session("MyUserID") = Membership.GetUser().ProviderUserKey
    

    And then in code, any time, use

      Session("MyUserID") to get the user "id"
    

    But, since you have ProviderUserKey, then even session() should not be required here.