why ViewStates instead of Sessions - asp.net

why we use to store data in ViewState? even we have Sessions to do the same job?
Session["Data"]
vs.
ViewState["Data"]
What's the difference?

ViewState applies on the page you are currently in and is stored on the client machine as a hidden field __ViewState, and is encrypted with Base64
While Session is stored on the server and in the scope of the whole user session, it is removed when the user leaves your site and the session expires (by default 20 minutes of inactivity) or you explicitly call Session.Abandon() on logout for example
You have to be careful when using session that it does not contain big objects, as when there are more active sessions, the memoru will be filled up.
And be careful when using big objects with ViewState, as its stored on the clients and goes back and forth with post backs.

**Session**
Session state is maintained in session level.
Session state value is available in all pages within a user session.
-
Session state information stored in server.
-
Session state persist the data of particular user in the server.
This data available till user close the browser or session time
Completes.
-
Session state used to persist the user-specific data on the server
Side
View state
View state is maintained in page level only.
View state of one page is not visible in another page.
View state information stored in client only.
View state persist the values of particular page in the client
(browser) when post back operation done.

Session data is valid only when the current session is active. Usually the server deletes the session after half an hour or so. The ViewState is available, even when the session is expired and you still have the page on screen. That content is serialized in the view, and it is send over the network every time you open the page, or send a form back.
Another thing is this: When you have multiple instances of one page where you want to keep a name for example, you don't want two open instances of the form share the same variables. Instead, you save it in the View, where you have it available for that page, and that page only.

Related

How does ASP.NET server know when a session is terminated?

