31

I'd like to maintain a session state per browser tab.

Is this easy (or even possible) to do in ASP.NET?

Example: A user hits Ctrl-T in firefox 5 times and visits the site in each tab. I'd like each tab to have its own session state on the server

Brian Webster
  • 30,033
  • 48
  • 152
  • 225

3 Answers3

25

To facilitate multi-tab session states for one user without cluttering up the URL, do the following.

In your form load function, include:

If Not IsPostback Then
  'Generate a new PageiD'
  ViewState("_PageID") = (New Random()).Next().ToString()
End If

When you save something to your Session State, include the PageID:

Session(ViewState("_PageID").ToString() & "CheckBoxes") = D

Notes:

  • As with session ID's in general, you cannot trust that malicious viewers will not change the SessionID / PageID. This is only a valid solution for an environment where all users can be trusted. Fortunately, ViewState does offer more protection than using a hidden input field.
  • You will not have access to the PageID until the ViewState is restored upon PostBack. Therefore, you will not have access to the PageID in the page_init() handler.
Brian Webster
  • 30,033
  • 48
  • 152
  • 225
  • 1
    For devs using ASP.NET web forms, you can get a degree of protection from malicious users tampering with the PageID by using ViewState rather than a native HTML hidden field. By default ViewState is hashed with the server machine key and ASP.NET throws an exception if the posted data is not a valid hash. If the Session ID is tampered with this would typically cause a new session to be created when the next data is written to it as the existing session would be invalid - attempts to recall existing data would result in null reference exceptions. Could check for these or IsNewSession property. – pwdst Feb 13 '13 at 23:55
  • @pwdst Excellent point, I will adjust the solution to match! Thank you – Brian Webster Feb 14 '13 at 00:03
  • 2
    This is an excellent solution to a question that I had to deal with this week for data integrity at work. Users were opening second tabs and then returning to update the record held in the first tab, with of course session data associated with the second record. I used a variant of this solution to prevent incorrect updates on the wrong record. – pwdst Feb 14 '13 at 00:20
  • Maybe could be better (or additionally) using hiddenfields, in order to make javascript access simplier (for example if you have to send values to a WebMethod, and so on), isn't it? – Morcilla de Arroz Oct 18 '13 at 10:16
  • the name 'ViewState' does not exists in current context. is the error showing @GeorgeWBush – Dinav Ahire Jul 16 '15 at 04:11
  • How this applies to ASP.NET MVC? – usefulBee Aug 25 '16 at 16:57
  • MVC does not have ViewState so this answer would not apply. However, using something that functions in similar fashion to a ViewState should work. The following question may point you in the right direction: http://stackoverflow.com/questions/23623229/what-is-the-equivalent-of-viewstate-in-asp-net-mvc – Brian Webster Aug 25 '16 at 18:25
17
<configuration>
  <system.web>
    <sessionState cookieless="true"
      regenerateExpiredSessionId="true" />
  </system.web>
</configuration>

http://msdn.microsoft.com/en-us/library/ms178581.aspx

in this case each tab will get unique ID and it will looks like it is another visitor.

zerkms
  • 249,484
  • 69
  • 436
  • 539
  • cookieless="true" is really needed? – ErTR Jan 26 '15 at 19:20
  • @Ertürk Öztürk: the question sounds "I'd like to maintain a session state per browser tab.". All browser instances share the same cookies. – zerkms Jan 26 '15 at 20:29
  • @zerkms I'm okay with cookieless but I need to set it dynamically on page load. Unfortunately it's read-only. – ErTR Jan 26 '15 at 20:35
  • 1
    @ErtürkÖztürk my advice would be to ask a separate question if you have one. – zerkms Jan 26 '15 at 20:37
  • 4
    Note: This will not work if a user copies the URL from one tab and pastes it into another. Since the session is based on a key within the URL, both tabs will now be using the same session. – MyNameIsKo Oct 09 '15 at 17:20
  • Setting cookieless="true" is not a good suggestion. Since you will now clutter your urls with additional data. – Robert Smith Aug 28 '23 at 18:37
  • @RobertSmith it's a solution that requires no code changes. Whether it's "good" or not so - is to decide not by me (or you), but by a person who makes a decision for a particular project. – zerkms Aug 28 '23 at 21:52
1

Using Brian Webster's answer I found a problem with XMLHttpRequests. It turned out, XMLHttpRequests did not set the IsPostback flag to true and therefore the request looked like a new request and one would end up having a new session state for that request. To solve that problem I also checked the value of the ViewState("_PageID")

so that my code looks like this in C#:

protected dynamic sessionVar; //a copy of the session variable

protected void Page_Load(object sender, EventArgs e)
{
    if (!IsPostBack && ViewState["_PageID"] == null)
    {
        ViewState["_PageID"] = (new Random()).Next().ToString();
        Session[ViewState["_PageID"] + "sessionVar"] = initSessionVar(); //this function should initialize the session variable
    }
    sessionVar = Session[ViewState["_PageID"] + "sessionVar"];
    //...
}
casenonsensitive
  • 955
  • 2
  • 9
  • 18