20

.NET's HttpSessionState using an "InProc" store seems to treat session variable key values as case insensitive. For example:

session["foo"] = 1;
session["Foo"] = 2;
Trace.Write(session["foo"].ToString()); // => 2

This behavior appears to be undocumented, so I'm wondering if it is simply a side-effect of the underlying session store mechanism, or intentionally implemented by the class itself. Since C# treats everything else as case-sensitive, it is a bit unnerving for the session to not act the same way. What gives? Does it differ by store type? Is it there for backwards-compatibility with VB?

Mike Atlas
  • 7,972
  • 4
  • 41
  • 61
Alison R.
  • 3,994
  • 25
  • 32

2 Answers2

34

HttpSessionState's keys were made case-insensitive to match the behavior of the classic ASP Session object. This made it easier for developers to port their ASP applications to ASP.NET without introducing subtle case-sensitivity issues.

The same case-insensitive-key behavior is true of the QueryString, Cookies, etc. objects and other similar-to-Classic-ASP built-in objects.

I was on the IIS team at Microsoft when ASP.NET was being designed, and the ASP.NET worked hard to keep ASP.NET code backwards compatible to ASP wherever possible. That doesn't mean ASP.NET had perfect backwards compatibilty, but whenever a decision came up (like this case-sensitivity one), the default answer was to match Classic ASP behavior unless there was a good reason not to.

That said, I agree that Session's case-insensitivity could be better documented.

BTW, the ASP.NET Session collection gets its case behavior from NameObjectCollectionBase which is the base class for all the ASP.NET built-in objects for Cookies, Session State, Application State, Headers, etc. From the docs:

The underlying structure for this class is a hash table.

Each element is a key/value pair.

The capacity of a NameObjectCollectionBase is the number of elements the NameObjectCollectionBase can hold. As elements are added to a NameObjectCollectionBase, the capacity is automatically increased as required through reallocation.

The hash code provider dispenses hash codes for keys in the NameObjectCollectionBase instance. The default hash code provider is the CaseInsensitiveHashCodeProvider.

The comparer determines whether two keys are equal. The default comparer is the CaseInsensitiveComparer.

In .NET Framework version 1.0, this class uses culture-sensitive string comparisons. However, in .NET Framework version 1.1 and later, this class uses CultureInfo..::.InvariantCulture when comparing strings. For more information about how culture affects comparisons and sorting, see Comparing and Sorting Data for a Specific Culture Comparing and Sorting Data for a Specific Cultureand Performing Culture-Insensitive String Operations.

A reasonable follow-up question would be: why was classic ASP designed with case-insensitive keys? The reason for this is that, back in 1996 (or thereabouts) the main language used with ASP was VBScript, so it made sense to cater to the case-insensitive expectations of VB developers.

Justin Grant
  • 41,265
  • 11
  • 110
  • 185
  • Hey Justin, I was trying to see this behavior in .NET reflector - the underlying store is Hashtable - it appears to be a straight get/set pass-through to it. I couldn't find any code that would make it act this way. Can you provide a link (web) or pointer? – Mike Atlas Nov 13 '09 at 20:10
  • 1
    See above. I added more info. Gets and Sets do pass through, but the hash code provider used is case-insensitive, so uppercase and lowercase emit the same hash code. – Justin Grant Nov 13 '09 at 20:13
  • Nope, this is probably set by the base class's (NameObjectCollectionBase) constructor, which SessionStateItemCollection derives from and probably doesn't overload the base class's settings. – Justin Grant Nov 13 '09 at 21:31
  • It is weird. It seems to be case sensitive for me. ASP.NET with VB, framework 4.5.1 ?Session("actionMsg") "FTP Credentials tested succussfully
    Settings Saved successfully" ?Session("ActionMsg") Nothing
    – Sameers Javed Sep 14 '18 at 07:22
0

While C# is case sensitive, these constructs in ASP.NET are case-insensitive because much in HTML is case insensitive (at least in HTML4 -- XHTML is case-sensitive, or course). I believe this is implemented in the class itself. It's independent of whether the state is in-proc or elsewhere.

Bernard Chen
  • 5,727
  • 5
  • 19
  • 27