What should I be aware of when using session variables? - asp.net

I'm planning to use some session variables on an intranet ASP/VB.NET page, and want to make sure that I'm not missing out on anything important I should know, or that I have my information mixed up. So here's what I (think) I know about session variables.
They:
are stored on the server, so if I have a lot of users then they'll each be using some more memory which could lead to a slowdown.
are inaccessible by the user unless I expose access.
hang around/persist across user requests (i.e. each time the user makes a request from the page the data will still be there - until it times out). This also means that I need to make sure that the variable doens't have "left over" data in it.
Is there anything that I've got totally wrong, or anything I'm missing? I'd prefer not to get bitten by a bug down the road because I think I understand what's going on.
Thanks!

Unless it's a trivial app, I'd advise (out of proc) using StateServer or SQL server for session, with a preference to SQL. To configure just make a small change to web.config and run a sql script (see http://msdn.microsoft.com/en-us/library/ms972429.aspx).
It will save you a lot of headaches with IIS recycles and allow you to scale your app to multiple load balanced servers if the need should ever arise.

Related

ASP.NET: Session state has created a session id, but cannot save it because the response was already flushed by the application

in an old ASP.NET Web Forms application, developed in Visual Studio 2010,
suddenly does not run anymore, and in the log file appears this message:
Session state has created a session id,
but cannot save it because the response was already flushed by the application.
No new deployment has been made, and no code modifications take place.
Until now I didn't find any solution to this.
What I have to check?
I state that the source code is no longer available, and therefore it would be very difficult to change the code and proceed with a new deployment.
Thanks in advance.
Luis
This would suggest that someone might be hitting the site and jumping directly to some URL (and thus code) that say does some response redirect to another page or some such.
Remember, when code behind runs, and say re-directs to another page, in most cases the running code for the current page is terminated, and that is normal behaviors.
However, the idea that you going to debug code and debug a web site when you don't have the code to debug? Gee, I don't see how that's going to work at all. As noted, if this just started, then it sounds like incoming requests are to pages that don't expect to be hit "first", but some pages that expect to be ONLY called from other pages in the site when some session() and imporant values are setup BEFORE such pages are to be hit.
It also not clear if the site is using sql based sessions, or just in-memory sessions. In memory can (and is) faster, but it also not particually relaible. Now, if you deployed to a new web server or new hosting, then often session errrors can now start to appear, and this is due to the MASSIVE HUGE LARGE DIFFERENT of using cloud based hosting vs that of older hosting soluions that run on a single server.
Clould computing is real utility computing, and thus when you host a web site on such systems, then in-memory session() cannot be used anymore, since multiple servers can and will be used to "dish out" web pages. Since more then one server might be used, then obvisouly in-memory sesson() can't work, since a few web pages might be served out by one server, and then a few more pages might be served out by another server. And using shared memory for a session is limited to ONE server, since multiplel servers don't and can't transfer their memory to other servers.
So, this suggests that you want to be sure that sql server based sessions are being used here - and for any kind of server farm, or any kind of system that does load balances between more then one server, then of course you HAVE to use sql server based sessions, since in memory can't work in that kind of environment.
The error could also be due to excessive server loads - often the session database is "locked" for a short period of time, and can thus often be a bottleneck. So, for say years you might not see a issue, but then as load and use of the web site increases, then this can become noticed where as in the past it was not. I suppose the database used for storing sessions could be checked, or looked at, since as you note, you don't have the ability to test + debug the code. I would REALLY but REALLY work towards solving and fixing this lack of source code for the web site, since without that, you have really no means to manage, maintain, and fix issues for that web site.
But, abrupt terminations of web pages? As noted, this could be a error triggered in code, and thus the page never finished what it was supposed to do. And as noted, perhaps a page that expects some session() values but does not have them as explained above could be the problem. It not clear if your errors also shows what URL this was occurring for.
While nothing seems to have changed - something obviously did.
Ultimate, you need to get that source code, or deal with the people + vendor that supplies the code for that site. If you don't have a vendor, and you don't have source code, you quite much attempting to work on a car that you cant even open the hood to check what's going on under that hood.
so, one suggestion here? Someone is hitting a page that expected some value(s) in session to exist. Often the simple solution is to shove ANY simple or dummy value into session so session REALLY does get created, and then when the page attempts to save the session(), there is one to save!!!
In other words, this error often occurs when session is attempted to be saved, but no sesison exists. For such pages, as noted, a simple tiny small code change of doing this session("zoozoo") = "my useless text" will fix this error. So, it sounds like session is being lost.
As noted, a error on a web page can also trigger a app-pool re-start. If app-pool re-starts, then session is lost (in memory session). Now, with session being lost, then any page that decides to terminate early AND ALSO having used session() will trigger this error.
So, this sounds like app-pool is being re-started and session is being lost. (you can google why app-pool restarts and for the many reasons). However, critical to this issue would be are you using sql based sessions, or in-memory (server) sessions? So, this sounds like some code is triggering a error, and with a error triggered, app-pool re-starts. And with app-pool being restarted, then in-memory session is blown away. And now, without ANY session at all, then attempts to save the session trigger the exact error message you see. (and this is why shoving a dummy value into the session allows and can fix some pages - since you can't save a "nothing" session, and if you do, then you get that exact error message.
but, as noted, you can't make these simple changes to code anyway, right?
But, first on this issue - are you using memory based sessions or not? And that feature can be setup and configured in IIS, and without changes to the code base. So, one quick fix might be to turn on sql server based sessions. It will cost web site performance (10%), but the increased reliability is more then worth the performance hit.
Another area to look at? Are AJAX calls being made to a page, and again without any previous session having been created? So, once again, we down to a change in end user behaviors, and possible those hitting a page first before having logged in, or done other things - and again one would see this error crop up.

What's the problem with Sessions in ASP .Net

I keep hearing that it's bad practise to store large object collections / anything in the session. Often during conversation it's quickly followed by: 'Just turn sessions off'
So what is the general problem with sessions? I use them a fair bit and since they 'real' session is stored behind a strongly typed container I don't really see the issue.
There is nothing wrong with session - you just need to be mindful of its limitations. To say "just turn off session" is throwing the baby out with the bathwater.
There is a huge difference between storing BIG objects and small objects in a session
The session will stay alive on a server untill it expiers, and that means those big objects pollute your available memory. If you do that with a server under load, or a server that runs many application pools, then this can cause trouble.
You dont need cookies to have a session, since ASP cal also encode that information in the urls. Also you can configure the session store to run out of process, or even to store the information inside a SQL Server (reducing the memory load on the server, and enabeling sessions across a farm)
So basically: Objects are ok - Big objects not
Here's my take -- sessions are not bad but sometimes they are overused. It can also be harder to understand a web application's flow when it relies on a lot of sessions so of course you should be careful not to get carried away.
However, you should feel free to use them anytime you need to store temporary data to be made accessible across multiple pages. In no other situation should they be used. But that situation is one for which sessions were specifically designed.
Now, if you're worried about memory consumption on the server, that's not necessarily a reason to avoid sessions. But it may be more of a reason to avoid the InProc session provider. In fact I'm not a fan of InProc sessions as they tend to expire prematurely after a certain number of recompiles in your application.
What I actually prefer and nearly always use are SQL Server sessions. They'll be slightly slower, but the benefits are numerous. They'll persist even if the server is rebooted and that makes them a very reliable choice. And of course since they're stored in the SQL file system instead of in memory, they won't make such a big hit on memory.
This article on MSDN talks about the various session providers and also explains how to configure SQL to handle your sessions. If you don't have SQL, just know that even the free SQL Server Express 2008 can be configured as your session provider.
I had thought that it largely depends on the traffic to your web site. If you are running something like amazon.com, trying to store the user's shopping cart in a session would take huge amounts of IIS allocated memory, bringing down your web server. For smaller web sites, session variables are fine to use in moderation.
Storing large objects in Session is bad, yes, but "large" is relative.
Basically, storing an object in session will keep it in memory until the session expires, so if you have a site with a high user count all storing mega-objects in their session, you'll kill your server pretty quickly.
With that being said, an argument could be made for the idea that if you have objects that are 5k+ in memory and have enough users to actually cap out a server then you can probably afford more hardware anyway.
There are also topics like server clustering and session integrity between boxes in the cluster. Some frameworks handle this, I don't know if .NET does or not.
There are two things to be careful of:
Memory consumption: if you store large data objects in session and you have many user you may well run out of memory or at the very least triggering many early recycling of your application
This is only a problem if you have multiple web servers (web farm): the session has to be stored externally (not in process) in a SQL server or a windows service so that it is accessible from different machines. This can be quite slow at times.
Session requires the user to have cookies turned on
If you're working in a web farm, you'll run into trouble.
I guess these reasons don't have anything to do with storing large objects in session, just in using sessions at all.
2 major issues come to mind...
1) Persistence of sessions across servers when you start scaling your website
2) Memory usage explosion from storing UI objects in session state
The more serious issue is the tendency to store objects in session. When you store something as innocuous as a Label from a page on your page, you get LOTS of unwanted object attributes as well. You probably just wanted the text of that label stored in your session, but along with it, you get references to the page itself...and all of a sudden, you have a massive usage of memory to store the page, its view state, and lots of unwanted attributes in memory on your server.
Check out this link about storing UI elements in session
You may want to check out this question as well.
This is an old thread although.
But I have an experience for a session problem. I would like to share it.
There is a simple flow.
One .aspx validate a client, and read a bill-html from a file (for this client), then save this html(about 2MB) in a session variable.
This .aspx will auto redirect to next .aspx, the next .aspx retrieves this html from session. Then show it to the client.
It works fine in most cases. But some clients encountered a problem: The bill he saw is not his bill, but others.
We used sniffers tools to intercept the network package.
And we saw a strange situation:
Our IIS has definitely sent the SessionID(eg: 1111111) to the client, But when the client redirects to next page and tries to access session. The SessionID(eg: 11112222) that this client brings is different.
We think that the browser of that client does not accept the SessionID.
And finally, we abandon the use of Session, and solved this problem.

