|
In my organization we are required to warn the user that their session will timeout soon and allow them to request more time. he warning and request for more time is handled with a JavaScript timer and a confirm. Then i have found that it works well to request a page that returns a status code of 204 and no content. Just start 204.aspx, remove all the HTML except the first line and then modify the PageInit like this:
Private Sub Page_Init(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Init
'CODEGEN: This method call is required by the Web
'Form Designer
'Do not modify it using the code editor.
' IGNORED THE CODEGEN DIRECTIVE
'Send only an HTTP header to prevent replacing
'the old page. This extends the session
'timeout without the delivery of a new page.
System.Web.HttpContext.Current.Response.StatusCode = 204
System.Web.HttpContext.Current.Response.StatusDescription = "No Content"
System.Web.HttpContext.Current.Response.SuppressContent = True
'InitializeComponent() REMOVE THIS
End Sub
|
|
|
|
|
Thanks spot! That's a great way to extend the session with user interaction. Is there a component that you're using that will extend the session automagically without user action?
Hey, it's cool to see the ssa using asp.net. Are you excited about the new security tools in 2.0? I just took a look at the configuration and connection string encryption tool in beta 2. Wow!
Achieve by taking great pride in everything you're charged with, be successful by having the initiative to charge yourself, and realize that talent is comprised of aptitude, hard work, and spirit. Hone in on your aptitudes and dedicate your spirit to reach your full potential.
|
|
|
|
|
I don't use any components for this since the 204.aspx is so simple and you only need it once in each project. Also, I don't extend the session without interaction but if I did, I'd probable use some in-line JavaScript and functions in a linked file similiar to this untested code.
setTimer();
function setTimer() {
setTimeout("extendSession()", 1200000);
}
function extendSession() {
navigate("204.cfm");
setTimer();
}
I can't wait for VS 2005. It's going to make things much better and they are pretty good now.
|
|
|
|
|
That's a cool technique ssa, thanks. I have been thoroughly enjoying VS 2005...can't wait for DB Professional edition too.
Achieve by taking great pride in everything you're charged with, be successful by having the initiative to charge yourself, and realize that talent is comprised of aptitude, hard work, and spirit. Hone in on your aptitudes and dedicate your spirit to reach your full potential.
|
|
|
|
|
ssaSpot, can you please give some more information on your solution. How do I fully implement this - do I have to set up a javascript timer that if they click yes, I want to extend my session, just redirects to this page? Is this what you mean with your instructions?
Thanks for your help
|
|
|
|
|
Each time the IFrame is refreshed, the system 'navigate' sound is played. This can get quite annoying, in my experience. Is there any way to supress this that you know of, other than instructing the user to turn off their navigate sound?
Testing gravity, one jump at a time...
|
|
|
|
|
Excellent observation dz. Unfortunately as far as I know...there's no way in ASP.NET 1.1. Automatic interaction with the server requires a postback or a request. Off the top of my head I would say any HttpRequest or postback causes that navigate sound in IE. You will see a new concept called a Script Callback in .NET 2.0 that I am very excited about. Essentially it allows for server interaction without posting back and redrawing the page. I imagine I will use this construct to improve the defibrillator when 2.0 is released.
The only work around I can think of is to extend your session timeout a bit so it is not as noticeable. In my situation I basically had scores of users in this organization working with some insensitive data, but getting frustrated if they had to log back in...i.e.:
Joe-what-did-they-hire-you-for User starts interacting with system. Joe gets an IM. Joe goes to get coffee. Joe gets a business call and chats for a while. Now joe has to browse the net to do some research in another browser. Then Joe opens the latest humorous forward from his friends. Now joe goes back to my system and finds that he has to log back in to continue, and gets annoyed.
You can see in my situation that Joe never noticed the 'click' that refreshed his session because he was browsing elsewhere or doing something unrelated when it happened. I'd imagine if your Joes are actively working with the system and paying attention long enough for multiple 'CLICKs' to bother them, you might try to increase your session timeout to an average time between typical user-initiated postbacks, if it makes sense for what you're dealing with....
Until .NET 2.0, sorry I can't offer anything else off the top of my head to solve the issue outright. Any ideas fellow devs? Please chime in.
Achieve by taking great pride in everything you're charged with, be successful by having the initiative to charge yourself, and realize that talent is comprised of aptitude, hard work, and spirit. Hone in on your aptitudes and dedicate your spirit to reach your full potential.
|
|
|
|
|
Perhaps by using a Javascript XMLHTTP request instead of a META REFRESH in Defibrillator.aspx, you might be able to get rid of the tag. You might need to set the cookie information for the request in JavaScript so it matches the cookie known by the Session. Just a thought.
|
|
|
|
|
That's a fantastic thought chris! If anyone gives this one a shot, let us know the results please. I'm onto .NET 2.0 work and a robust graphics processing API that I will be posting soon.
|
|
|
|
|
Even better don't use activeX, this works on all DOM1 browsers
<br />
var script = document.createElement("script")<br />
srcipt.src = "http://www.domain.com/keep-session-alive.aspx"<br />
document.getElementsByTagName("HEAD")[0].appendChild(script)<br />
|
|
|
|
|
Aaaaa yes, thanks Killer. I don't think I was alive during the time of DOM1 browsers, you have enlightened me with excellent new tricks
Achieve by taking great pride in everything you're charged with, be successful by having the initiative to charge yourself, and realize that talent is comprised of aptitude, hard work, and spirit. Hone in on your aptitudes and dedicate your spirit to reach your full potential.
|
|
|
|
|
That's a great idea chris, thanks for it! I hope with ATLAS I can make an even better easy solution.
Achieve by taking great pride in everything you're charged with, be successful by having the initiative to charge yourself, and realize that talent is comprised of aptitude, hard work, and spirit. Hone in on your aptitudes and dedicate your spirit to reach your full potential.
|
|
|
|
|
In my experience, admins tend to keep similar timeouts for most web sites, so while it's cool that your page can determine its own refresh interval, I'd rather just have an .htm page that requires no code execution to do its thing.
My page looks like this:
<br />
<html><br />
<head><br />
<title>KeepAlive</title><br />
<meta http-equiv="refresh" content="600"><br />
</head><br />
<body></body><br />
</html><br />
It's got a 5 minute interval which is long enough to not bother the server, but still stay well below most site's session timeout interval. Adjust as needed.
I also don't like to have to cut-n-paste any more than absolutely necessary, so I created a class to do any necessary work for me. This way, I can make a change in one place and all my pages that need to stay alive get the update. I don't like to create a base page for something this simple.
Here's my class:
<br />
Public Class KeepAlive<br />
Private Sub New()<br />
End Sub<br />
<br />
Public Shared Sub KeepSessionAlive(ByVal ThePage As System.Web.UI.Page)<br />
KeepSessionAlive(ThePage, "KeepAlive.htm")<br />
End Sub<br />
<br />
Public Shared Sub KeepSessionAlive(ByVal ThePage As System.Web.UI.Page, ByVal KeepAliveURL As String)<br />
Dim MyFrame As New System.Web.UI.HtmlControls.HtmlGenericControl("iframe")<br />
With MyFrame.Attributes<br />
.Add("frameBorder", "no")<br />
.Add("width", "300")<br />
.Add("height", "100")<br />
.Add("src", KeepAliveURL)<br />
End With<br />
ThePage.Controls.Add(MyFrame)<br />
End Sub<br />
End Class<br />
I really enjoyed your article and it's a creative solution to an issue we've probably all run across.
-Kevin Buchan
|
|
|
|
|
OK, I'm retarded in addition to being lazy.
Of course I meant "10 minute" interval, not 5.
Also, I forgot to set my width and height back to "0" after testing me solution and before posting my code.
Sorry for any confusion.
(I rated the article a 4. Thanks.)
-Kevin Buchan
|
|
|
|
|
Hey! Thanks for the looksee and input Kevin . Looks like you've got your own effective solution happening too, which I like a lot! While I don't see how your code is less time consuming than: right-click>Add Web Form>view Code, copy paste one line, Open UserControl>ViewHTML, copy paste one line, I think it's a very slick way you found to approach the problem!
For my purposes, I will have to adhere to the defibrillator, however, because I like the flexibility of not being affected by a changing session.timeout which happens occassionaly in this organization, so if the UC with the defibrillator is on a part of the site that needs to be kept alive, it doesn't matter whether or not another developer had changed the session.timeout on some other area of the site.
Also I like the practice of keeping the "Refresh" postback as close to the session.timeout as possible just to avoid more server trips, especially when I'm inviting joe-oblivious-user to keep their browswer open and hit my server all day long if they want. Those trips might add up with joe-user X thousands per day.
Please feel free to berate my anal-retentive concern for precision...I have to uphold the stereotypes of engineers I swear, I wasn't always like this, it was that course in rocket science and celestial mechanics that warped my brain past normalcy. One of Ferris Bueller's comments about Cameron comes to mind .
Achieve by taking great pride in everything you're charged with, be successful by having the initiative to charge yourself, and realize that talent is comprised of aptitude, hard work, and spirit. Hone in on your aptitudes and dedicate your spirit to reach your full potential.
|
|
|
|
|
My mindset was if I were to want to add this functionality to many pages within a site, I could do that with one line of code per page and not having to touch the HTML. It does seem, however, that if I'm only talking about a couple pages or especially if the server administration is not under my control, then your idea is the better one.
You bring up some good thoughts that I hadn't considered. I tend to work almost exclusively on an intranet so a few more hits are not even noticable, but on a public web site with many more users (assuming your marketing $ is paying off) could be a different story.
I have both of our solutions in my code bank now because they seem to each have their strong points and I can see times when I'll use each.
Thanks for your time.
-Kevin Buchan
|
|
|
|
|
Good call Kevin! I see that in your situation that the method you developed is a clean and great way to do things. I have added it to my bag of tricks too . Some really cool things are going to happen soon with Script Callbacks in .NET 2.0, which will give us the abilities to do even more amazing things. Thanks for your time and sharing your trick too!
Achieve by taking great pride in everything you're charged with, be successful by having the initiative to charge yourself, and realize that talent is comprised of aptitude, hard work, and spirit. Hone in on your aptitudes and dedicate your spirit to reach your full potential.
|
|
|
|
|
Hey thanks Kevin! That is an excellent addition you have made to this frequently traversed issue! Much appreciation for the 4.
Achieve by taking great pride in everything you're charged with, be successful by having the initiative to charge yourself, and realize that talent is comprised of aptitude, hard work, and spirit. Hone in on your aptitudes and dedicate your spirit to reach your full potential.
|
|
|
|
|
Nice one
I have been fiddling with something similar, inspired by my banking site which has a javascrip popup displayed if you're inactive for ~20 minutes telling you that the session will expire in 5 minutes unless you click OK. That way, you won't have the scenario of keeping a session alive if the user has just forgotten to close the browser window, which could be a security risc in a internet cafe/library f.ex.
|
|
|
|
|
Thanks Fredrik. Yes that is an excellent idea! I would be interested in encapsulating that functionality into my .js file and accessing it with a javascript timer from the defibrillator page. I could see where that would be useful, but for my current charge, I wouldn't need that ability. Perhaps I will expand this in the near future. I saw some guy selling a dotNet control that does only these things for $2700, to which I could only roll on the floor in laughter, thinking that someone must have paid that much cash for something that can be done in less than 100 lines of code.
Achieve by taking great pride in everything you're charged with, be successful by having the initiative to charge yourself, and realize that talent is comprised of aptitude, hard work, and spirit. Hone in on your aptitudes and dedicate your spirit to reach your full potential.
|
|
|
|
|
Fredrik, are you talking about Chevy Chase bank? I also noticed that nice feature and remember it for a possible use. The real question is how to redirect to logout page in case user did not hit "OK" button. JavaScript confirm() function opens a modal window and won't allow it. I see two possible solutions:
a) To open a small pop-up window (it could be made modal if we want) displaying HTML page with a warning. It'll allow a main page to redirect itself to logout.asp if user doe not click OK.
b) Use DHTL and display a DIV which mimics a pop-up. I think it's better, it allows to avoid pop-ups. See this article, by the way.
|
|
|
|
|
hm, what about instead of calling confirm directly, it would be called from within a javascript function - then one could if/else the confirm and manually postback (or callback with asp.net 2.0) on true or redirect on false.
Btw not the Chevy Chase bank, I'm not from the US
|
|
|
|
|
What I was trying to say is: until user clicks OK/Cancel button page stays (although session might be already expired.) When user clicks a button it might be too late and page will redirect to logout page regardless of button clicked. So, it's better to have a DIV with a prompt and and OK/Cancel buttons on the same page and to have JavaScript to display this DIV 20 seconds or so before session expires. This JavaScript would also call JavaScript setTimeout(goToLogout, 20000). If user does not hit any button whithin 20 seconds goToLogout() function would redirect to logout.asp[x] page which will force session to expire immediately. If user hits Cancel button it will redirect to logout.asp immediately. If user hits OK button it will initiate postback (or callback with asp.net 2.0) or just use this technique or XMLHTTP Request functionality to referesh session. It actually has almost nothing to do with ASP.NET and could be done in JavaScript + any server language. .NET makes it harder, not simplier.
I'm not from the US
But this says you are
Vladimir Kelman
http://www.vkelman.com
|
|
|
|
|
Creative idea. How many browsers have you tested it in?
|
|
|
|
|
Thanks Joe! Yes, it will work in any browser that interprets the refresh HTTP header. In Netscape it has the effect of hitting 'Reload' at the specified time. I have read online that this refresh will exclude your page from search engine crawling...which is fine since you put this functional tag on a dummy page in an iframe, that you don't want anyone browsing to anyway.
For the final caviat, I've found that the session timeout itself in asp.net is not entirely accurate, ESPECIALLY when you are in a debug process. While I haven't had the Defibrillator fail for Session.Timeout - 10 seconds, I tested for 2 days with Session.Timeout - 5 seconds and it failed at around 36.5 hours of inactivity, because the asp.net session timed out before it was supposed to on the server. You may want to keep this in mind and perform your own little test. You could even fire up different browsers and let them rip, logging a time of failure and the browser type from the Request in your DB. So far so good on my app, no problems with the way I presented the solution here on Netscape or IE 6.
Achieve by taking great pride in everything you're charged with, be successful by having the initiative to charge yourself, and realize that talent is comprised of aptitude, hard work, and spirit. Hone in on your aptitudes and dedicate your spirit to reach your full potential.
|
|
|
|
|