- void OnReleaseState(Object source, EventArgs eventArgs) {
- HttpApplication app;
- HttpContext context;
- bool setItemCalled = false;
- _releaseCalled = true;
- app = (HttpApplication)source;
- context = app.Context;
- ChangeImpersonation(context, false);
- try {
- if (_rqSessionState != null) {
- bool delayedSessionState = (_rqSessionState == s_delayedSessionState);
- SessionStateUtility.RemoveHttpSessionStateFromContext(_rqContext, delayedSessionState);
- if (
- // 如果会话状态是新的, 并且没有被访问过,
- // 那么这样的会话状态存储不用保存到系统的缓存中, 保存了没有意义.
- // 所以不做任何处理 (不保存在系统缓存中)
- _rqSessionStateNotFound
- && _sessionStartEventHandler == null
- // Nothing has been stored in session state
- && (delayedSessionState || !_rqSessionItems.Dirty)
- && (delayedSessionState || _rqStaticObjects == null || _rqStaticObjects.NeverAccessed)
- ) {
- }
- // 如果会话被丢弃了, 即我们在控制器中调用了 Session.Abandon(), 常用于注销操作.
- else if (_rqSessionState.IsAbandoned) {
- if (_rqSessionStateNotFound) {
- // The store provider doesn't have it, and so we don't need to remove it from the store.
- // However, if the store provider supports session expiry, and we have a Session_End in global.asax,
- // we need to explicitly call Session_End.
- if (_supportSessionExpiry) {
- if (delayedSessionState) {
- InitStateStoreItem(false /*addToContext*/);
- }
- _onEndTarget.RaiseSessionOnEnd(ReleaseStateGetSessionID(), _rqItem);
- }
- }
- else {
- // Remove it from the store because the session is abandoned.
- _store.RemoveItem(_rqContext, ReleaseStateGetSessionID(), _rqLockId, _rqItem);
- }
- }
- else if (!_rqReadonly ||
- (_rqReadonly &&
- _rqIsNewSession &&
- _sessionStartEventHandler != null &&
- !SessionIDManagerUseCookieless)) {
- // We save it only if there is no error, and if something has changed (unless it's a new session)
- if ( context.Error == null // no error
- && ( _rqSessionStateNotFound
- || _rqSessionItems.Dirty // SessionItems has changed.
- || (_rqStaticObjects != null && !_rqStaticObjects.NeverAccessed) // Static objects have been accessed
- || _rqItem.Timeout != _rqSessionState.Timeout // Timeout value has changed
- )
- ) {
- if (delayedSessionState) {
- InitStateStoreItem(false /*addToContext*/);
- }
- if (_rqItem.Timeout != _rqSessionState.Timeout) {
- _rqItem.Timeout = _rqSessionState.Timeout;
- }
- // 该标识设置为 true, 说明该模块设置过 session, 该标识用于一些优化
- s_sessionEverSet = true;
- // 为 true 说明我们已经把当前的 session 保存进系统缓存中了
- setItemCalled = true;
- // 将这个会话状态存储放入系统缓存中, 在这个代码中, 我们看到使用了 ReleaseStateGetSessionID() 这个方法去获取 session id
- // 有这样的意思. 如果已经有 session id 了, 则直接使用, 如果没有则会创建一个 session id, 且写入 cookie , 则浏览器端就有了这个 id
- // 如果这是一个全新的请求, 而且也没有在控制器中也没有 Session.SessionID 这样的访问, 那么到了此处, session id 就是空值
- _store.SetAndReleaseItemExclusive(_rqContext, ReleaseStateGetSessionID(), _rqItem, _rqLockId, _rqSessionStateNotFound);
- }
- else {
- // Can't save it because of various reason. Just release our exclusive lock on it.
- if (!_rqSessionStateNotFound) {
- _store.ReleaseItemExclusive(_rqContext, ReleaseStateGetSessionID(), _rqLockId);
- }
- }
- }
- }
- // 上面是决定是否保存会话状态存储的代码, 下面是决定是否将 session id 保存在 cookie 中的代码
- // 有这样一种情况, 在一次全新的请求中, 如果我们在控制器中有了 Session.SessionID 这样的访问
- // 那么, 此时会创建一个 SessionID 且写入 cookie 中, 但是如果我们没有向 Session 中存储数据
- // 那么这样的 SessionID 继续保存在 cookie 中, 就是没有意义的, 所以就从 cookie 中删除这个 id
- if (_rqAddedCookie && !setItemCalled && context.Response.IsBuffered()) {
- _idManager.RemoveSessionID(_rqContext);
- }
- }
- finally {
- RestoreImpersonation();
- }
- bool implementsIRequiresSessionState = context.RequiresSessionState;
- if (HttpRuntime.UseIntegratedPipeline
- && (context.NotificationContext.CurrentNotification == RequestNotification.ReleaseRequestState)
- && (s_canSkipEndRequestCall || !implementsIRequiresSessionState)) {
- context.DisableNotifications(RequestNotification.EndRequest, 0 /*postNotifications*/);
- _acquireCalled = false;
- _releaseCalled = false;
- ResetPerRequestFields();
- }
- }
来源: https://www.cnblogs.com/lgshare/p/9015982.html