ASP.NET Masters: What are the advantages / disadvantages of using Session variables?

I've done a search on this subject already, and have found the same data over and over-- a review of the three different types of sessions. (InProc, Sql, StateServer) However, my question is of a different nature.
Specifically, what is the advantages/disadvantages of using the built in .NET session in the first place?
Here is why I am asking: A fellow .NET developer has told me to NEVER use the built in Microsoft Session. Not at all. Not even create a custom Session State Provider. His reasoning for this is the following--that if you have the Session turned on in IIS it makes all of your requests happen synchronously. He says that enabling session degrades the performance of a web server.
His solution to this is to create a session yourself-- a class that stores all values you need and is serialized in and out of the database. He advises that you store the unique ID to reference this in a cookie or a querystring variable. In our environment, using a DB to store the sessions is a requirement because all the pages we make are on web farms, and we use Oracle-- so I agree with that part.
Does using the built in Session degrade performance more than a home-built Session? Are there any security concerns with this?
So to sum it all up, what are the advantages/disadvantages?
Thanks to all who answer!
My experience has been that the session is a good means of managing state when you use it appropriately. However, often times it's misused, causing the "never ever use the session" sentiment shared by many developers.
I and many other developers have ran into major performance issues when we mistakenly used the session to store large amounts of data from a database, so as to "save a trip." This is bad. Storing 2000 user records per session will bring the web server to its knees when more than a couple of users use the application. Session should not be used as a database cache.
Storing an integer, however, per session is perfectly acceptable. Small amounts of data representing how the current user is using your application (think shopping cart) is a good use of session state.
To me, it's really all about managing state. If done correctly, then session can be one of many good ways to manage state. It should be decided in the beginning on how to manage state though. Most often times, we've run into trouble when someone decides to just "throw something in the session".
I found this article to be really helpful when using out-of-process modes, and it contains some tips that I would have never thought of on my own. For example, rather than marking a class as serializable, storing its primitive datatype members in separate session variables, and then recreating the object can improve performance.
Firstly, you colleague is implementing his own DB backed session management system, I do not see what advantage this has over using built in session state stored on a database (MS SQL is the default, there is no reason not to use Oracle instead).
Is his solution better than the built in one? Unlikely. It's way more work for you for a start. Here's a simple illustration of why. Let's say you use cookies to store your ID, how do you cope with a user who turns off cookies? If you are using ASP.Net's session state there's no problem as it will fall back to using the query string. With your colleagues idea you have to roll your own.
There is a very valid question as to whether you shold have session state at all. If you can design your application not to need any session state at all you will have a much easier time scaling and testing. Obviously you may have application state which needs to live beyond a session anyway (simple case beign user names and passwords), but you have to store these data anyway regardless of whether you have session state.
The MS implementation of Session State is not evil in and of itself... it is how some developers use it. As mentioned above, using the built-in session state provider means that you don't have to reinvent the security, aging, and concurrency issues. Just don't start jamming lots of garbage in the session because you're too lazy to figure out a better way to manage state and page transitions. Session doesn't scale really well... if each user on your site stuffs a bunch of objects in the session, and those objects take up a tiny bit of the finite memory available to your app, you'll run into problems sooner than later as your app grows in popularity. Use session in the manner for which it was designed: a token to represent that a user is still "using" your site. When you start to venture beyond that, either because of ignorance or laziness, you're bound to get burned.
You should be judicious in your use of Session, since multiple requests to the same Session object will usually be queued: see "Concurrent requests and session state" http://msdn.microsoft.com/en-us/library/ms178581.aspx.
Note that you can set EnableSessionState to ReadOnly to allow concurrent read access to session state.
This queuing is a good thing, as it means developers can use Session without being concerned about synchronization.
I would not agree with your colleague's recommendation to "never" use Session and I certainly wouldn't consider rolling my own.
First, a browser will only make two requests, to a given hostname, at a given time. For the most part these requests are for static content (JS files, CSS, etc). So, the serializing of requests to dynamic content aren't nearly the issue that one might think. Also, I think this may be confused with Classic ASP, where pages that use Session are definitely serialized, I don't believe this is the case with ASP.Net.
With ASP.Net session state (SQL mode, state server, or custom) you have an implementation that is standard, and consistent throughout an application. If you don't need to share session information this is your best bet. If you need to share information with other application environments (php, swing/java, classic asp, etc.) it may be worth considering.
Another advantage/disadvantage is that there has been a lot of developer focus on the built-in methodology for sessions with regards to performance, and design over rolling your own, even with a different provider.
Are there any security concerns with this?
If you roll your own you'll have to handle Session Fixation and Hijacking attacks, whereas using the built-in Session I think they are handled for you (but I could be wrong).
the home made session as you have described is doing nothing different "SQL" state of .Net sessions and in my experience i dont think session degrades your performance in anyway. building your own session manager will require putting in several other plumbing tasks along - security, flushing it out, etc.
the advantage with in-built sessions is its easy to use with all this plumbing already been taken care of. with "SQL" mode you can persist the session data in database thus allowing you to run your app on web-farms without any issues.
we designed a b2b ecommerce app for fortune 57 company which processes over 100k transactions a day and used sessions [SQL mode] quite extensively without any problems whatsover at all.
Correct me if I am wrong:
The primary advantage of storing Session state in a db, e.g., SQL Server, is that you are not consuming memory resources, but instead storing it to disk in a db.
The disadvantage is that you take an IO hit to retrieve this info from the database each time you need it (or maybe SQL Sever even does some magic caching of the data for you based on recently executed queries?)
In any event, this the price an IO to retrieve the session info from a db per trip to the web server seems like a safer strategy for sites that encounter a lot of traffic.

