tags:

views:

369

answers:

5

I'm storing some value in an asp.net session on the first page. On the next page, this session value is being read. However if multiple tabs are opened and there are multiple page 1->page 2 navigation going on, the value stored in session gets mixed up since the session is shared between the browser tabs.

I'm wondering what are the options around this :

  1. Query String: Passing value between the pages using query string, I don't want to take this approach since there can be multiple anchor tags on page 1 linking to page 2 and I can not rewrite the URLs of each tag since they are dynamic.

  2. Cookies??? In-memory cookies are shared across browser tabs too, same as the session cookie, rite ?

Any other option?

PS: Page 1 to page 2 is not a form submit.

+1  A: 

It sounds like you want each page to keep it's own values, separate from each other.

  • If you can use Post (eg: you can keep from manipulating the URL on the client), hidden input tags can do the job well. You'll certainly want to encapsulate this, since doing it manually would be a huge pain. Otherwise:
  • If you're using ViewState, you could use that. Otherwise:
  • You get the values or an ID (which would be better. see below) into the URL. A last resort, because the human will be able to screw this up. Or they might bookmark it and cause confusion when they come back a week later.

If the values cannot be sent to the client, then you need to pass a "PageSessionID" or something down to the client. This ID is either a guid (better if security is an issue) or some value you get in a way to guarantee uniqueness. Send to the client in a hidden input tag or in ViewState (or url if no other choice), and store related data on the server based on that ID.

Cookies won't work for you purposes.

Patrick Karcher
Page 1 to page 2 is not a form submit - the user can jump to page 2 directly by typing in the url of page 2 in the address bar.
ace
I think the only way is to put a PageSessionID (see above) into the URL, and hope the human doesn't mess it up. If she does, then she'll have to begin that page's "session" over.
Patrick Karcher
+2  A: 

Could you use ViewState instead of SessionState?

Update:

Or perhaps a combination of ViewState and SessionState.

Here's an example sequence:

  • On Page 1, user chooses "Red". Value is stored in SessionState.
  • User navigates to Page 2. Value is read from SessionState and stored in ViewState of Page 2.
  • User opens a second Page 1 in a new tab and chooses "Blue". Value is stored in SessionState, so "Red" is replaced with "Blue".
  • User navigates to Page 2. Again, value is read from SessionState and stored in ViewState.
  • User returns to original Page 2 (the one on the first tab) and performs a PostBack. Value is read from ViewState. Value is still "Red".
  • User returns to second Page 2 (the one of the second tab) and performs a PostBack. Value is read from ViewState. Value is still "Blue".

In other words, use SessionState for transitions between pages. Use ViewState for PostBacks of same page.

Does that help?

DanM
Page 1 to page 2 is not a form submit - the user can jump to page 2 directly by typing in the url of page 2 in the address bar.
ace
@ace: Sometimes you can use a combination of SessionState and ViewState to handle all contingencies, but I'm not sure of the details of what you're trying to accomplish.
DanM
@ace: I updated my answer. Hopefully, that explains better what I'm thinking.
DanM
thanks Dan, however on page 2 there is no postback, page 2 simply renders results based on session value.
ace
@ace, okay, so what circumstances cause the value to be wrong?
DanM
+2  A: 
  1. Give each page a guid. Store the guid in a hidden field.
  2. Use this guid as the session key that stores a struct with all the variables etc. for that page.
  3. You can now pull information for a specific page "rendering" and passes data to the session struct to the new "rendering" in the code-behind.

This is similar to what ViewState does automatically.

EDIT

Comment response

I don't think that's possible as you described it.

In your question you mentioned page 1 to 2 navigation. If the user types in the URL for page 2 in the browser then how do you tie that current page 2 rendering with the previous page 1?

You need something to do so, unless the code-behind can search a list of incomplete workflows that have stopped at page 1 and uses that as the previous guid value for the new page 2 rendering.

Comment response 2

You can find all the links on the page and modify those but it hints that something is wrong ( in my opinion ). But...

http://www.extremeexperts.com/Net/Articles/LoopingthroughControls.aspx

Gives you a simple way of processing all controls on the page. You can test to see if the control is a hyperlink easily. Not that all links will need that runat="server" parameter set for this to work.

kervin
Page 1 to page 2 is not a form submit - the user can jump to page 2 directly by typing in the url of page 2 in the address bar.
ace
@ace: If the session variable doesn't exist, assume you navigated directly to page 2 and process it however you normally would.
Greg
Updated my answer. The problem with direct URL access is that you have multiple renderings of the same page in the same session. There is no way with direct access to attach the new page 2 with an older *unsubmitted* page 1 *authoritatively*. You can keep a list of incomplete workflows and guess though.
kervin
@Greg: That is also a good strategy. I was assuming that he would try to *salvage* the direct access somehow and *connect* it to an existing incomplete workflow. But I agree, the best thing may be to just prohibit direct access to page 2.
kervin
@ace. Update my answer, see the link.
kervin
A: 

Another way to do it is to use a Server.Transfer or a CrossPagePostBack. Then you can access all of the previous page's variables using Page.PreviousPage. If Page.PreviousPage is null, you know the user came to the page directly and you should process page 2 with that in mind.

I can't really recommend it though, because with Server.Transfer you don't update the URL in the browser and CrossPagePostBack makes everything a postback, which can lead to problems like the back button not working "normally".

Greg
A: 

I figured out a solution :

  1. Using Javascript assign a unique id like a guid to the browser window / tab by assigning the guid value to the window.name property. window.name property is unique to each browser window/tab and won't be shared across the windows.

  2. Using the guid as the key, read and write data to your ASP.NET session via a webservice. Since javascript does not have access to asp.net session, you will need to use a webservice and call it's method through javascript.

The data can be transfered between javascript and webservice via JSON.

Cheers!

ace