代码首先检查请求头和响应头,看看是否符合写缓存的条件,例如检查缓存是否修改、返回状态是否为200等。接下来创建缓存主键、设置缓存周期。最后一步就是通过OutputCache.InsertResponse方法把结果缓存到OutputCache中。
2. SessionStateModule所在管道步骤:AcquireRequestState、ReleaseRequestState、EndRequest。SessionStateModule的Init方法调用了InitModuleFromConfig方法,从配置文件中读取配置,初始化状态存储。在Web.config配置中我们经常看到<sessionState mode="InProc" cookieless="UseCookies" />配置,mode包括InProc(进程内)、SQLServer(数据库)、StateServer(进程外)、Custom(自定义)、Off(关闭Session)等。我们先看下InitModuleFromConfig方法的代码:
private void InitModuleFromConfig(HttpApplication app, SessionStateSection config) { if (config.Mode != SessionStateMode.Off) { app.AddOnAcquireRequestStateAsync(new BeginEventHandler(this.BeginAcquireState), new EndEventHandler(this.EndAcquireState)); app.ReleaseRequestState += new EventHandler(this.OnReleaseState); app.EndRequest += new EventHandler(this.OnEndRequest); this._partitionResolver = this.InitPartitionResolver(config); switch (config.Mode) { case SessionStateMode.InProc: if (HttpRuntime.UseIntegratedPipeline) { s_canSkipEndRequestCall = true; } this._store = new InProcSessionStateStore(); this._store.Initialize(null, null); break; case SessionStateMode.StateServer: if (HttpRuntime.UseIntegratedPipeline) { s_canSkipEndRequestCall = true; } this._store = new OutOfProcSessionStateStore(); ((OutOfProcSessionStateStore)this._store).Initialize(null, null, this._partitionResolver); break; case SessionStateMode.SQLServer: this._store = new SqlSessionStateStore(); ((SqlSessionStateStore)this._store).Initialize(null, null, this._partitionResolver); break; case SessionStateMode.Custom: this._store = this.InitCustomStore(config); break; } this._idManager = this.InitSessionIDManager(config); if (((config.Mode == SessionStateMode.InProc) || (config.Mode == SessionStateMode.StateServer)) && this._usingAspnetSessionIdManager) { this._ignoreImpersonation = true; } } }
前面的几行代码加载Session事件到执行管道,接下来的switch代码根据Mode的枚举值初始化不同的Session存储介质。 后面还有一行代码调用了InitSessionIDManager方法,生成一个Session的ID管理器。
当管道执行到AcquireRequestState事件时,SessionStateModule中的BeginAcquireState事件被触发,精简后的代码如下:
private IAsyncResult BeginAcquireState(object source, EventArgs e, AsyncCallback cb, object extraData) { this.ResetPerRequestFields(); this._rqContext = ((HttpApplication)source).Context; this._rqAr = new HttpAsyncResult(cb, extraData); this.ChangeImpersonation(this._rqContext, false); this._store.InitializeRequest(this._rqContext); if (this._idManager.InitializeRequest(this._rqContext, false, out this._rqSupportSessionIdReissue)) { ._rqAr.Complete(true, null, null); return this._rqAr; } this._rqId = this._idManager.GetSessionID(this._rqContext); this._rqExecutionTimeout = this._rqContext.Timeout; this._rqReadonly = this._rqContext.ReadOnlySessionState; if (this._rqId != null) { sessionStateItem = this.GetSessionStateItem(); } else if (!flag3) { bool flag4 = this.CreateSessionId(); this._rqIdNew = true; if (flag4) { if (s_configRegenerateExpiredSessionId) { this.CreateUninitializedSessionState(); } this._rqAr.Complete(true, null, null); return this._rqAr; } } if (sessionStateItem) { this.CompleteAcquireState(); this._rqAr.Complete(true, null, null); } result = this._rqAr; return result; }