Caching database data in session - getting the balance right

If you cache data from your database in ASP.NET session then you will speed up subsequent requests for that data (note: depending on the serialization/deserialization cost of the data concerned), at the expense of memory load in IIS.
(OK, this is probably a simplification of the reality of the situation - feel free to correct or refine my statement above)
Do you use any rules (simple rules of thumb or otherwise) to decide when it is appropriate to cache in Session?
Update
Can use of Session for storing read-only data without very well thought out rationale simply be considered another case of Premature Optimization? (and therefore, bad)
Keep in mind with caching in session if you use the InProc mode, you are limiting your scalability unless your code will go back to the DB when the session is empty. You will be forced to use a single server or pin your user to a particular server.
If your using Session State Server this doesn't apply, and if your using SQL to store session state then using session for caching is pointless.
Edit
Any advice around this topic is subject to your specific environment. As you stated, a very complex sql query might benefit from being cached even when using SQL Session State. I think the most important thing is first make your application perform the functions and achieve the business requirements. Then go back and test and optimize the application to handle the load you expect.
Edit 2
Based on your update no I don't think this is true. In one of my ASP.Net Applications I am using session state to store a complex object model that the user is then manipulating and modifying. We are using AJAX and so we have a lot of short communication to server as user updates the object. Keeping the object in session was done as a convience. The object performs a lot of customized calculations to generate different data points, so doing this on the server was ideal as opposed to trying to replicate the code in the servr and in javascript. Also keeping it in session lets us have an undo function very easily.
And Yes I know we sacrificed scalability, but I welcome the day when I sit down with my boss and explain we have a problem because we have too many users (And I know he would too).
So I think the question is why are you storing data in session is it for convience and to provide access to transient data while the user is logged in? That is different then storing it there for caching. One thing to remeber with caching is how are you going to flush the cache? How do you invalidate it? I don't session state is built to handle this.
Edit 3
Back at it well read only data, user specific, expensive to load from DB, go ahead cache it in session. You can write your code so if it's not in session then you hit the DB. Have a nice little helper class that does this hidding it from your web app that your even using session and you should be good. Nice thing about hidding where you store it from your web if you find you run into issues you only have one place to change it.
Given that it is very hard to guarantee that data in a session gets cleared up in a reasonable time frame, I would be very wary of cashing anything more than the odd integer there. When you get up to a large scale you will either hit memory issues or have all your users get session time out errors. Remember that unlike the Cache object sessions don't get killed off when memory is low.
Also as Josh says if you go to multiple servers and need to use either a Database or Session State Server your session object will need to be serialisable. In this case the cost of serialising and de serialising is likely to be worse than the cost of a well optimized query.

