IF {@recordnumber} mod 12 = 0 Тогда opNo12 else ""
Global.asax реализует HttpApplication - который является тем, с чем Вы говорите при вызове этого из него.
Документация MSDN для HttpApplication имеет детали о том, как можно овладеть им в HttpHandler, например, и затем получить доступ к различным свойствам на нем.
ОДНАКО
Ваше приложение может создать несколько экземпляров HttpApplication для обрабатывания параллельных запросов, и эти экземпляры могут быть снова использованы, поэтому просто взятие его так или иначе не собирается гарантировать, что у Вас есть правильный.
Я также также добавил бы предупреждение - если Ваши сбои приложения, нет никакой гарантии, что session_end будет названным, и Вы потеряете все данные через все сессии, ясно не хорошая вещь.
Я соглашаюсь, что, входя в систему каждая страница является, вероятно, не прекрасной идеей, но возможно социальной гостиницей с некоторым асинхронным случаем входа - Вы исчерпываете детали к регистрирующемуся классу, который время от времени регистрирует детали, которые Вы после - все еще 100%-е тело, если сбои приложения, но Вы, менее вероятно, потеряете все.
Я думаю, что Вы уже ответили на свой собственный вопрос: обычно свойство Session в Global.asax и HttpContext. Текущий. Сессия является тем же (если существует текущий запрос). Но в случае тайм-аута сессии, нет никакого активного запроса, и поэтому Вы не можете использовать HttpContext. Текущий.
Если Вы хотите получить доступ к сессии из метода, названного Session_End, то передайте его в качестве параметра. Создайте перегруженную версию Журнал () метод, который берет HttpSessionState в качестве параметра, затем назовите Tracker.Log (это. Сессия) от обработчика событий Session_End.
BTW: Вы знаете, что не можете полагаться на событие конца сессии в любом случае? Это будет только работать, пока у Вас есть незавершенное состояние сеанса. При использовании SQL-сервера или StateServer к чесотке состояние сеанса, не будет стрелять событие конца сессии.
Помните, что Session_End работает, когда сессия испытывает таймаут без действия. Браузер не порождает то событие (потому что это неактивно), таким образом, единственное время, Вы на самом деле получите событие, будет при использовании поставщика InProc. В ЛЮБОМ поставщике никогда не будет стрелять это событие.
Мораль? Не используйте Session_End.
Отвечать на исходный вопрос лучше:
Каждый запрос страницы вращает новое Session
возразите и затем расширьте его от своего хранилища сессии. Чтобы сделать это, это использует cookie, обеспеченный клиентом или специальной конструкцией пути (для сессий без cookie). С этим идентификатором сессии это консультируется с хранилищем сессии и десериализовывает (это - то, почему все поставщики, но InProc должен быть сериализуемым), новый объект сессии.
В случае поставщика InProc просто руки Вы ссылка это сохранило в HttpCache
включенный идентификатором сессии. Поэтому поставщик InProc отбрасывает состояние сеанса когда AppDomain
переработан (и также почему несколько веб-серверов не могут совместно использовать состояние сеанса InProc.
Этот недавно созданный и расширенный объект застревает в Context.Items
набор так, чтобы это было доступно для продолжительности запроса.
Любые изменения Вы делаете к Session
объект затем сохраняется в конце запроса к хранилищу сессии путем сериализации (или случай InProc, HttpCache
запись обновляется).
С тех пор Session_End
огни без текущего запроса в мухе, Session
объект вращают ex-nilo без доступной информации. При использовании состояния сеанса InProc, истечения HttpCache
инициировал событие обратного вызова в Ваш Session_End
событие, таким образом, запись сессии доступна, но является все еще копией того, что было в последний раз сохранено в HttpContext.Cache
. Это значение хранится против HttpApplication.Session
свойство внутренним методом (названный ProcessSpecialRequest
) где это затем доступно. Под всеми другими случаями это внутренне прибывает из HttpContext.Current.Session
значение.
Так как Session_End всегда стреляет против пустого Контекста, необходимо ВСЕГДА использовать это. Сессия в таком случае и передает объект HttpSessionState к Вашему коду трассировки. Во всех других контекстах это прекрасно подходит для выборки от HttpContext.Current.Session
и затем передача в код трассировки. Однако, не позволяйте коду трассировки достигнуть контекста сессии.
Не использовать Session_End
если Вы не знаете хранилище сессии об использовании поддержек Session_End
, который это делает, если это возвращается true
от SetItemExpireCallback
. Единственное хранилище в поле, которое делает, InProcSessionState
хранилище. Возможно записать хранилище сессии, которое делает, но вопрос того, кто обработает Session_End
довольно неоднозначно, если существует несколько серверов.
Okay, I am in the same problem to track the session activity. Instead of using session_end event, I have implemented the IDisposable interface and destructor to my sessiontracker class. I have modified the Dispose() method to save the session activity to DB. I invoked the method obj.Dispose() when a user clicks the logout button. If user closed the browser by mistake, then GC will call the destructor while cleaning the objects (not immediately but for sure it will call this method after sometime). The destructor method internally execute the same Dispose() method to save the session activities into DB.
-Shan