we have a vb.net application with send and receive mailing also. Now we have added a session timer of 30 min but the users are complaining that they are facing a problem when they write a long text message or while composing they get busy in something else and when they return back to continue composing message , they are redirected to a session expiry page, and their long text message is gone forever. So I am new to this and I was thinking like , when the user is in compose message the text should be automatically saved to drafts like hotmail.
Any help will be appreciated . Thank you.
There are two basic approaches you can take to this:
The proper "web" way would be to remove the need for session and state from at least this part of the application i.e. set up the application so that its resilient if the session expires and can pick up the necessary user details etc from the post if the session has expired - you can do this with a value stored in viewstate or in a cookie. However this doesn't deal with the problem of saving work in progress.
So the more appropriate solution here will be to investigate AJAX solutions to the problem whereby the page uses client side scripting to transparently "save" (post) the message text back to the server at defined intervals. This has the further advantage of prolonging the session as well.
Of course with the AJAX solution your back end data management becomes more complex too... but it that's manageable (limit it to one draft in progress and remember to clear out the draft on "send" and you should be fine) and you may still want to consider some degree of additional resiliency for loss of session for other reasons.
Related
I have a web app that has some fairly hefty data processing on the backend. A current example workflow is:
User POSTS a form
Server receives form, starts processing
2-4 minutes pass
The server responds
The reason i'm asking this is that initially a web proxy on the user side was killing idle POSTs after 2 minutes. The more I think about it the more this seemed like a reasonable default.
This leaves the question, should I increase the timeout and not fix the problem? Or is this bad practice? It is currently at 2-4 minutes but could easily get longer. Should the application be responding with something rather than just leaving the connection open? If so other than completely redesigning the UI to be asynchronous submit/check back later what options are there?
Generally, if I were to submit a form and it would take that long, I would think something would have gone wrong and attempt to submit again. I think that you should collect the data and give the user some sort of success message. Then create another page that allows them to check on the status of the processing (if the user needs to get the results from that processing).
Problem description
I have an ASP.NET app in which the users have different rights, and are logged in through Facebook. The app includes (among other things) filling out some forms. Some users have access to forms others don't. The forms can sometimes require some searching in books and/or on the internet before being able to submit them.
As such, we're having problems with session time-outs (it seemed), where users would be met with "Not authorized to see this page/form" after doing research somewhere else.
Attempted solutions
I've created a log function that logs the state of a handful of variables on strategic points in the application. I've pinpointed the problem to the fact that the Session variable "UserRole" is null when the problem occurs.
Relogging
The obvious solution is: "Have you tried relogging?" - which should reset the session and allow the user back to the form they want. On logout, I use
Session.Clear();
Session.RemoveAll();
and I create a new session with relevant variables (including UserRole) on login. This doesn't help, though.
Keeping session alive
One way to do it is just increase the standard 20-minute Session length to an arbitrary, higher number (say 2 hours). Although that could be viable during beta (there are only around 5 users right now), it is not a viable solution in the long haul as the server would have to keep the Session objects from many users for longer time, exponentially increasing server demands.
Instead, I created a 'dummy' .ashx handler "RefreshSession.ashx", that can recieve a POST request and return "200" statuscode. I then created a jQuery function in the shared part of the app (that all the pages use) that calls this handler every 10 minutes in order to refresh the session as long as the tab is open in the browser. I've checked the network traffic, and it works as intended, calling the handler even if the window is minimized or the user is viewing another tab. This did not solve the problem either.
A caveat
When one of the users encounter the problem, they call me or my programming partner up. Of course, we go and see if we get the same issue. We all have the same (admin) rights. The 'funny' thing is that we see the exact same error on the same subpage - even if we haven't had any contact with the application for days.
The problem will 'fix itself' (i.e. let users with proper role back on the subpage) after a while, but not even republishing the app to the server will reset it manually.
Therefore, it seems to not be a simpel session error as supposed from the "UserRole" session variable being null after 15-20 minutes of inactivity. It seems to be saved somewhere internally in the server state.
My problem is, that I now have no idea where to look and how to progress. I was hoping that someone here might have an idea for a solution, or at least be able to point me in the right direction? :-)
Thank you all for your time, it is much appreciated.
Based on MaCron's comment to the question, we decided to keep the information in the user's cookies instead of the session variables. Everything seemed to point to us having exactly that issue, and deadlines being deadlines and with me not being able to figure out how to disable the synchronization of worker processes, this seemed to be a feasible and comparatively easy fix.
I am quite new to WebForms and I'm trying to understand the ViewState. AFAIK today, it keeps modifications of the UI over postbacks to the same page. But why does it send the state (= stored modifications) to the client and does not keep it on the server saving CPU cycles and bandwidth?
Am I understanding something completely wrong?
The view state is something intrinsically connected to the view, as the name implies, and trying to manage it separately while maintaining that relation is not something that is easily accomplished.
You would need to store view state per page, so you would still have to send to the client an ID in order to be able to get the correct view state on a postback. Another serious issue is that you send a page to the client but you don't know when or if the client is going to postback that page to the server, so you would need to store view state at least until the session expires.
This could lead to a waste of server resources, as all those view states are being stored for users that may never postback to the server. If you keep your view state slim you'll agree that the best place to store it is to send it with view.
Finally, if you're still not happy with the view state on the client you can override the SavePageStateToPersistenceMedium and LoadPageStateFromPersistenceMedium methods of the page and save it to another medium. I've already heard many people complain about view state on the client, and most time I just tell them to go ahead and implement persistence to another medium on the server... however, I believe no one ever did, probably because it's complicated and you'll end up with a solution that's not that clean.
ViewState is used when a page performs a post back in order to restore the control tree of the page to what is was when the page was last rendered.
This allows for instance a GridView control to keep it's state (what is shown in the GridView) on post back without having to rebind it to the same data.
The reason why the ViewState per default is serialized and sent to the client is (I guess) that it's the easiest way to get it back when the client performs a post back.
What if for instance a user has several browser windows open with the same page loaded and you have the viewstate stored in the Session? Assigning the correct viewstate to the different windows in such a case can of course be solved, but having the client explicitly post it seems to be the easiest way.
That said, it is possible to have the viewstate stored in the Session. See for instance this link.
Other possibilities are available by implementing your own System.Web.UI.PageStatePersister.
There might be a few questions here, but one major question... what should be implemented if we make a modal authentication work? Let me try to explain..
Current environment:
ASP.NET w/ .NET 4.0 w/ forms authentication
Our customers that use our lab software have to be extra cautious of another user taking control of their computer, so we can't implement persistent timeouts (I think the last time I read, you can keep extending the timeout as long as there's something happening in ASP.NET, right?). Even though we have password authentication throughout our laboratory rich client application, we still don't want a random person walking by some employees desk to see what they're working on and have something get compromised. So I've been thinking about this for quite some time and tonight I had an epiphany. What if we were to have the Login page pop up in a modal dialog within an iframe (or object tag) in a modal div that's inside of our masterpage? How can we keep their session from ever expiring, but require them to login after the session has timed out? Is there anything else you can think of that will be required if we were to implement something like this for it to work? Note, we have session variables within the software that cannot be reset if this occurs. How can we keep them persistent but still make this work? The main thing is I want to avoid having them be redirected to the Login page. This is rather annoying for end-users. By law, they need to have the timeout set to 2 minutes, so I thought this would be really cool if I can make it work. Any other things we need to watch out for??
I can't but think that it's scary to use asp.net session, especially with forms-auth - because, the user gets 2 cookies: session and auth. Imagine what would happen if, somehow, authenticated user A would steal session cookie from authenticated user B: it would result in user A having access to all data that user B owns (unless your code checks whether user-id from auth-cookie owns the session object. In other words, I would suggest to get rid of the session, or at least add user-id value to session object and make sure you check that user id from the auth-cookie matches that within application_authorize event, maybe. You didn't ask for this info, but I think it's appropriate, regardless.
Since the session and the auth cookies have little to do with each other, as far as browser is concerned, and your goal is to keep the session alive, while auth-cookie should expire, then, you can maybe solve that by writing a piece of JS (hint: window.setInterval) that regularly pings some ANONYMOUS url (aspx page) at your server (make sure you add a random query to those requests; e.g. new Date().getTime()). The anon aspx page would need to read (do not write!) some value from the session (or simply retrieve the session object) - just to keep it alive (maybe this isn't really necessary; do experiment), but the browser WILL be sending asp.net session cookie with these requests, so you can keep the session object alive forever this way.
On the other side, your auth-cookie will expire. However you MUST set web.config settings (authentication > forms) to NOT use sliding expiration (as that mode essentially extends the validity/expiration of the auth cookie for another whatever-the-timeout-is minutes). Then, you can be sure that, after the cookie expires (e.g. after 20 min), when the user clicks on a protected link (well, a link that links to protected page; non-anon page), then they will land on login page. I know that you don't want this. So, to solve that, add another (independent) piece of javascript (hint: window.setTimeout([code], 2 * 60 * 1000) // to fire after 2 min since the page-load) to launch the login dialog. The login dialog would extend the auth-cookie by posting the uid/pwd and letting asp.net validate it.
Another thing: if you have ajax going on on that page, you must think of resetting these js timeouts back to 0 (or cancelling then reinitializing interval and timeout events). In other words, you can't start measuring inactivity since the page load - you have to reset the inactivity counter on every user's action (click; or at least on every ajax callback).
What I'm suggesting here may be an overkill. I would probably try to solve this differently. I would try to eliminate in-process session from the picture, and reload it based on auth-cookie's user-id from whereever user data is, every time it's needed (or once per request). I don't know why it's so important to keep the session object hanging in memory, even when the user is logged out (how do you know they won't leave for a week; keeping sessions alive would be killing your server if you had a large number of users). Maybe store the session data in database or some other caching mechanism on the network (e.g. memcached) and retrieve it once per request (e.g. in application_authorize), store it in request.context (to eliminate retrieving it multiple times from multiple places). Then, your auth-cookie will expire, and use JS to popup the login dialog a few min before the auth cookie expired (to avoid the gap where the user will land on login page if they click on a link, if you care about that even).
I hope these ideas help.
Weird problem here, we're running a few mixed environment web applications, that use Windows or Forms authentication depending on where the user comes from.
I'm curious how everyone else might be handling expired sessions to avoid the errors you would get from someone leaving an idle session open for too long and then trying to resume work, mainly looking for best practices on the subject.
Any suggestions or opinions would be greatly appreciated.
Thanks,
I'm not sure how your authentication method affects session timeouts, the mechanism they use to get in shouldn't affect how long they can stay in.
Generally speaking, if someone does have an expired session, you can add code to check to see if their session is active. If it isn't, just redirect them to a login page, or display some other friendly text.
Basically something like:
if (Session.IsNewSession)
Response.Redirect("login.aspx");
Don't store unnecessary information on the session.
If you are storing something you can reload, have the appropriate code that will reload it if it wasn't found in the session
Consider if some processes are meant to be handled in long periods of time, in which case save intermediate info to the database.
If the user is doing a process that uses the session, and the data is missing, take them to step 1 (not much you can do about it, if you don't have the info elsewhere).