What to put in a session variable

I recently came across a ASP 1.1 web application that put a whole heap of stuff in the session variable - including all the DB data objects and even the DB connection object. It ends up being huge. When the web session times out (four hours after the user has finished using the application) sometimes their database transactions get rolled back. I'm assuming this is because the DB connection is not being closed properly when IIS kills the session.
Anyway, my question is what should be in the session variable? Clearly some things need to be in there. The user selects which plan they want to edit on the main screen, so the plan id goes into the session variable. Is it better to try and reduce the load on the DB by storing all the details about the user (and their manager etc.) and the plan they are editing in the session variable or should I try to minimise the stuff in the session variable and query the DB for everything I need in the Page_Load event?
This is pretty hard to answer because it's so application-specific, but here are a few guidelines I use:
Put as little as possible in the session.
User-specific selections that should only last during a given visit are a good choice
often, variables that need to be accessible to multiple pages throughout the user's visit to your site (to avoid passing them from page to page) are also good to put in the session.
From what little you've said about your application, I'd probably select your data from the db and try to find ways to minimize the impact of those queries instead of loading down the session.
Do not put database connection information in the session.
As far as caching, I'd avoid using the session for caching if possible -- you'll run into issues where someone else changes the data a user is using, plus you can't share the cached data between users. Use the ASP.NET Cache, or some other caching utility (like Memcached or Velocity).
As far as what should go in the session, anything that applies to all browser windows a user has open to your site (login, security settings, etc.) should be in the session. Things like what object is being viewed/edited should really be GET/POST variables passed around between the screens so a user can use multiple browser windows to work with your application (unless you'd like to prevent that).
DO NOT put UI objects in session.
beyond that, i'd say it varies. too much in session can slow you down if you aren't using the in process session because you are going to be serializing a lot + the speed of the provider. Cache and Session should be used sparingly and carefully. Don't just put in session because you can or is convenient. Sit down and analyze if it makes sense.
Ideally, the session in ASP should store the least amount of data that you can get away with. Storing a reference to any object that is holding system resources open (particularly a database connection) is a definite scalability killer. Also, storing uncommitted data in a session variable is just a bad idea in most cases. Overall it sounds like the current implementation is abusively using session objects to try and simulate a stateful application in a supposedly stateless environment.
Although it is much maligned, the ASP.NET model of managing state automatically through hidden fields should really eliminate the majority of the need to keep anything in session variables.
My rule of thumb is that the more scalable (in terms of users/hits) that the app needs to be, the less you can get away with using session state. There is, however, a trade-off. For web applications where the user is repeatedly accessing the same data and typically has a fairly long session per use of the site, some caching (if necessary in session objects) can actually help scalability by reducing the load on the DB server. The idea here is that it is much cheaper and less complex to farm the presentation layer than the back-end DB. Of course, with all things, this advice should be taken in moderation and doesn't apply in all situations, but for a fairly simple in-house CRUD app, it should serve you well.
A very similar question was asked regarding PHP sessions earlier. Basically, Sessions are a great place to store user-specific data that you need to access across several page loads. Sessions are NOT a great place to store database connection references; you'd be better to use some sort of connection pooling software or open/close your connection on each page load. As far as caching data in the session, this depends on how session data is being stored, how much security you need, and whether or not the data is specific to the user. A better bet would be to use something else for caching data.
storing navigation cues in sessions is tricky. The same user can have multiple windows open and then changes get propagated in a confusing manner. DB connections should definitely not be stored. ASP.NET maintains the connection pool for you, no need to resort to your own sorcery. If you need to cache stuff for short periods and the data set size is relatively small, look into ViewState as a possible option (at the cost of loading more bulk onto the page size)
A: Data that is only relative to one user. IE: a username, a user ID. At most an object representing a user. Sometimes URL-relative data (like where to take somebody) or an error message stack are useful to push into the session.
If you want to share stuff potentially between different users, use the Application store or the Cache. They're far superior.
Stephen,
Do you work for a company that starts with "I", that has a website that starts with "BC"? That sounds exactly like what I did when I first started developing in .net (and was young and stupid) -- I crammed everything I could think of in session and application. Needless to say, that was double-plus ungood.
In general, eschew session as much as possible. Certainly, non-serializable objects shouldn't be stored there (database connections and such), but even big, serializable objects shouldn't be either. You just don't want the overhead.
I would always keep very little information in session. Sessions use server memory resources which is expensive. Saving too many values in session increases the load on server and eventualy the performance of the site will go down. When you use load balance servers, usage of session can run into problems. So what I do is use minimal or no sessions, use cookies if the information is not very critical, use hidden fields more and database sessions.

Resources