Seeking to understand something about the HttpSessionState class

C

Chris Austin

A co-worker asked me today what would happen if Session.Add() method
was called multiple times with the same key. My first thought was
that it would throw some sort of duplicate key exception. Thinking
about it some more, the only thing it really does is implement
ICollection and possibly IDictionary so the implementation could be
anything so I looked into a bit further. Documentation didn't say
anything about the Add() methods besides that it adds items to the
collection. But, decompiling it revealed a whole lot more. In fact
the following code is perfectly legal with HttpSessionState class:

Session.Add("a", "b");
Session.Add("a", "c");
Response.Write(Session["a"]);

The output would display "c".

Following it further, the Session.Add() method merely references the
indexer of the internal dictionary variable Microsoft uses called
SessionDictionary. And, SessionDictionary inherits from
NameObjectCollectionBase which is an abstract class found in the
System.Collections.Specialized namespace. The
NameObjectCollectionBase then has a private Hashtable variable to
store the entries. And, Hashtables do throw a duplicate key
exception, so why is the above code valid? Well, that is because of
the BaseSet() method located in NameObjectCollectionBase. It searches
for an existing item, if found it sets the value property and if not
found it adds it to the collection. So, obviously, this behavior is
most likely implemented by design, but why design it this way?
Microsoft even included an internal property called "Dirty" that is
set to true when the above code snippet happens so that makes me think
even more that this is by design. I would also like to find out what
the "Dirty" property is used for in the framework because it is
internal to the assembly.

It would seem to me that they need to rename the Session.Add() method
to something like Session.Set() because the second call to Add()
doesn't really add anything. Instead, it sets the current value for
the already added item.

I tend to think this really gives developers a lot of room to create
bugs. Such as, Developer A codes First.aspx web form. And, Developer
B, codes Second.aspx web form. Each developer decides they need
Session state and by chance both of them give the session state
variable the exact same name like "dropdowndata". And, they write the
code to fill it, if it doesn't already exist but if it exists then
just bind to the existing value in Session state. Then User C hits
the application visiting First.aspx then hits Second.aspx and wonders
why the data is not correct in the drop down. I realize my example
might be extreme but it could easily happen in a large development
project and be one of those nasty little bugs that might be difficult
to find.

Also, why wasn't this documented better in MSDN. It should say, Add()
method used to add a new session variable or update an existing
session variable. Or something like that. If someone has some
enlightenment, I would be very happy to hear it.

Thanks,
Chris

~
Senior Consultant, STATERA (http://www.statera.com)
Microsoft MCP
Web log: http://weblogs.austinspad.com/caustin
 
S

Scott Allen

Hi Chris, see inline:

A co-worker asked me today what would happen if Session.Add() method
was called multiple times with the same key. My first thought was
that it would throw some sort of duplicate key exception. Thinking
about it some more, the only thing it really does is implement
ICollection and possibly IDictionary so the implementation could be
anything so I looked into a bit further. Documentation didn't say
anything about the Add() methods besides that it adds items to the
collection. But, decompiling it revealed a whole lot more. In fact
the following code is perfectly legal with HttpSessionState class:

Session.Add("a", "b");
Session.Add("a", "c");
Response.Write(Session["a"]);

The output would display "c".

Following it further, the Session.Add() method merely references the
indexer of the internal dictionary variable Microsoft uses called
SessionDictionary. And, SessionDictionary inherits from
NameObjectCollectionBase which is an abstract class found in the
System.Collections.Specialized namespace. The
NameObjectCollectionBase then has a private Hashtable variable to
store the entries. And, Hashtables do throw a duplicate key
exception, so why is the above code valid? Well, that is because of
the BaseSet() method located in NameObjectCollectionBase. It searches
for an existing item, if found it sets the value property and if not
found it adds it to the collection. So, obviously, this behavior is
most likely implemented by design, but why design it this way?
Microsoft even included an internal property called "Dirty" that is
set to true when the above code snippet happens so that makes me think
even more that this is by design. I would also like to find out what
the "Dirty" property is used for in the framework because it is
internal to the assembly.

I imagine the dirty bit is useful for out of process session state, as
it allows the runtime to avoid serializing and publishing session
state if no changes were made.

It would seem to me that they need to rename the Session.Add() method
to something like Session.Set() because the second call to Add()
doesn't really add anything. Instead, it sets the current value for
the already added item.

Good point. It is also inconsitent with the behavior of the Cache Add
and Insert methods.
I tend to think this really gives developers a lot of room to create
bugs. Such as, Developer A codes First.aspx web form. And, Developer
B, codes Second.aspx web form. Each developer decides they need
Session state and by chance both of them give the session state
variable the exact same name like "dropdowndata". And, they write the
code to fill it, if it doesn't already exist but if it exists then
just bind to the existing value in Session state. Then User C hits
the application visiting First.aspx then hits Second.aspx and wonders
why the data is not correct in the drop down. I realize my example
might be extreme but it could easily happen in a large development
project and be one of those nasty little bugs that might be difficult
to find.

This is one of the reasons why I believe nobody should ever access the
Session object directly in a non-trivial application. Instead, create
a class to abstract away the source of session data and expose session
data through strongly typed properties. When developer A needs another
session variable they need to add a property to the class and can see
it already exists. This is just one advantage to adding this
additional layer of indirection between the code and the state for a
user.

Also, why wasn't this documented better in MSDN. It should say, Add()
method used to add a new session variable or update an existing
session variable. Or something like that. If someone has some
enlightenment, I would be very happy to hear it.

I don't know why it isn't documented, but it would be good to click on
the feedback link and let MS know what you think of it.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,995
Messages
2,570,226
Members
46,815
Latest member
treekmostly22

Latest Threads

Top