Нечувствительность к регистру .NET HttpSessionState

HttpSessionState в .NET, использующий хранилище "InProc", похоже, обрабатывает значения ключей переменных сеанса как нечувствительные к регистру. Например:

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

Это поведение кажется недокументированным, поэтому мне интересно, является ли оно просто побочным эффектом базового механизма хранилища сеансов или намеренно реализовано самим классом. Поскольку C# рассматривает все остальное как чувствительное к регистру, то, что сеанс не действует таким же образом, немного расстраивает. Что дает? Отличается ли он в зависимости от типа магазина? Это для обратной совместимости с VB?


person Alison R.    schedule 13.11.2009    source источник


Ответы (2)


Ключи HttpSessionState были сделаны нечувствительными к регистру, чтобы соответствовать поведению классического объекта Session ASP. Это упростило разработчикам перенос их приложений ASP на ASP.NET без возникновения тонких проблем с чувствительностью к регистру.

Такое же поведение ключа без учета регистра верно для объектов QueryString, Cookies и т. д., а также других встроенных объектов, аналогичных классическому ASP.

Я был в команде IIS в Microsoft, когда проектировался ASP.NET, и ASP.NET усердно работал над тем, чтобы по возможности поддерживать обратную совместимость кода ASP.NET с ASP. Это не означает, что у ASP.NET была идеальная обратная совместимость, но всякий раз, когда возникало решение (например, это решение с учетом регистра), ответ по умолчанию состоял в том, чтобы соответствовать классическому поведению ASP, если только не было веской причины не делать этого.

Тем не менее, я согласен с тем, что нечувствительность к регистру Session может быть лучше задокументирована.

Кстати, коллекция сеансов ASP.NET получает свое поведение от NameObjectCollectionBase, который является базовым классом для всех встроенных объектов ASP.NET для файлов cookie, состояния сеанса, состояния приложения, заголовков и т. д. Из документов:

Базовой структурой для этого класса является хеш-таблица.

Каждый элемент представляет собой пару ключ/значение.

Емкость NameObjectCollectionBase — это количество элементов, которые может содержать NameObjectCollectionBase. По мере добавления элементов в NameObjectCollectionBase емкость автоматически увеличивается по мере необходимости за счет перераспределения.

Поставщик хэш-кода распределяет хэш-коды для ключей в экземпляре NameObjectCollectionBase. Поставщиком хэш-кода по умолчанию является CaseInsensitiveHashCodeProvider.

Компаратор определяет, равны ли два ключа. Компаратором по умолчанию является CaseInsensitiveComparer.

В .NET Framework версии 1.0 этот класс использует сравнение строк с учетом языка и региональных параметров. Однако в .NET Framework версии 1.1 и более поздних версиях этот класс использует CultureInfo..::.InvariantCulture при сравнении строк. Дополнительные сведения о том, как язык и региональные параметры влияют на сравнения и сортировку, см. в разделе Сравнение и сортировка данных для определенного языка и региональных параметров Сравнение и сортировка данных для определенного языка и региональных параметров и Выполнение строковых операций, не зависящих от языка и региональных параметров.

Разумным дополнительным вопросом было бы: почему классический ASP был разработан с ключами, нечувствительными к регистру? Причина этого в том, что еще в 1996 году (или около того) основным языком, используемым с ASP, был VBScript, поэтому имело смысл удовлетворить ожидания разработчиков VB без учета регистра.

person Justin Grant    schedule 13.11.2009
comment
Привет, Джастин, я пытался увидеть это поведение в рефлекторе .NET - базовым хранилищем является Hashtable - похоже, это прямой переход к нему. Я не мог найти никакого кода, который заставлял бы это действовать таким образом. Можете ли вы предоставить ссылку (веб) или указатель? - person Mike Atlas; 13.11.2009
comment
См. выше. Я добавил больше информации. Get и Sets проходят, но используемый поставщик хэш-кода нечувствителен к регистру, поэтому верхний и нижний регистры выдают один и тот же хеш-код. - person Justin Grant; 13.11.2009
comment
Нет, это, вероятно, устанавливается конструктором базового класса (NameObjectCollectionBase), из которого происходит SessionStateItemCollection и, вероятно, не перегружает настройки базового класса. - person Justin Grant; 14.11.2009
comment
Это странно. Кажется, это чувствительно к регистру для меня. ASP.NET с VB, framework 4.5.1 ?Session(actionMsg) Учетные данные FTP успешно протестированы ‹br›Настройки успешно сохранены ?Session(ActionMsg) Ничего - person Sameers Javed; 14.09.2018

В то время как C# чувствителен к регистру, эти конструкции в ASP.NET нечувствительны к регистру, поскольку многое в HTML нечувствительно к регистру (по крайней мере, в HTML4 — XHTML, конечно, чувствителен к регистру). Я считаю, что это реализовано в самом классе. Это не зависит от того, находится ли состояние в процессе или в другом месте.

person Bernard Chen    schedule 13.11.2009