After frustrating myself to no end with how little this problem is discussed on the web, I took it upon myself to give back to the
community all I've learned:
=========================
Problem
=========================
Trying to use ASP.NET's Session object to implement application security (i.e., redirect to login page if session object is null)
fails when using In Process Session state management. This is especially true in a hosted environment.
Assume your Web.Config file has something like this:
<sessionState mode="InProc" cookieless="false" timeout="40" />
Here's What I've learned if you are using InProcess session state management:
ASP.NET drops the session object randomly for many reasons:
1) Client does not allow cookies (use cookieless option if you can't get users to turn on cookies)
2) On Windows 2003 Server, Worker Processes are pooled and depending on virtual memory available on the server (and other settings),
these processes get restarted, killing the session object. Nothing you can do about it in a hosted environment.
3) The application instance, web server service or the whole server is restarted.
=========================
Solution
=========================
Don't use In-Process session state management. Use either a State Server (the ASP Session State Service) or SQL Server to store
session information (obviously, but there are some nuances, read on).
=========================
Using State Server in a Hosted Environment
=========================
Using the state server requires the NT service "ASP.NET State Service" to be running on your web server (or any server at the hosting
company that you know the name/ip of). I had my ISP turn on this service for my domain.
Use the following Web.Config settings in a hosted environment:
<sessionState mode="StateServer" stateConnectionString="tcpip=127.0.0.1:42424" cookieless="false" timeout="40" />
The loopback IP is important here. You technically could use some other known web server at your hosting company to store session
state information but I don't know how the ISP would like that. Using another machine would mean your session information would
survive a web server restart (but not a restart of the server running the state service).
=========================
Using SQL Server to store session state information *in a hosted environment*
=========================
Here things get complicated. To set this up you neet to run a SQL script to create the neccessary database objects. This script wants
to create a new database (called ASPSTATE) and requires sys admin access to the database server. This obviously won't work in a
hosted environment. You don't want ALL sites that use SQL Server storage to hit the same database for session information. This is a
big bottleneck (see below). To get around that issue, you want the ASP.NET server to use a database of your chosing to store session
state information. But, there is a problem in telling ASP.NET which database to use to store session state information. To configure
SQL Server storage you must use a Web.Config entry like this:
<sessionState mode="SQLServer" cookieless="false" timeout="400" stateNetworkTimeout="15"
sqlConnectionString="Server=sqla19.webcontrolcente r.com;User ID=mylogin;Password=mypass"/>
Notice how no database is specified? ASP.NET hard codes the ASPSTATE database name into the connection string so you can't get ASP to
use your own session state database. If the sqlConnectionString was an actual vanilla connection string specification, you should be
able to add a database attribute to the connection string like this:
<sessionState mode="SQLServer" cookieless="false" timeout="400" stateNetworkTimeout="15"
sqlConnectionString="Server=sqla19.webcontrolcente r.com;database=mysessiondb;User ID=mylogin;Password=mypass"/>
However, doing so will produce the following error:
"The sqlConnectionString attribute cannot contain the connection options 'Database' or 'Initial Catalog'."
There is good news! Microsoft knows about this problem and has a hot fix. See
http://support.microsoft.com/?id=820782 but getting
your ISP to actually implement the hot fix is another issue. Crystaltech was going down the road to implementing the hot fix, but I
solved my problem by using State Server instead of SQL Server to store session information so I aborted trying the SQL Server route.
(By the way, you have to hack up the Script Microsoft provides (see reference link below) to get the database objects all in your own
database instead of the ASPSTATE db the script wants to create.
=========================
Final Thoughts
=========================
Use State Service in a hosted environment. If you really really really need session information to survive a web server reboot, use
the State Server service a machine other than your web server (<sessionState stateConnectionString=tcpip=someknownispserver:424 24).
If both the web server and the server running the ASP Session State service go down, you'd lose the session information. If you
really really really really really need your session state information to survive that scenario, get the hot fix applied to your web
server, hack up the SQL script microsoft supplies (see references link below) and add the database attribute to your connection
string in your Web.Config file (and good luck to you). If someone replies to this wanting the hacked up SQL Script, I'll post it here
as a reply.
References:
http://msdn.microsoft.com/library/de...ssionstate.asp
http://support.microsoft.com/?id=820782