We have a custom session handler which stores a history of data for pages. We have a requirement where we need to store and identify unique sessions for every tab/window.
For simplicity let's just say I need a unique string for each tab i.e.
Window A - Tab 1 - ABCDEF
Window A - Tab 2 - CDEFGH
Window A - Tab 3 - EFGHIJ
Window B - Tab 1 - GHIJKL
Window B - Tab 2 - IJKLMN
I need these strings to be accessible immediately when any link is clicked or when any tab performs a postback.
We have an overly complication solution in place at the moment which generates these unique strings and saves them in the tab name and cookies and uses the window blur/focus events to determine when a page has been navigated away. It works well 'in the lab' but we do get problems with this 'in the wild'.
I guess the most 'reliable' way to do this would be to generate a unique string and place it on the querystring for every page and every URL on that page, that way it would be available immediately as you click on any link or post back, and you could move between tabs / windows freely. However that would take a significant rewrite and I wonder if I'm missing a more straightforward option.
Any suggestions welcome.
In the end we found an ideal solution to this. We don't have 'unique' sessions between tabs, we have 'unique' sessions for every page, ignoring tabs entirely.
We still use the blur/focus events to handle which tab the user is currently on, but that is only used to provide tab specific navigation history and is nothing separate to the session handling.
This seems to work well for our needs.
Related
I have a grid view and an edit button in the grid view. On edit button click I am opening a new aspx page that has text fields for input the data. When a user copies the URL of the gridview and opens it in a new tab of any browser then click on the edit button for two different records. If the user changes anything in the first tab and submits it. It changes the info for the record on the second tab. It is happening because I am passing userid in session to the form aspx page and session got updated when user opens the second record in the new tab.
Are there only two ways to passing data to aspx page?
using session
using a query string
I don't want to use the query string.
Please help thank you.
You are writing a ASP.Net application, so at the end of the day there is only that much you can do. You can request some things off the browser, but if he actually does it is entirely up to it.
You can make it unlikely to happen by accident, using the HTML Links target property. This requests the browser to re-use any alread open tabs for this record. But that will not prevent a dedicated person from still opening 2 copies.
A pretty simple way to avoid race conditions in general, is the SQL rowversion column. You retreive the rowversion with the rest. You keep it along in a hidden formular field (that is what they are there for). When writing the update, check if it still matches before the write. If yes, you update. If not, somebody has modified the record since then and you reject the update. Can be the same user in another tab, can be another user at the end of the world. Could be that this tab was opened a year ago, surviving on sleep mode. It does not mater - any change trips this protection.
I have a C# WinForms TabControl, with many controls on each tab page. When you start, not many user objects are loaded, but as you switch tabs, it seems to load the tab with controls, and USER objects grows and grows, eventually hitting the limit and crashing the program. USER Objects is at its max setting in windows. At the moment, it can't be radically redesigned to use less controls, so that is a requirement here to maintain the same amount of controls on each tab.
I'm trying to see if there is a way to after switching tabs, to actually force unload the previous tab, so that it releases its user objects, then if switching back to that tab, everything seems normal and loads that one again (and unloads the previous one). Or some way to mimic this which actually releases USER objects.
I made a test program showing the issue, which can be easily recreated. C# WinForms, added 72 text boxes on each tab. When you start up to Tab 1, Task Manager shows 94 User Objects. When I click Tab 2, it shows 168. They never go lower. This happens without adding anything extra, no events, etc. Adding 2 more tabs, it goes to 315. So this is definitely something going on that is never unloaded, but only after click to tab. I need to find a way to lower USER objects on non-used tabs.
Hi StackOverflow Community,
I am working on a universal app for Windows in C# and XAML. So far, progress has been smooth (the whole framework is very easy to use) however I have run into an issue related to page navigation and state caching that I was hoping to get some help with.
In a standard template, navigation through an app would look like this:
Home -> Profile (ID 1) -> Game (ID 120) -> (Back) Profile (ID 1) -> (Back) Home -> Profile (ID 2) -> Game (ID 210)
However, I'd like to do something like this:
Home -> Profile (ID 1) -> Profile (ID 2) -> Profile (ID 3) -> Game (ID 120)
The reasoning behind this requirement is simple: the profile page contains a list of friends, groups, games, etc for that profile. Clicking on a friend should bring you to their profile page and from there you should be able to view their details, their friends, etc and continue to drill down friends lists or groups (which can link back to profiles).
This is important, since most of the questions I've come across on SO have been related to this... but I am already able to navigate back and forth through the list properly like I listed in the second example. The issue that I'm having comes from some funny caching and state issues during navigation.
For simplicity sake, lets just talk about the Windows Phone view; the Profile Page contains a Pivot Table with four sections (Details, Games, Friends, Groups). If I'm on the profile for user 1, swipe over to the friends section, and tap on the profile for user 2 then the navigation occurs and I have 3 pages in my back stack (home, profile for user 1, profile for user 2). This is not the part I'm having trouble with; the issue I'm having is related to navigating backwards - when I hit the back button and navigate backwards on the frame I am returned to the profile for user 1 (which is good), however the state of the view is reset and instead of being on the 'Friends' section I am returned to the first section (in this case the 'Details' section - which is annoying from a UX perspective).
I have played around with the NavigationHelper and the SuspensionManager as well as experimented with setting the page caching to enabled, however I got some unexpected results. As explained above if I don't set the NavigationCacheMode to Enabled then I am always returned to the first pivot section when I navigate backwards, however if I DO set the cache mode to Enabled then when I navigate to new instances of the profile page then the state seems to be recycled and instead of appearing on the 'Details' section for the NEW profile, I am loaded into the same section I was in when the navigation occured (i.e. if I was on the 'Friends' section for User 1, then when I tap User 2 I will be on the 'Friends' section for User 2. Also annoying from a UX Standpoint). The same will occur when I'm navigating backwards as well, if I'm 4 profile deep and looking at the 'Groups' section for profile 4, when I hit back then I will be looking at the Groups' section for profile 3 (even if I navigated from profile 3 -> profile 4 from the 'Friends' section)
Is this something that any of you have experienced? I'm not looking for code snippets specifically (though I definitely am not in the habit of turning them down!), but more just the thought process on how I should handle this. I know that some apps do something similar to this, and I'm sure I'm missing something small but any advice would be greatly appreciated.
An example of this same type of navigation I'm trying to achieve would be on the Hulu App. If you select a series and swipe over to the 'Recommended' Section you will see other shows. Tapping on one of these shows will open up the details for that show (and you can go multiple layers deep), however tapping the back button will bring you back to the last series you viewed (and most importantly, will also put you back on the 'Recommended' Section)
Normally I would absolutely provide code-snippets, but since this is more of a broad question rather than a "Why doesn't my code work?" question I decided hold off and will wait to provide snippets only if they are requested.
Thanks in advance!
Page Caching has gotten a lot more flexible but also a lot more complex in Windows Store Apps. You now have the flexibility to implement navigation patterns like yours, but you also have to do a lot of stuff by hand.
First there is NavigationCache: You can enable it on pages (but ONLY in the constructor).
For the Cache to work correctly you also have to set the CacheSize (it is in the default App.xaml.cs and set to 1. You will have to increase it to work properly.
Still, it only keeps one instance of the page in the cache. In your case, you navigate to that page multiple times with different IDs. With navigation cache enabled, it will just make sure the all land on the same instance of the page.
I usually only cache the root page of my app and only if it contains a lot of data (like your hub).
NavigationCache if used to often fills up a lot of memory and therefore your app gets shut down earlier when put in background. Use it with care.
Usually it is best to just reconstruct pages every time you navigate to them and just cache the data (if obtained over the wire).
The NavigationHelper offers a simple standard implementation for saving a state dictionary for a page. When your page gets recreated on a back navigation, you still have to handle it your state by hand.
It just provides you with a dictionary where you can save values in: What HubSection you are in, how far you scrolled, etc.
It utilizes the BackStackDepth to get you the right dictionary for the page you are on.
Once you get your dictionary back, you have to set the HubSection, scroll down, etc.
So in the end: Yes, you have to do all that by hand...
On my two-page web application, users progressively enter info and make selections on page one. When done, they click a 'Generate' button that navigates to page two. Users print that page and hit the browser's Back arrow to return to page one with selections intact.
After a few generated pages (2 or 3), clicking Back just disables the icon without going back. They have to manually revisit page one, reentering their info and selections.
I found that the down arrow to the right of to the Back / Forward arrows (IE8) that shows the immediate history generally includes all 'previous' pages. But when the back button is about to disable on click, the history only shows the current site.
What events, scripts, headers, etc. clear the history for the current site? It occurs in IE7 and IE8 on WinXP and Win7. In FireFox, the button did not disable, but it did not do anything either. Users report it as a recent and I have been making changes to the application, but it only affects the HTML on page two (not scripts, though). It's probably a code issue if it's recent, but I'm not sure what to look for when double checking my recent changes.
Which version of IE?
Internally, IE maintains a limited amount of data in the travellog (aka back/forward stack). ASP.NET pages with huge postback forms often blow this limit, wiping the history stack.
In IE6 and IE7, if there is a form input field with a value longer than 523,659 characters, when you navigate away from the page, IE may clear the current session's travellog (similar to history), disabling the back and forward buttons.
I believe the overall Travellog size limit was upped somewhat in IE8, but it's not more than a few megabytes.
As a general rule, if you want your users to navigate back and forth between pages, I would give them links on the page that do the job (without using javascript:back()) instead of using the browser's navigation.
What's happening, most likely, is that the postbacks of a single page are sometimes considered pages, sometimes not. If a user action loads a page that has the same URI and query string, most browsers consider that "the same page" even though EVERYTHING may have changed. This is usually due to heavy use of MultiViews with the information about the current view kept in ViewState or Session; navigating within that page doesn't change the URI being navigated to, so the browser doesn't log each new load as unique.
If you really need proper back-and-forth functionality, you will need to make sure that every link will result in the browser being told to navigate to a different URI than the current page. You can do this by adding a query string element that will be present in every link to a different page or view, that will auto-increment with each click the user takes. This gives the browser a different URI every time. You only use the existing QueryString element to create the new one on your links' URIs. This can get cumbersome, and the easier solution is simply to provide in-page navigation and tell your users not to hit "Back" any more.
I'm using an usercontrol (*.ascx) in a CMS system C#.NET
I've got a Gridview which displays address. You hav a link on the line items and you can click on the items (link) which navigates to other page with querystring info and displays the detail information. When the user clicks on cancel/back it returns the the overview page. Both are separate programs.
When the user clicks on Next, Next, Next e.g. page 7 is displayed. So clicking on an "adres link" on Page 7 will open a new page and when the user comes back it should display page 7 back again.
I was keeping the page numbers in a session. so when the user comes back it reads the pagenumber from the session. This works fine. But the issue is this module is used other placess too, and also in other portals (which uses the same module)
So when have clicked next next etc and you are on page 7 and then you open another portal or other Porgram which have the same module, it displays page 7. Because it reads the Session variable and sometiems it gives a dump because page 7 doesn't exist, because no much records.
Viewstate fix this issue, but everytime after clicking the adres item and coming back it displays page 1, which is not what I want.
As I said, I use the same module in other pages and other portals (same program with different settings CMS -system)... So where and how do I need to store the pagenumbers so it doesn't have conflict with other pages and other portals?
ViewState["page"] = 7 -> starts on page 1 always when you come back
Session["page"] = 7 -> page number is shared....
Why don't you keep a Structure or Dictionary instead of simple int in the session. In this you can store Page as well as the Module.
I believe you need to think about instantiation. It seems that you need to isolate each instance of your CMS so each one will share its own set of server variables, includinig session ones.
Well, it's true you're using some ASCX control, but you can have some "application identifier" so any of control instances can have their own set of values.
Anyway, storing long objects in session is a bad practice, since other modes than "in process" will serialize objects and deserialize them whenever you access to session's state.
Maybe you need some kind of custom session management in order to optimize performance and memory usage so your components will be rightly isolated and they will remain performant.