Что мне делать, если текущий сеанс ASP.NET нулевой?

125

В моем веб-приложении я делаю что-то вроде этого, чтобы прочитать переменные сеанса:

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

Я понимаю, почему важно проверить, почему HttpContext.Current.Session ["MyVariable"] имеет значение null (возможно, переменная еще не была сохранена в сеансе или сеанс был сброшен по разным причинам), но зачем мне это проверять если 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 будет вести себя иначе, вы можете проверить это при доступе к сеансу с помощью веб-API ASP.NET
Тьяго Гувеа,

Ответы:

158

Да, объект Session может быть нулевым, но только в определенных обстоятельствах, с которыми вы редко будете сталкиваться:

Если у вас есть только код на страницах, вы не столкнетесь с этим. Большая часть моего кода ASP .NET использует сеанс без повторной проверки нулевого значения. Однако есть над чем подумать, если вы разрабатываете IHttpModule или иным образом не разбираетесь в более сложных деталях ASP .NET.

редактировать

В ответ на комментарий: Доступно ли состояние сеанса, зависит от того, было ли выполнено событие AcquireRequestState для запроса. Здесь модуль состояния сеанса выполняет свою работу, считывая файл cookie сеанса и находя для вас подходящий набор переменных сеанса.

AcquireRequestState запускается до передачи управления вашей странице. Так что, если вы вызываете со своей страницы другие функции, включая статические классы, все будет в порядке.

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

Кроме того, если клиент отключил файлы cookie, объект сеанса все равно будет доступен, но при следующем запросе пользователь вернется с новым пустым сеансом. Это связано с тем, что клиенту дается пакет состояния сеанса, если у него его еще нет. Если клиент не передает cookie сеанса, у нас нет возможности идентифицировать клиента как того же самого, поэтому ему снова и снова будет передаваться новый сеанс.

driis
источник
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может иметь значение null для кода в Application_AcquireRequestState. Однако запрос самой страницы делает объект сеанса доступным для кода. По крайней мере, это под MVC.NET 4.
ингридиент_15939
Я думаю, что он также может быть нулевым, если вы находитесь внутри действия MVC с кешированием вывода.
user2173353
40

Следующее утверждение не совсем верно:

«Так что, если вы вызываете другие функции, включая статические классы, со своей страницы, все будет в порядке»

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

Как я узнал здесь, вы можете решить проблему с помощью простого атрибута метода или использовать объект сеанса веб-службы:

Однако есть уловка, чтобы получить доступ к состоянию сеанса в веб-методе, вы должны включить управление состоянием сеанса следующим образом:

[WebMethod (EnableSession = true)]

Указав значение EnableSession, теперь у вас будет управляемый сеанс, с которым можно поиграть. Если вы не укажете это значение, вы получите нулевой объект сеанса и, скорее всего, столкнетесь с исключениями с нулевой ссылкой при попытке доступа к объекту сеанса.

Спасибо Мэтью Козье за ​​решение.

Просто подумал, что добавлю свои два цента.

издание

Эд Бишоп
источник
1
спасибо, Эд, Сессия в веб-методе отображалась как null - добавление исправило это. +1
fusi
1
Ну, когда вы вызываете веб-службу, вы используете другой запрос, чем для страницы, так что это утверждение все еще верное, ИМО.
driis
Документы MSDN здесь - the default value is false. Работает как шарм.
Benjineer
22

Если ваш экземпляр Session имеет значение null и вы находитесь в файле 'ashx', просто реализуйте интерфейс IRequiresSessionState.

Этот интерфейс не имеет членов, поэтому вам просто нужно добавить имя интерфейса после объявления класса (C #):

public class MyAshxClass : IHttpHandler, IRequiresSessionState
mathijsuitmegen
источник
Большое спасибо, сеанс в моем классе входа был нулевым. Когда я добавил этот код в свой обработчик ashx, он включил сеанс и в моем классе
Ateş Danış
Я думаю, это неплохо отвечает на вопрос. Спасибо.
Сачин Джозеф
2

Технические статьи по ASP.NET

РЕЗЮМЕ: В ASP.NET каждая веб-страница является производным от класса System.Web.UI.Page. Класс Page собирает экземпляр объекта HttpSession для данных сеанса. Класс Page предоставляет различные события и методы для настройки. В частности, метод OnInit используется для установки состояния инициализации объекта Page. Если в запросе нет файла cookie сеанса, запрашивающей стороне будет выдан новый файл cookie сеанса.

РЕДАКТИРОВАТЬ:

Сессия: Концепция для начинающих

РЕЗЮМЕ: Сеанс создается, когда пользователь отправляет первый запрос на сервер для любой страницы в веб-приложении, приложение создает сеанс и отправляет идентификатор сеанса обратно пользователю с ответом и сохраняется на клиентском компьютере в виде небольшого файла cookie. , Так что в идеале «машина, на которой отключены файлы cookie, информация о сеансе не будет сохранена».

adatapost
источник
2

В моем случае ASP.NET State Serviceбыло остановлено. ИзменениеStartup type к Automaticи запуску службы вручную в первый раз решается вопрос.

Эрик
источник