2009-12-16 7 views
1

На моей веб-странице входа в систему (т.е. на первой странице попадает пользователь) У меня есть код этой формы:Когда создается сеанс?

public class MyPage : System.Web.UI.Page { 
    private MyClass _obj = new MyClass(); 
    ... 

MyClass имеет конструктор:

public MyClass() { 
    var sess = HttpContext.Current.Session; // no problem here 
    sess["MyValue"] = 123; // throws null ref exception coz sess is null 
} 

Как я уже отметил, вызов до sess["MyValue"] выбрасывает исключение с нулевой ссылкой, поскольку HttpContext еще не создал объект сеанса.

Итак, когда безопасно начать доступ к объекту Session? Я не хочу отказываться от встроенного объявления/инициализации _obj; это очень удобно для меня! Какие у меня альтернативы?

ответ

13

Вы должны иметь доступ к сеансу в событии OnInit или PreInit, если это вас беспокоит. До этого и ты умираешь со смертью.

+1

+1 для информации и LOL :) –

1

Вы можете посмотреть http-конвейер. У Rich Starhl есть nice article.. Объекты сеанса создаются/извлекаются во время события aquireRequestState. Если у вас есть HTTP-модули, которые перехватывают запрос до этого события, ваш сеанс может быть не инициализирован

2

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

if (Session["MyValue"] == null) 
    Session.Add("MyValue", ""); 

Session["MyValue"] = "123"; 

Вы также можете добавить файл Global.asax к проекту. Именно здесь вы можете обрабатывать событие Session_Start.

1

Сессия создана в aquireRequestState Событие контура Http-модуля. Я попытался подробно объяснить все это ниже.

Мы ниже событий в трубопроводе Http Модуль:
(Pre - Страница жизненного цикла)
1. BeginRequest
2. AuthenticateRequest
3. AuthorizeRequest
4. ResolveRequestCache
5. AcquireRequestState
6. PreRequestHandlerExecute

сообщение - Страница жизненного цикла
7. PostRequestHandlerExecute
8. ReleaseRequestState
9. UpdateRequestCache
10. EndRequest

Теперь, когда мы знаем, первое событие в жизни страницы цикла PreInit. Вы пытаетесь создать объект _obj до PreInit событие. В жизненном цикле запроса этот процесс создания объекта и выполнения конструктора выполняется во время ResolveRequestCache i.e; перед Событие AcquireRequestState (так как это напрямую создается в классе, а не в любом методе).Как и ожидалось, сеанс по-прежнему не будет доступен в конструкторе, поскольку AcquireRequestState еще не выполнен.

PreInit метод в жизненном цикле страницы вызывается после AcquireRequestState и, следовательно, сессия доступна там.

Заключение: ранние работы сессии может быть сделано в любое время после AcquireRequestState в модулях HTTP (если вы перехватывают запрос программно) или в/после PreInit метода.

Смежные вопросы