I have got an Asp.Net MVC application. This is just an approach so I can't provide code.
Basically what I want to achieve is if the session is over show an alert on whatever page the user is on.
The picture from Azure shows what I want to achieve (but this is farther, I want to start with displaying an alert first).
So is there a function or anything provided by asp.net detecting if the session is over? And secondly how would I display an alert?
Unfortunately, there is no easy answer to this. The reason is that if you were to ping the server to check the session, that action would actually renew the session timeout, unless you configure the service to not access the session - which means you need yet another tracking mechanism. The "fake" way is to set a JavaScript time that equals the session timeout. You would need to reset that timer on any ajax call.
The more involved solution is to use a persistent connection technology like SignalR that notifies a subscriber on session_timeout.
There is no specific function in asp.net that notifies the user that the session is over or going to end. But this functionality is seen nowadays in many websites.
The session is started by the server when a postback request is received. When there is no user action for a specific period of time, session expires. You can use javascript alert to show popup to the user regarding session timeout.
I will suggest 2 ways :
Run a timer in client side and notify the user when it is about to expire. For eg. if your session timeout is 5 min, you can probably
notify the user after 4 min that the session will expire in 1 min if
no action is done.
The second approach is to initiate a post-back request to the controller automatically or when user clicks ok button on an
alert(Your session will expire soon and you will be logged out. Do you
wish to extend the session?)
Related
What is it?
The Heartbeat control that I'm currently developing is a client-side/server-side solution which displays a popup modal to the user after 27 minutes of server session inactivity thereby displaying a countdown of 3 minutes before the session expires and returns the user to the Login page. The modal popup also includes an "Extend time" button and a "Logout" button.
How it works
On the client-side, once the page loads the heartbeat control is initialized and the countdown starts. The heartbeat control has a MaxHealth (milliseconds) and a CriticalHealthRatio (percentage) specifying the session life and when the modal should pop-up respectively.
If the user does nothing during the countdown or alternatively clicks "Logout" then the JavaScript code will redirect the user to the Logout page which clears all sessions and redirects to the Login page.
If the user clicks "Extend time" then an ajax call is made to a web service which simply revitalizes the session on the server-side as well as the client-side's MaxHealth.
Extending control to be multi-tab compatible
At this point, the heartbeat control works on a page by page basis, but does not take into account other tabs that are opened.
Scenario 1: A user logs in and after 15 minutes they open a second tab. Opening another tab will revitalize the session, but the to the first tab the heartbeat is still counting down from that initial MaxHealth, not knowing that the session was in fact reset. Even if the user continues to navigate with the second tab, constantly revitalizing the session, the moment the first tab reaches 0, it will automatically cause the user to be logged out.
Partial Solution
In order to solve the underlying problem of causing the user to be logged out on currently opened tabs which aren't being refreshed, my solution was to implement another web service called GetLastResponse() that retrieves a session which contains a DateTime value of the last server response time.
Therefore on each page request, the server resets the LastReponse session to the current time which is handled in the Global.asax and the HeartBeat control will now countdown from that LastResponse time when the page is loaded on the client-side.
With this new web service which returns the LastResponse time, I can now simply have the heartbeat control on every tab call it every X minutes to determine if the session is any different since the last request thereby synchronizing the Heartbeat controls on all tabs to display the popup at the same time as well as remove the popup on all tabs when the user extends the time on one of the tabs.
But of course, this can't possibly work. The moment I call GetLastResponse() the session is effectively reset in the Global.asax.
Even if I add a condition in the Global.asax which doesn't reset the LastResponse session when a request is made to the GetLastResponse() web service, that doesn't stop the actual session lifetime from being revitalized; it only disassociates the LastResponse DateTime from the actual lifetime of the session.
Questions
I believe the proposed solution will work, however being that the LastResponse
and the actual session lifetime will effectively be different, is
there a better way to go on about this while retaining the core
functionality intended of the Heartbeat control (synchronized
countdown, multi-tab extend time, multi-tab logout)?
Is there a way to designate a web service to not reset the session
lifetime when called but also allows C# to access the session?
Is there a way to request the remaining session lifetime without
revitalizing it?
Currently, when the using is logged in (using the built in forms authentication) and they let their session timeout, they loose all data when they submit a form. How do I make it so that the viewstate data is resubmitted AFTER logging back in? Example, if they were writing an email and it expires, how do I make it send after they relogin instead of loosing all their data? I don't want a solution that extends the session on these pages please.
viewstate will only work in postback-scenarios,you will lose it if you redirect.So i think you use session for your problem.
I agree with Shree..
You could use a timer of sorts and either do a save to the DB, Session, or Cookie w/ the temp date entered so far.
Also, what I have done on some applications, is before the session will time out give the user a warning popup to "Continue" the session. This takes a little more work..
If you want to preserve the state of the form along with all form data, you don't want automatic redirects to the login page, which means that you need some sort of an "in place" authentication. You may consider intercepting the postback, i.e. adding your own handler to the form submit event, and issuing an AJAX callback to check your session state. If the session is valid, just proceed with the postback, otherwise display a login page in a popup or a modal dialog. The user will be able to resubmit the form after logging in.
I think your problem is not on ViewState, simple solution is save the email and action into local storage[HTML5], when user re-logs on, check the previous action and email, then you can submit email automatically. All browsers except IE6/7 already support local storage now.
I have an asp.net web-forms application which is using entity model. When a users logs in, we create a row in user_session table with timein. and when user logs out we update that row and put timeout.
Now problem is, when user closes the browser without logging out, how can we update the row in user_session table?
You can't. There is no way of the server being notified that a browser has been closed by the client. The best you could do is to schedule some job on your SQL Server which runs and updates rows. You may try also subscribing for the Session_End event in Global.asax but be careful because this event might never be triggered if you are using an out-of-process session.
Short answer is: You can't. That's why you shouldn't try to do such a silly thing.
The longer answer is: You have to put up with the delayed response of a session timeout. That could be a significant amount of time. In Global.asax there is an event called Session_End, which you can hook to do what you want.. but it won't show when the user closed their browser. It will only fire when the session has ended, which by default is 20 minutes after the last request. And that's only if it's an in-memory session and the process hasn't crashed.
The better solution is to just run a job every so often to clear the users online table. That solves the problem regardless, but requires more work for your job to figure out what to remove.
In your Global.asax.cs, you can code that in the Session_End event. It will not happen till the session timeout (default 20 minutes), but it will happen. You will likely want to delete any existing records on Application_Start and/or Application_End events (the Application_End event does not execute when the computer or web process crashes so best to use Application_Start) to make sure you start off fresh when the web application loads.
You can use the Event Session_End in the Global.asax.
There may be a delay between the browser closing and the actual session timeout on the server depending on your session settings.
I guess should be scheduled job that will close expired sessions like in AspState.
You can take a look into AspState database stored procedure DeleteExpiredSessions to see what you need to do. This procedure job with name ASPState_Job_DeleteExpiredSessions call each minute to close sessions.
Try the below code.
On the form_load event in every page, write the below code.
Response.AppendHeader("Refresh", "60; URL=../default.aspx")
Default session time out is 20 minutes and I am using "60" seconds for this demo. If there is no activity in this period of time, then it goes back to the default or home page and we send a key to update the database "session key" or any other tag. This way we can possibly know the activity of the user or member.
This worked for me.
I need to maintaing the Session throughout the day? On or before session expires, how do I enforce session throughout the day without giving any session timeout either in IIS or web.config?
Note: Default Session Timeout in IIS – 20 minutes.
Thanks in Advance
The first thing you can do is decouple the session from the process by using a SQL (or other database) session state server that holds the serialized copy of the session data attached to a session id. Then you could use a persistent cookie to pass the session id back and forth. Any session that expires could then be regenerated or reinstated.
Since you're wanting to maintain a session all day (which is innately insecure), we'll assume that most security considerations have already been thrown out. If you're concerned about replay attacks, you could use an HMAC to validate cookie session requests by having the session id, datetime, username (if that's part of your data), maybe IP address in a string followed by a one-way salted hash of this data. This way you rehash the data and compare the hash sent with the request with the generated hash from that data to see if the request is valid.
Forcing the page to be refreshed every 10 minutes or so by javascript. The session timeouts are how long after the last requested page, the session becomes invalid. When you refresh the page every 10 minutes or so, the session is extended for 20 minutes on every refresh.
If you refuse to change the setting in the web.config to a longer value, you could try to force the browser to refresh within a short time of the session timeout (eg at 17 minutes). There might be other nifty ways.
If you can find a way to do without the session, it will save you pain later. Either use a caching strategy (memcached) or look at your resource usage.
eg Do you really need to serialise X into the session?
Use StateServer instead of InProc
This delegates all session handling to a separate database and removes it from the servers process. This will mitigate problems with eating up server resources which then allows you to increase the session timeout to 24 hours.
I believe this is the only viable solution.
Peiter is on the right track -- making fake requests to keep things alive. You definitely don't want to refresh the page, that leads to unwanted updates and such. You don't even need to refresh part of the page. You just need to send an ajax request every X minutes while a user has a browser open to an IHttpHandler that does have session state enabled. This is very, very effective -- we've got one app which is compltely dependent upon sessions for everything that has a 5 minute session timeout. And a session heartbeat that fires every 4.5 minutes. Its been in production upwards of 3 years and we have not lost a session yet. And yes, session state is stored in process in this case -- the use of sessions is so heavy we don't want to wait for them to go out to SQL and back.
PS: protip -- make sure to make the request and response unique; caching kicks in otherwise in certain browsers rendering this trick ineffective.
put a ajax call into a timer, to a method which does nothing "", that's how even the user is on the page but not doing anything means "totally inactive", would not log out, we have implemented the same logic and resolved our problem, our target was 3 to 4 hours, and we did not want to change the value in web.config or using any other way cause of some reasons.
that ajax call would be in a "timer", set the timer time to "any".
I am stuck with count down in ajax, I have a small website where I ask each user 5 question in 1 min time, after they login using asp.net membership provider. I want when the user time is over he/she must be taken to result page and show the result, I am using asp.net ajax timer, but if the user press F5 his time start again and by pressing F5 he can continue his test.
how can I stop that. also is there a easy way to show countdown using Ajax for 60sec
Regards
Arshad
Anything client side is potentially hackable, so you can't effectively maintain a time limit using only client-side technologies. When they begin a test, keep a DateTime in their Session to indicate that a test has been begun. If the submission comes in after more than the time limit has elapsed based on the server time, then tell them to try again cause they cheated.