I am new to using MVC and still trying to learn how to use it properly. As such, I may be asking the wrong questions. Here is my current problem and what I am trying to do. I have an intranet web application that I am building. I have some data filter
information that I need to hold and apply across most of the web application. I have tried multiple ways to hold this information (Static variable, Session, TempData). All have worked very well unless I open the same web application in a second browser tab.
Then, all methods bleed their data through each other. What I have come up with as a current solution to this problem is a list that uses a unique GUID for each browser tab. Each list item would contain all of the data that the browser tab needs to keep
its' data filters correct. In order to give each browser tab a unique GUID, I have used the javascript variable (window.name) to hold it. Basically, when a new browser tab is opened and a new session for the web application, then the javascript will check
if window.name is blank. If so, then it will make an ajax call to the web application which will pass back a new GUID. The javascript will then populate this value into (window.name). This part works fine and (window.name) holds the value fine in both IE
and FireFox. Now comes the problem.
PROBLEM:
I have thought that I could use the RouteConfig section to set a route option to always load and hold the javascript variable (window.name). For example url: "{controller}/{action}/{id}/{tabid}", defaults: new { controller = "Home", action = "Index", id
= UrlParameter.Optional, tabid = <? javascript variable (window.name) ?>}. How can I run a piece of javascript code to return the (window.name) variable? If I can't run it here, where can I load this value into the web application so it will be available
either in the URL or in a visible variable within the web application that can be seen only by that specific browser tab?
Is there a solution to this or am I going completely the wrong way with this?
Javascript can't be used in Server code and, in Routing especially. You're trying to keep the state in stateless application. To keep the state - there are many ways.
As you found you can use the URL QueryString parameter, but in this case in your requests you have to pass the parameter. You have to keep this parameter in all Models (like to create the BaseModel) and assign it in Controller action.
You can try another one - use cookies. But in this case your clients, where cookies are disbaled, can't use your application.
If your application is behind the security, you can use SessionId, user name or any other indicator and keep the data against the user in DB or Cache Service.
you are on the correct approach. the session key is stored in a cookie. as the browser shares the cookie with all instances (tabs or new windows) opened from each other.but don't use static, as these are shared across all request (every user).
so as you found you need second key that is tied to the tab/window. you can use a route value or a hidden field.
An example would be having your web application open on 2 browser tabs. In the first tab, you set a session variable to: Sesssion["MyName"] = "JohnDoe";. Then, on the second browser tab, you set the same session variable to: Session["MyName"] = "JaneDoe";.
The web application on the first browser tab will then read its Session variable "MyName" and suddenly JohnDoe has become JaneDoe. I may have called this bleeding (data from one browser tab appearing on a different browser tab), but I am sure it goes by other
names as well.
you are on the correct approach. the session key is stored in a cookie. as the browser shares the cookie with all instances (tabs or new windows) opened from each other.but don't use static, as these are shared across all request (every user).
so as you found you need second key that is tied to the tab/window. you can use a route value or a hidden field.
Thank you for the encouraging words. It is the same user that is logged in for each browser tab. They are just setting some primary filters to be different for each browser tab. Since it seems that all data is shared across all browser tabs, then I will
need a second key that is not shared. I had tried a hidden field, but it kept losing its value after a refresh. I could find no way to get it to keep the value set properly. That could be due to my inexperience as well.
My current approach is using the route value as you have suggested. My question is how to set it properly so it will stay consistent and separate between browser tabs. My current thought is to set the javascript DOM variable: window.name. This one value
stays separate between browse tabs or even windows on the same tab. I have a way to set its value with a GUID to keep them unique. Now, all I need is a way to insert this value as a Route Value properly. Is there a way to have javascript run some code when
the page is refreshed, fetched or clicked (activated) so that it can append the necessary value onto the Route if it doesn't already exist (ie: append "?tabid=123-45-678-345" to the url)?
An example would be having your web application open on 2 browser tabs. In the first tab, you set a session variable to: Sesssion["MyName"] = "JohnDoe";. Then, on the second browser tab, you set the same session variable to: Session["MyName"] = "JaneDoe";.
The web application on the first browser tab will then read its Session variable "MyName" and suddenly JohnDoe has become JaneDoe. I may have called this bleeding (data from one browser tab appearing on a different browser tab), but I am sure it goes by other
names as well
THis occurs in any web application. It is normal! More, the name should be unique by user- not by tab!
Think about email provider - yahoo, gmail - you delete in one tab an email and in the other you want to see it from previous folder. Guess what? Error!
ideally you want to create the guid when they open the tab but this is not always possible. te guid/id should supply some context. say your app list employess and allows the user to view. in this case when you view an employee you want to include a unique
if for the employee in the url.
now they may view the same employess in 2 tabs. if you can edit/update employee, then you may need a transaction guid for each view, to detect update from tab 1 does not overwrite tab 2.
ideally you want to create the guid when they open the tab but this is not always possible. te guid/id should supply some context. say your app list employess and allows the user to view. in this case when you view an employee you want to include a unique if
for the employee in the url.
I have a piece of javascript that activates at $(document).ready(). It checks the DOM variable: window.name. If it is blank ( = ""), then it will automatically perform an ajax call (async: false) to a SetWindowID function (MVC ASP) in the application.
This function will create a new unique GUID. Then it will add this GUID to the Session list<> class that contains the necessary tab unique values. Then it will pass the GUID back as a string to the javascript that called it. The javascript ajax call will
then populate this GUID into the window.name variable.
This way, even if they copy / paste the URL into a new tab, it will still create a new list<> record for the tab and it would be given a new GUID and be able to follow its own path in the application. This also means if they open 2 tabs to the same record
and attempt to update the same record on both tabs, then it would be intentional on their part and not because the tabs don't know the difference.
An extra option on this is if the user did copy / paste the url to a new tab, the script could be smart enough to send the old tabid along with the new tabid. The script could then copy the old record for the old tabid into a new record with the new tabid.
This would let the user open a second tab at the same spot if they want. Or, the script, when sent an old tabid for a different tab, could just wipe and send the user to the default start screen. Either way, it is up to my boss to tell me which way they
want the intranet app to behave. I just need to be able to keep each tabs information separate.
All i need now is a way to attach this identifying GUID to the URL so when the web page processes an action, the information is already there. For example, the javascript will always make sure that the parameter ?tabid=123-45-6789-abc is always appended
to the URL regardless if it is a GET or a POST prior to the MVC APP processing the request. All requests do start from the client so where would I be able to intercept the URL, and add to it if needed, prior to being sent to the server?
THis occurs in any web application. It is normal! More, the name should be unique by user- not by tab!
I do agree that this does occur. I don't disute that in the least. But I fear you might be reading a bit too much into the example I have given. My example was only to simplify what I an trying to do understandably. It does not exemplify exactly what
data I am trying to hold. I am unable to detail all information I want to keep unique per browser tab due to 1. complexity - there are multiple pieces of information (filters) that I am asked to contain. 2. security - the details of my projects are considered
sensitive in nature so I have to be ambiguous and use examples for explanations.
It is obvious to me that your knowledge far surpasses mine in this and as such I accept your information, and criticism with the utmost respect. But, as a developer, I am still constrained to have to create a web application that performs in the manner
that has been requested of me. In this case, create an application that can be opened in multiple tabs and keep each tabs filter data independent.
tsteadman
0 Points
7 Posts
Routes and javascript
Dec 20, 2012 05:14 PM|LINK
Greetings,
I am new to using MVC and still trying to learn how to use it properly. As such, I may be asking the wrong questions. Here is my current problem and what I am trying to do. I have an intranet web application that I am building. I have some data filter information that I need to hold and apply across most of the web application. I have tried multiple ways to hold this information (Static variable, Session, TempData). All have worked very well unless I open the same web application in a second browser tab. Then, all methods bleed their data through each other. What I have come up with as a current solution to this problem is a list that uses a unique GUID for each browser tab. Each list item would contain all of the data that the browser tab needs to keep its' data filters correct. In order to give each browser tab a unique GUID, I have used the javascript variable (window.name) to hold it. Basically, when a new browser tab is opened and a new session for the web application, then the javascript will check if window.name is blank. If so, then it will make an ajax call to the web application which will pass back a new GUID. The javascript will then populate this value into (window.name). This part works fine and (window.name) holds the value fine in both IE and FireFox. Now comes the problem.
PROBLEM:
I have thought that I could use the RouteConfig section to set a route option to always load and hold the javascript variable (window.name). For example url: "{controller}/{action}/{id}/{tabid}", defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional, tabid = <? javascript variable (window.name) ?>}. How can I run a piece of javascript code to return the (window.name) variable? If I can't run it here, where can I load this value into the web application so it will be available either in the URL or in a visible variable within the web application that can be seen only by that specific browser tab?
Is there a solution to this or am I going completely the wrong way with this?
Thank you for your time.
Terry Steadman
ignatandrei
All-Star
135142 Points
21676 Posts
Moderator
MVP
Re: Routes and javascript
Dec 20, 2012 08:46 PM|LINK
What? Could you give a small example of "bleeding"?
vladnech
Member
175 Points
78 Posts
Re: Routes and javascript
Dec 20, 2012 11:36 PM|LINK
Hi
Javascript can't be used in Server code and, in Routing especially. You're trying to keep the state in stateless application. To keep the state - there are many ways.
As you found you can use the URL QueryString parameter, but in this case in your requests you have to pass the parameter. You have to keep this parameter in all Models (like to create the BaseModel) and assign it in Controller action.
You can try another one - use cookies. But in this case your clients, where cookies are disbaled, can't use your application.
If your application is behind the security, you can use SessionId, user name or any other indicator and keep the data against the user in DB or Cache Service.
Regards,
Vladimir
bruce (sqlwo...
All-Star
36860 Points
5450 Posts
Re: Routes and javascript
Dec 21, 2012 03:12 AM|LINK
you are on the correct approach. the session key is stored in a cookie. as the browser shares the cookie with all instances (tabs or new windows) opened from each other.but don't use static, as these are shared across all request (every user).
so as you found you need second key that is tied to the tab/window. you can use a route value or a hidden field.
tsteadman
0 Points
7 Posts
Re: Routes and javascript
Dec 21, 2012 12:49 PM|LINK
Greetings ignatandrei,
An example would be having your web application open on 2 browser tabs. In the first tab, you set a session variable to: Sesssion["MyName"] = "JohnDoe";. Then, on the second browser tab, you set the same session variable to: Session["MyName"] = "JaneDoe";. The web application on the first browser tab will then read its Session variable "MyName" and suddenly JohnDoe has become JaneDoe. I may have called this bleeding (data from one browser tab appearing on a different browser tab), but I am sure it goes by other names as well.
Thank you for your time.
Terry Steadman
tsteadman
0 Points
7 Posts
Re: Routes and javascript
Dec 21, 2012 01:05 PM|LINK
Greetings bruce,
Thank you for the encouraging words. It is the same user that is logged in for each browser tab. They are just setting some primary filters to be different for each browser tab. Since it seems that all data is shared across all browser tabs, then I will need a second key that is not shared. I had tried a hidden field, but it kept losing its value after a refresh. I could find no way to get it to keep the value set properly. That could be due to my inexperience as well.
My current approach is using the route value as you have suggested. My question is how to set it properly so it will stay consistent and separate between browser tabs. My current thought is to set the javascript DOM variable: window.name. This one value stays separate between browse tabs or even windows on the same tab. I have a way to set its value with a GUID to keep them unique. Now, all I need is a way to insert this value as a Route Value properly. Is there a way to have javascript run some code when the page is refreshed, fetched or clicked (activated) so that it can append the necessary value onto the Route if it doesn't already exist (ie: append "?tabid=123-45-678-345" to the url)?
Thank you for your time.
Terry Steadman
ignatandrei
All-Star
135142 Points
21676 Posts
Moderator
MVP
Re: Routes and javascript
Dec 21, 2012 03:25 PM|LINK
THis occurs in any web application. It is normal! More, the name should be unique by user- not by tab!
Think about email provider - yahoo, gmail - you delete in one tab an email and in the other you want to see it from previous folder. Guess what? Error!
bruce (sqlwo...
All-Star
36860 Points
5450 Posts
Re: Routes and javascript
Dec 21, 2012 03:27 PM|LINK
ideally you want to create the guid when they open the tab but this is not always possible. te guid/id should supply some context. say your app list employess and allows the user to view. in this case when you view an employee you want to include a unique if for the employee in the url.
now they may view the same employess in 2 tabs. if you can edit/update employee, then you may need a transaction guid for each view, to detect update from tab 1 does not overwrite tab 2.
tsteadman
0 Points
7 Posts
Re: Routes and javascript
Dec 21, 2012 03:54 PM|LINK
Greetings bruce,
I have a piece of javascript that activates at $(document).ready(). It checks the DOM variable: window.name. If it is blank ( = ""), then it will automatically perform an ajax call (async: false) to a SetWindowID function (MVC ASP) in the application. This function will create a new unique GUID. Then it will add this GUID to the Session list<> class that contains the necessary tab unique values. Then it will pass the GUID back as a string to the javascript that called it. The javascript ajax call will then populate this GUID into the window.name variable.
This way, even if they copy / paste the URL into a new tab, it will still create a new list<> record for the tab and it would be given a new GUID and be able to follow its own path in the application. This also means if they open 2 tabs to the same record and attempt to update the same record on both tabs, then it would be intentional on their part and not because the tabs don't know the difference.
An extra option on this is if the user did copy / paste the url to a new tab, the script could be smart enough to send the old tabid along with the new tabid. The script could then copy the old record for the old tabid into a new record with the new tabid. This would let the user open a second tab at the same spot if they want. Or, the script, when sent an old tabid for a different tab, could just wipe and send the user to the default start screen. Either way, it is up to my boss to tell me which way they want the intranet app to behave. I just need to be able to keep each tabs information separate.
All i need now is a way to attach this identifying GUID to the URL so when the web page processes an action, the information is already there. For example, the javascript will always make sure that the parameter ?tabid=123-45-6789-abc is always appended to the URL regardless if it is a GET or a POST prior to the MVC APP processing the request. All requests do start from the client so where would I be able to intercept the URL, and add to it if needed, prior to being sent to the server?
Thank you for your time.
Terry Steadman
tsteadman
0 Points
7 Posts
Re: Routes and javascript
Dec 21, 2012 04:08 PM|LINK
Greetings ignatandrei,
I do agree that this does occur. I don't disute that in the least. But I fear you might be reading a bit too much into the example I have given. My example was only to simplify what I an trying to do understandably. It does not exemplify exactly what data I am trying to hold. I am unable to detail all information I want to keep unique per browser tab due to 1. complexity - there are multiple pieces of information (filters) that I am asked to contain. 2. security - the details of my projects are considered sensitive in nature so I have to be ambiguous and use examples for explanations.
It is obvious to me that your knowledge far surpasses mine in this and as such I accept your information, and criticism with the utmost respect. But, as a developer, I am still constrained to have to create a web application that performs in the manner that has been requested of me. In this case, create an application that can be opened in multiple tabs and keep each tabs filter data independent.
Thank you for your time.
Terry Steadman