Що робити, якщо поточний сеанс ASP.NET недійсний?


125

У своєму веб-додатку я роблю щось подібне для читання змінних сеансу:

if (HttpContext.Current.Session != null &&  HttpContext.Current.Session["MyVariable"] != null)
{
    string myVariable= (string)HttpContext.Current.Session["MyVariable"];
}

Я розумію, чому важливо перевірити, чому HttpContext.Current.Session ["MyVariable"] є нульовим (змінна, можливо, ще не зберігалася в сесії або сесія була скинута з різних причин), але чому мені потрібно перевірити якщо HttpContext.Current.Sessionнуль?

Я розумію, що сеанс створюється автоматично ASP.NET, тому HttpContext.Current.Session ніколи не повинен бути нульовим. Чи правильне це припущення? Якщо він може бути нульовим, чи означає це, що я також повинен перевірити його, перш ніж щось зберігати в ньому:

if (HttpContext.Current.Session != null)
{
    HttpContext.Current.Session["MyVariable"]="Test";
}
else
{
    // What should be done in this case (if session is null)?
    // Is it possible to force the session to be created if it doesn't exist?
}

ASP.NET WebApi матиме різну поведінку, ви можете перевірити це на
доступі

Відповіді:


158

Так, об’єкт Session може бути недійсним, але лише за певних обставин, до яких ви рідко стикаєтеся:

Якщо у вас є лише код на сторінках, ви не натрапите на це. Більшість мого коду ASP .NET використовує сесію без повторної перевірки нуля. Однак варто над цим подумати, якщо ви розробляєте IHttpModule або іншим чином вписуєтеся в більш дрібні подробиці ASP .NET.

Редагувати

У відповідь на коментар: Доступний стан сеансу чи ні, залежить від того, чи подія AcquireRequestState виконується для запиту. Тут працює його модуль стану сеансу, читаючи файли cookie сесії та знаходячи для вас відповідний набір змінних сеансу.

AcquireRequestState запускається до того, як контроль буде передано вашій сторінці. Тож якщо ви закликаєте зі своєї сторінки інші функціональні можливості, включаючи статичні класи, вам слід добре.

Якщо у вас є деякі класи, які виконують логіку ініціалізації під час запуску, наприклад, на події Application_Start або за допомогою статичного конструктора, стан сеансу може бути недоступним. Все зводиться до того, чи є поточний запит і чи запущено AcquireRequestState.

Крім того, якщо у клієнта відключені файли cookie, об’єкт Session все ще буде доступний - але при наступному запиті користувач повернеться з новим порожнім сеансом. Це пов’язано з тим, що клієнту надається мішок стану сеансу, якщо він ще не має. Якщо клієнт не транспортує файли cookie сеансу, у нас немає способу ідентифікувати клієнта як такого самого, тож йому буде передано нову сесію знову і знову.


6
Просто швидке оновлення, яке я знайшов сьогодні. Сесія недоступна в конструкторі сторінок! Тільки на події Init або після цього.
Нуно Агапіто

Щойно я зіткнувся з HttpContext.Current.Session == null - це код, який викликається подією Page_Load головної сторінки. Мабуть, це може статися в контексті сторінки. Якщо я перевіряю об'єкт HttpContext.Current, більшість його членів ініціалізуються, але CurrentNotification та IsPostNotification видають помилку: {System.PlatformNotSupportedException}. Якою б не була причина, це питання не виникало у виробництві, де воно працювало роками. Платформа - це Windows Server 2003 R2 SP2, програма має цільовий фреймворк .Net 3.5 і працює в IIS з увімкненим станом сесії.
Р. Шреурс

Я також виявив, що коли IIS обслуговує прямий запит на файл ресурсу, який існує на диску, такий як таблиця стилів, HttpContext.Current.Sessionможе бути нульовим кодом у "Application_AcquireRequestState". Запит на саму сторінку, однак, робить об’єкт сеансу доступним для кодування там. Це принаймні під MVC.NET 4.
інгредієнт_15939,

Я думаю, що це також може бути недійсним, якщо ви знаходитесь у MVC-дії, кешованої виведеннями.
користувач2173353

40

Наступне твердження не зовсім точне:

"Отже, якщо ви закликаєте зі своєї сторінки інші функціональні можливості, включаючи статичні класи, вам слід добре"

Я викликаю статичний метод, який посилається на сеанс через HttpContext.Current.Session, і він є нульовим. Однак я викликаю метод через метод веб-сервісу через ajax за допомогою jQuery.

Як я дізнався тут, ви можете виправити проблему простим атрибутом методу або скористатися об'єктом сеансу веб-сервісу:

Однак є хитрість, щоб отримати доступ до стану сеансу в рамках веб-методу, потрібно ввімкнути таке управління сеансом:

[WebMethod (EnableSession = true)]

Вказавши значення EnableSession, тепер у вас буде керований сеанс, з яким можна грати. Якщо не вказати це значення, ви отримаєте об’єкт Nul Session і, швидше за все, зіткнетеся з нульовими посиланнями винятків, намагаючись отримати доступ до об'єкта сеансу.

Дякую Метью Козьє за рішення.

Просто подумав, що я додам свої два центи.

Ред


1
дякую Еду, сеанс виглядав як нуль у веб-методі - додавши це виправлено. +1
фусі

1
Добре, коли ви зателефонуєте у веб-сервіс, ви використовуєте інший запит, ніж для сторінки, щоб ця заява все-таки була правильною, IMO.
driis

Документи MSDN тут - the default value is false. Працює як шарм.
Benjineer

22

Якщо ваш екземпляр сесії є нульовим, а ваш - у файлі 'ashx', просто реалізуйте інтерфейс 'IRequiresSessionState'.

Цей інтерфейс не має членів, тому вам потрібно просто додати ім'я інтерфейсу після оголошення класу (C #):

public class MyAshxClass : IHttpHandler, IRequiresSessionState

Дуже дякую, сесія була нульовою у моєму класі входу. Коли я додав цей код до свого обробника ashx, він перетворив сесію і на моєму класі
Ateş Danış

Я думаю, що це досить добре відповідає на питання. Дуже дякую.
Сачин Йосиф

2

Технічні статті ASP.NET

ПІДСУМОК: В ASP.NET кожна веб-сторінка походить від класу System.Web.UI.Page. Клас Page агрегує екземпляр об'єкта HttpSession для даних сеансу. Клас Page розкриває різні події та методи налаштування. Зокрема, метод OnInit використовується для встановлення стану ініціалізації об'єкта Page. Якщо у запиті немає файлу cookie сесії, запитувачеві буде видано нове cookie сесії.

Редагувати:

Сесія: Концепція для початківців

ПІДСУМОК: Сесія створюється, коли користувач надсилає перший сервер запиту на будь-яку сторінку веб-програми, програма створює сесію та надсилає ідентифікатор сесії назад користувачеві з відповіддю і зберігається на клієнтській машині у вигляді невеликого файлу cookie . Тому в ідеалі "машина, яка відключила файли cookie, інформація про сеанси не зберігатиметься".


2

У моєму випадку ASP.NET State Serviceбуло зупинено. Зміна Startup typeдо Automaticі запуску служби вручну в перший раз вирішується питання.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.