views:

531

answers:

5

I want to ensure a user isn't editing the same form data in two different browser tabs or windows (of the same web browser instance). The intention is to stop the user from stupidly overwriting their own data as they continue through a very long form process. On the server, ongoing data input through the screens is collected into the Session.

Assume for any browser, all tabs and windows run in the same instance of it (i.e. not each in a separate process). Obviously the browser tabs and windows share the same cookies in this scenario so cookie modification seems out of the question for viable solutions. This is also the reason they are sharing the same session state.

Considering that the form is already created and this is one of the final touches, how can I use ASP.NET, hopefully easily, to oversee this "feature"?

A: 

During the rendering of your specified page, generate a GUID and save in session. Write a generic handler, that keep track that for a specified page, no two GUID exists.

Following data structure will help.

class MultipleOpenedPage{
    string guid;
    string pageURL;
    DateTime timeStamp;
    bool IsMultiplePageOpened(List<MultipleOpenedPage> list)
    {
    ///logic 
    }
}
Adeel
How do you determine that the request is a new instance and not just the user hitting F5?
CodingInsomnia
In case of GET request, Pressing F5 behaviour is same as opening new instance as in both cases, a new http GET request so there is no easy way to detect. we can detect through ajax request when page unloads but those ajax request sometimes fail.In case of POST refresh, it can be detected by placing a GUID in viewstate and on postback match viewstate GUID with the session value.
Adeel
+1  A: 

You could try something like this:

Store an integer as Session["LastRequest"]. Put this into a hidden field on the page. For every request, you add one to the integer.

On postback, make sure that no other request has been made by checking that Request.Form["LastRequest"] is equal to Session["LastRequest"].

If you need to check for multiple instances before the postback happens you should be able to do so using AJAX calls.

CodingInsomnia
A: 

Because of the stateless nature of the web, I don't believe there is a reliable way to differentiate between two browser windows. However, you can store a flag in Session that a given long running process is in progress. In this way, you don't care if they try to rerun the process from the same browser window or multiple browser windows. The trick is going to be handling situations where the process fails and doesn't get a chance to reset the flag so that the process can be run again.

Thomas
If I understand the OP correctly, he doesn't have a single process that takes a long time on the server, but a series of pages that collect a whole lot of information (in Session) that shouldn't be re-initialized/rewritten by pages on a second browser tab.
Hans Kesting
Even if that is the case, I still do not believe that there is a means to differentiate different browser windows. What we are discussing is finding a way of storing the state of the user's progress through the multi-page process. That is one of ideal uses for Session. So, instead of trying to detect how the user got to the state they did, he should simply design the system to react to the state in which it thinks the user is.
Thomas
A: 

You cannot distinguish two http POSTs for the same page even if they are from different tabs.

It's like the famous back-button problem - they can post, press back, and repost.

The usual solution is hidden tracking fields, but it's very hard to make them reliable.

If it's a wizard-type process, it should be simple to detect if they are overwriting fields that have already been entered, and show a warning.

martin
+1  A: 

Every time you render a form, set the value of some hidden field to random string. Store the same string in Session state. When the user posts back, check if the two values are equal. If not, this must be a re-post.

naivists