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.