|
Below is a quick summary of the different modes of
session state, followed by a list of FAQ's, compiled from several sources,
including my own "discoveries":
Other Article here : Hijack Session Variables
Basic use of Session in ASP.NET (C#):
STORE:
DataSet ds = GetDataSet(whatever parameters);
Session["mydataset")=ds;
RETRIEVE:
DataSet ds = (DataSet)Session["mydataset"];
Storage location
- InProc - session kept as live objects in web server (aspnet_wp.exe).
Use "cookieless" configuration in web.config to "munge"
the sessionId onto the URL (solves cookie/domain/path RFC problems too!)
- StateServer - session serialized and stored in memory in a separate
process (aspnet_state.exe). State Server can run on another machine
- SQLServer - session serialized and stored in SQL server
Performance
- InProc - Fastest, but the more session data, the more memory is consumed
on the web server, and that can affect performance.
- StateServer - When storing data of basic types (e.g. string, integer,
etc), in one test environment it's 15% slower than InProc. However,
the cost of serialization/deserialization can affect performance if
you're storing lots
of objects. You have to do performance testing for your own scenario.
- SQLServer - When storing data of basic types (e.g. string, integer,
etc), in one test environment it's 25% slower than InProc. Same warning
about serialization as in StateServer.
Performance tips for Out-of-Proc (OOP) modes
If you're using OOP modes (State Server or SQL Server), one of your major
cost is the serialization/deserialization of objects in your session state.
ASP.NET performs the serialization/deserialization of certain "basic"
types using an optimized internal method. "Basic" types include
numeric types of all sizes (e.g. Int, Byte, Decimal, ... etc), String,
DateTime, TimeSpan, Guid, IntPtr and UIntPtr.
If you have a session variable (e.g. an ArrayList object)
that is not one of the "basic" types, ASP.NET will serialize/deserialize
it using the BinaryFormatter, which is relatively slower.
For performance sake it is better to store all session
state data using one of the "basic" types listed above. For
example, if you want to store two things, Name and Address, in session
state, you can either
(a) store them using two String session variables, or
(b) create a class with two String members, and store that class object
in a session
variable. Performance wise, you should go with option (a).
Robustness
- InProc - Session state will be lost if the worker process (aspnet_wp.exe)
recycles, or if the appdomain restarts. It's because session state is
stored in the memory space of an appdomain. For details, see KB324772.
- StateServer - Solve the session state loss problem in InProc mode.
Allows a webfarm to store session on a central server. Single point
of failure at the State Server.
- SQLServer - Similar to StateServer. Moreover, session state data can
survive a SQL server restart, and you can also take advantage of SQL
server failover cluster, after you've followed instructions in KB
311029.
Caveats
InProc - It won't work in web garden mode, because in that mode multiple
aspnet_wp.exe will be running on the same machine. Switch to StateServer
or SQLServer when using web garden. Also Session_End event is supported
only in InProc mode.
StateServer
- - In a web farm, make sure you have the same <machineKey> in
all your web servers. See KB
313091 on how to do it.
- - Also, make sure your objects are serializable. See KB
312112 for details.
- - For session state to be maintained across different web servers
in the web farm, the Application Path of the website (For example \LM\W3SVC\2)
in the IIS Metabase should be identical in all the web servers in the
web farm. See KB
325056 for details
SQLServer
- If you specify integrated security in the connection string (e.g. "trusted_connection=true",
or "integrated security=sspi"), it won't work if you also turn
on impersonation in asp.net. Unfortunately, this bug
isn't reported in KB yet. (There is a QFE fix for it.)
- Also, make sure your objects are serializable. See KB
312112 for details.
- For session state to be maintained across different web servers in the
web farm, the Application Path of the website (For example \LM\W3SVC\2)
in the IIS Metabase should be identical in all the web servers in the
web farm.
See KB
325056 for details.
FAQ's:
Question list:
Q: Session states works on some web servers but not on
others.
Q: Why isn't Session_End fired when I call Session_Abandon?
Q: Why are my Session variables lost frequently when
using InProc mode?
Q: Why does the SessionID remain the same after the Session
times out or abandoned?
Q: Why does the SessionID changes in every request?
Q: Can I share session state between ASP.NET and ASP
pages?
Q: What kinds of object can I store in session state?
Q: How come Response.Redirect and Server.Transfer is
not working in Session_End?
Q: Do I have a valid HttpContext in Session_End?
Q: How do I use session state with web services?
Q: I am writing my own HttpHandler. Why is session state
not working?
Q: I am using a webfarm, and I lost session state when
directed to some web servers.
Q: Why isn't session state availabe in the Application_OnAcquireRequestState
(or other)
Q: If using "cookieless", how can I redirect
from a HTTP page to an HTTPS page?
Q: What isn't Session available in my event handlerin
global.asax?
Q: Does session state have a locking mechanism that serialize
the access to state?
Answers:
Q: Session states works on some web servers but not on
others.
A: Maybe machine name problem. See http://support.microsoft.com/default.aspx?scid=kb;EN-US;q316112
.
Q: Why isn't Session_End fired when I call Session_Abandon?
A: First of all, Session_End event is supported only in InProc mode. In
order for Session_End to be fired, your session state has to exist first.
That means you have to store some data in the session state and has completed
at least one request.
Q: Why are my Session variables lost frequently when
using InProc mode?
A: Probably because of application recycle. See http://support.microsoft.com/default.aspx?scid=kb;en-us;Q316148
Q: Why does the SessionID remain the same after the Session
times out or abandoned?
A:Even though the session state expires after the indicated timeout period,
the session ID lasts as long as the browser session. What this implies
is that the same session ID can represent multiple sessions over time
where the instance of the browser remain the same.
Q: Why does the SessionID changes in every request?
A: This may happen if your application has never stored anything in the
session state. In this case, a new session state (with a new ID) is created
in every request, but is never saved because it contains nothing.
However, there are two exceptions to this same session
ID behavior:
- If the user has used the same browser instance to request another page
that uses the session state, you will get the same session ID every time.
For details, see "Why does the SessionID remain the same after the
Session times out?"
- If the Session_OnStart event is used, ASP.NET will save the session
state even when it is empty.
Q: Can I share session state between ASP.NET and ASP
pages?
A: Yes! Here
is our article on how to do this in either direction using two "intermediate"
pages. And here
is an article on how to do it with SQL Server.
Q: What kinds of object can I store in session state?
A: It depends on which mode you are using:
- If you are using InProc mode, objects stored in session state are actually
live objects, and so you can store whatever object you have created.
- If you are using State Server or SQL Server mode, objects in the session
state will be serialized and deserialized when a request is processed.
So make sure your objects are serializable and their classes must be marked
as so. If not, the session state will not be saved successfully. In v1,
there is a bug which makes the problem happen unnoticed. See this KB for
more info:
http://support.microsoft.com/directory/article.asp?ID=KB;EN-US;q312112
Q: How come Response.Redirect and Server.Transfer is
not working in Session_End?
A: Session_End is fired internally by the server, based on an internal
timer. Thus, there is no HttpRequest associted when that happens. That
is why Response.Redirect or Server.Transferdoes not make sense and will
not work.
Q: Do I have a valid HttpContext in Session_End?
A: No, because this event is not associated with any request.
Q: Will my session state be saved when my page hit an
error?
No. Unless you call Server.ClearError in your exception handler.
Q: How do I use session state with web services?
A: The extra trick needed is on the caller side. You have to save and
store the cookies used by the web service. See the MSDN documentation
on HttpWebClientProtocol.CookieContainer property.
However, please note if you're using proxy object to
call a web service from your page, the web service and your page cannot
share the same session state due to architecture limitation.
This can be done if you call your web service through
redirect.
Q: I am writing my own HttpHandler. Why is session state
not working?
A: Your HttpHandler has to implement the "marker" interface
IRequiresSessionState or IReadOnlySessionState in order to use session
state.
Q: I am using a webfarm, and I lost session state when
directed to some web servers.
A: For session state to be maintained across different web servers in
the web farm, the Application Path of the website (For example \LM\W3SVC\2)
in the IIS Metabase should be identical in all the web servers in the
web farm.
See KB 325056 for details.
Q: Why isn't session state availabe in the Application_OnAcquireRequestState
(or other)
event handler?
A: Session state is available only after the HttpApplication.AcquireRequestState
event is called. For details, see: http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpguide/html/cpconhandlingpublicevents.asp
Q: If using "cookieless", how can I redirect
from a HTTP page to an HTTPS page?
A: Try this:
String originalUrl = "/fxtest3/sub/foo2.aspx";
String modifiedUrl = "https://localhost" + Response.ApplyAppPathModifier(originalUrl);
Response.Redirect(modifiedUrl);
NOTE: Fully qualified URLs in the response.redirect, server.transfer,
and FORM action
tags cannot be used with cookiless sessions. Here is an example of a fully
qualified
URL: http://www.eggheadcafe.com/default.asp More
info here:
Q: What isn't Session available in my event handler in
global.asax?
A: It depends on which event you're handling. Session is available only
after AcquireRequestState event.
Q: Does session state have a locking mechanism
that serialize the access to state?
Session state implements a reader/writer locking mechanism:
- A page (or frame) that has session state write access (e.g. <%@ Page
EnableSessionState="True" %>) will hold a writer lock on
the session until the request finishes.
- A page (or frame) that has session state read access (e.g. <%@ Page
EnableSessionState="ReadOnly" %>) will hold a reader lock
on the session until the request finishes.
- Reader lock will block a writer lock; Reader lock will NOT block reader
lock; Writer lock will block all reader and writer lock.
- That's why if two frames both have session state write access, one frame
has to wait for the other to finish first.
| Peter Bromberg is a C# MVP, MCP, and .NET consultant who has worked in the banking and financial industry for 20 years. He has architected and developed web - based corporate distributed application solutions since 1995, and focuses exclusively on the .NET Platform. Pete's samples at GotDotNet.com have been downloaded over 41,000 times. You can read Peter's UnBlog Here. --><-- NOTE: Post QUESTIONS on FORUMS! |  |
|