Most AVR-driven ASP.NET Websites use the Session object to save the state of some variables. For example, a customer number may be stashed in a Session variable like this:
Session['custom-number'] = 673
when the user requests a page (the same page or another page), that value is available for your logic to fetch and do something with. For example, let's assume the user clicks a button to take the app to a new page and that page's logic needs the current customer number. That number could be fetched in the code-behind like this:
CustNo = Int32.Parse(Session['customer-number'])
(As an aside, session variables must also be converted to a specific type before assigning them to a typed variable)
How long is that customer number available?
That customer number is available for as long as the Session object is active. Session life is dictated by the ASP.NET Session timeout value. Each time a postback occurs the timeout clock starts anew. The default timeout value is 20 minutes, or you can explicitly set it to a given value in the web.config file. For example, this web.config setting sets session timeout to 60 minutes:
timeout value must be provided in minutes. As long as the user causes a postback to the server within the timeout value, the session is persisted and therefore the customer number in the session variable is persisted. Assuming a default 20-minute session timeout, if the user leaves a page idle for an 18-minute coffee break, the value is persisted and the app continues normally. However, if the user leaves a page idle during a 22-minute coffee break, the next time the user attempts a postback (by clicking an app button or some other interaction with the app) the customer number is no longer available (which most likely manifests itself with the notorious "Object reference not set to an instance of an object" error message and the app stops working.
In some cases, session timeout more than 20 minutes long is desirable. Consider an app in use on a shop room floor. An engineer may be going back and forth between the assembly line and the app many times during the day. In that case, the customer must persist for more than 20 minutes. I've heard of 8 or even 12-hour session timeouts to avoid timeout issues in a case like this.
The problem with very long session timeouts is that the session timeout also often dictates when application "clean up" operations are performed. This is especially true with an application modernized with ASNA Wings, ASNA Monarch, or a custom mobile app written with ASNA Mobile RPG. In those cases, the associated IBM i job will not end until the session ends. Beyond those examples, though, you may have clean-up processes of your own triggered by
Session_End event handler (as defined in the
The important thing to remember is that the user session doesn't end on the server until the session timeout value has expired. Any server-side operations based on session timeout occurring don't occur when the browser closes, but rather when the session times out. The server has no knowledge of the user simply closing the browser. That client-side action imposes no control on session time-out. As a general rule, once the user is done with the app (ie, when the user closes the browser), you want your clean-up operations to perform as soon as possible.
Stretching session timeout
Step 1. The key to this technique is using the much maligned HTML
iFrame tag. If your app uses master pages, add this code to the master pages' markup under the body
tag (if you aren't using master pages, you'll need to add this code to every page's markup):
<iframe src="<%=Page.ResolveClientUrl("~/StretchSession.aspx")%>" width="0" height="0" style="display:none;">
iframe tag has an inline style tag with
display:none. Without this style, the
iframe displays an odd little mark on the page.
Step 2. In the
web.config, set the session timeout to three minutes:
<system.web> <sessionState timeout="3"/> <compilation debug="true" targetFramework="4.5"/> </system.web>
The timeout value you're setting here controls how quickly the session times out of the server when the user closes the browser. As long as the user has the app running in a browser, its session will be stretched indefinitely. Depending on your on your needs, you may make this value greater than three minutes, but, as will soon be discussed, don't set it for much less than three minutes.
Step 3. In the root of the app, create a page called
StretchSession.aspx, being sure to not specify a master page for this page. This page will never be seen by users. In the markup for the
SesssionStretch.aspx page, add these three lines to its
<head runat="server"> <meta http-equiv="cache-control" content="no-cache"> <meta http-equiv="expires" content="0"> <meta http-equiv="refresh" content="55;url='StretchSession.aspx'"/> </head>
meta tags are the key to this technique, with the
meta http-equiv="refresh" doing the most interesting thing. This line reloads
iframe in the master page (or the current page if you aren't using master pages). The reload of this page 55 seconds restarts the session timeout clock. Recall that the session timeout is configured for three minutes. The difference between the 55-second refresh and the three minutes is to ensure that a little network latency doesn't cause problems.
A first pass at this technique had the meta refresh tag load a simple HTML file on the theory that sending any request back to the server would refresh the session timeout. However, a quick bit of testing showed an ASPX page was required to stretch the session (even though the page has no code). I am guessing, but the ASPX page is probably required to ensure the ASP.NET pipeline is invoked when the
StretchSession page is sent.
Once you get your app running, fire up your favorite Web browser developer tools. You'll see that the meta tag submits your StretchSession page submitted every 55 seconds or so, with no flicker or other artifacts of the page being submitted—but that page submission causes the session to get stretched ("refreshed" might be a better word).