I understand that Session object is used to store data per session. I did the following experiment:
Open browser and visit an aspx page A, which saves some data to Session object.
Keep the browser open and open another tab to visit an aspx page B which display the session data. And it displayed just as I stored in step 1.
I close the browser and re-visit the page B, the stored data is gone.
From 3, it seems server side somehow detect that I (the client side) has terminated a session. But as I checked with Fiddler, there's no bits sent to the server when I close the browser in step 3.
So how could the ASP.NET application possibly know my step 3 request is for a new Session?
And how is session defined? Do different tabs always belong to the same session?
ADD 1
Although the session data can be displayed in page A and page B, the session IDs displayed in them are different. Why?
Correct
The session id in page A and page B are the same. I am not using InPrivate browsing.
ADD 2
There's indeed a Cookie for session ID:
ASP.NET_SessionId=lmswljirqdjxdfq3mvmbwroy; path=/; domain=localhost; HttpOnly
It was set when a POST request is responded.
So I did another experiment, I close the browser (Fire Fox) and as expected, the Cookie no longer exist. I manually create the cookie in hope of "the faked Cookie could bring back the old session." But Fiddler indicates that the manual cookie didn't get sent at all.
Fiddler says:
This request did not send any cookie data.
So is it possible to fake a cookie and restore an previous session?
And how long does a session live on server?
When the server starts a new session, it generates a new identifier for the session. The session data is stored under this identifier / key in your session provider (can be in-memory, in SQL Server or something else entirely, depending on your configuration - this is usually configured in web.config).
At the same time, the server sends a cookie to your browser (at least in the default setup). This cookie contains the identifier for your session. That is how the server can correlate your requests to your particular session: in every request, your browser will send the session cookie along. The server retrieves the identifier from the cookie and looks up your session data using the identifier.
The session cookie is non-persistent, which means that the cookie will be deleted when the browser is closed. That is why it looks like the session was deleted: the session data still exists on the server, but because the session cookie has been deleted, the browser won't send along a session cookie, so the server will consider this to be the beginning of a new session, create a new session identifier etc. Thus, the server doesn't really know when a session ends, it just knows when a session begins. That is why, in the default SQL Server-backed setup, a scheduled job will purge inactive sessions - otherwise the session data would linger in the database forever.
For more on sessions, using sessions without cookies, session configuration, providers etc., see MSDN.
As to whether sessions are shared between browser tabs: this really comes down to whether cookies are shared between tabs. I think cookies are shared across tabs in all major browsers and I would assume it would be rather confusing if they weren't, but there is nothing preventing someone from creating a browser where cookies aren't shared across tabs.
EDIT 1
If you delete the session cookie, you could in theory recreate your session by recreating the cookie. This is not a security issue per se, because you are recreating data you already have access to. However, if someone else were to recreate your session cookie, that would be a security issue. You can google "ASP.NET session hijacking" if you want to look into this.
EDIT 2
The session basically lives on the server until something purges it. Thus, the lifetime of the session depends on where you store it. If you store it in memory, the session will be deleted when the application is recycled (could be because you recycle the app in IIS or because the server is restarted). If you store it in SQL Server, the session data will live until a job deletes it because it hasn't been accessed for a while (sorry, I don't remember the details, but you can probably google them). If you store your session data in Azure table storage, they will likely never be purged.
Note
Two important details of ASP.NET session state are often overlooked:
When the session is stored outside the process (say, in SQL Server), the data you want to store must be serializable.
To prevent race conditions when accessing the session data, requests accessing the session will be serialized, that is, they will not execute concurrently.
Further details may be found in the MSDN article "Underpinnings of the Session State Implementation in ASP.NET"
This article provides more details about ASP.NET Session (http://msdn.microsoft.com/en-us/library/vstudio/ms178581(v=vs.100).aspx)
The idea is simple.
When you visit a page, a session ID is generated and set as a cookie. A timer is started for that session ID too.
As you keep coming back, the timer is reset. If you wait long enough before requesting another page, the timer will expire and your session will not be valid. At that point a new session will be generated.
To Answer your questions:
If you open multiple tabs, they will "share" the session. Because your browser is sending the session cookie from all those tabs.
However, if you open Firefox and Chrome. These two browsers will not share the session. Since, they don't share cookies.
When you close your browser, your session is still valid. And if you visit a page on the site before the session has expired, you will not get a new session. That is why, it is suggested to always log out. This way the site knows that you're leaving and it will destroy the session on your behalf.
Q: Although the session data can be displayed in page A and page B, the session IDs displayed in them are different.
A: Are you sure? The session ID should be the same for all pages. It will be different if you access page A from one browser and Page B from another browser.
ADD2
It is possible your browser's setting is to destroy cookies on windows close. Please double check that in options it's set to remember history.
Cookies can be forged. If an attacker can get the session ID, they can forge a cookie at their end. I'm not sure if Fiddler allows you to create a cookie manually. You will need to dig through the docs. Or maybe someone else here can answer this questions.

Requirements for modal authentication (as a Login page iFrame or object) without getting redirected to Login page?

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.

.NET custom session state provider: not persisting across pages...sometimes

I've implemented a custom session state provider for Oracle in my application. It seems to run smoothly (without errors!), but I'm having trouble retrieving some Session variables when I redirect to another page. But it doesn't happen all the time.
When the Session starts, I load a User object into Session. It stays there, because when the user gets to the starting page (and is authenticated), the app still recognizes him. It has no problem retrieving the User object from Session.
But if I pass a value into Session on one of my pages inside the app, then redirect to another page in order to utilize that Session variable, the new page retrieves null from the same named Session variable. Using the Visual Studio Watch window, I can actually see its value change from "100" (or whatever) to null. I don't get it.
The session provider seems to be working correctly because as I said, I'm able to persist some variables. Does someone know what the reason might be for Session to "lose" a value? Thanks.
If you are doing a response.redirect in the page, that can cause the thread to abort before the Session is written back to the database.

What is the difference between ViewState,Application and Session of a Page?

Please anyone explain me the difference between ViewState,Application and Session of a Page ?
Quick one liners - if you want more detail, just ask
ViewState is the variable that holds the current state of the page, which is held in a hidden field in the page (used frequently)
ApplicationState is a variable you can store values in during the life off the application (may get cycled periodically, and without your knowledge) (used less-frequently)
Session is the variable you can write to that will persist from the moment they hit your site until they close the browser. (barring any timeouts). (used frequently)
A great article :
How to Choose From Viewstate, Session, Application, Cache, and Cookies
Some good discussion about the difference between Session and Viewstate : Session Vs ViewState
Session state is saved on the server.
Session state is usually cleared after a period of inactivity from the user.
Can be persisted in memory, which makes it a fast solution. Which means state cannot be shared in the Web Farm/Web Garden.
Can be persisted in a Database, useful for Web Farms / Web Gardens.
Is Cleared when the session dies - usually after 20min of inactivity.
ViewState is saved in the page.
The view state is posted on subsequent post back in a hidden field.
Is sent back and forth between the server and client, taking up bandwidth.
Has no expiration date.
Is useful in a Web Farm / Web Garden
SESSION Variables are stored on the server, can hold any type of data including references, they are similar to global variables in a windows application and use HTTP cookies to store a key with which to locate user's session variables.
VIEWSTATE Variables are stored in the browser (not as cookies) but in a hidden field in the browser. Also Viewstate can hold only string data or serializable objects.
When we use view state to design a web application it retains it's state consistently, in it's current position. If we use session then it does not retain it's state, so when we refresh the browser it starts from the initial page.

How would I use AJAX to determine if the user's session has expired and then return them to the login page?

In the following scenaio, how could I make use of AJAX to check if the session if is still active and then return the user to the login page?
The user logs in and starts working
The user disappears for 10 minutes
and the session times out
The user returns to their computer
and is still on the screen they were
on 10 minutes ago
The user submits their work, buts
get returned to the login screen (by
my existing Session state check) and
the changes are not persisted
Ideally what I'm after is some way of checking the session state every 1 minute to see if the user is idle. If they're idle and the session is about to expire, I'd save off their changes temporarily and then then, when the Session does expire, I'd automatically change the page to the login screen before the user returns from being idle.
Is it also possible to do this without using setTimeOut()?
Most if this can be handled server-side.
Whenever there is server-side user activity - page load, ajax call, whatever, set a session variable
Session["last_activty"]=DateTime.Now;
In your AJAX calls and page load (could do this in a master page/nested master page for pages that require authentication), check (pseudocode)
if (DateTime.Now-DateTime.Parse(Session["last_activity"]) > 10 minutes)
Session["logged_in"]=false;
If the page load or webmethod/webservice method determine based on the above that the user has timed out, either
a) redirect to the login page (server side), or
b) return a status code to your ajax caller which will cause a redirect or display of a login dialog.
NOTE: beware of use of real session variables as they tend not to work well/at all in clustered server environments. A better place for this type of thing is in your database.
table Users
.ID
.last_activity datetime
.logged_in - calculated column which returns if GetDate()-LastActivity > 10 minutes.

Resources