<add name="errorhandlermodule" type="system.web.mobile.errorhandlermodule, system.web.mobile, version=1.0.5000.0, culture=neutral, publickeytoken=b03f5f7f11d50a3a" />
</httpmodules>
</system.web>
httpmodules 节点指定了 httpapplication 需要初始化的模块列表,而在前面提到的 httpapplication.initmodules 函数正式根据此列表进行初始化的
以下内容为程序代码:
private void httpapplication.initmodules()
{
httpmodulesconfiguration cfgmodules = ((httpmodulesconfiguration) httpcontext.getappconfig("system.web/httpmodules"[img]/images/wink.gif[/img]);
if (cfgmodules == null)
{
throw new httpexception(httpruntime.formatresourcestring("missing_modules_config"[img]/images/wink.gif[/img]);
}
_modulecollection = cfgmodules.createmodules();
for(int i = 0; i < _modulecollection.count; i++)
{
_modulecollection[i].init(this);
}
globalizationconfig cfgglobal = ((globalizationconfig) httpcontext.getappconfig("system.web/globalization"[img]/images/wink.gif[/img]);
if (cfgglobal != null)
{
_applevelculture = cfgglobal.culture;
_appleveluiculture = cfgglobal.uiculture;
}
}
session 节点对于的 system.web.sessionstate.sessionstatemodule 对象将被 httpmodulesconfiguration.createmodules 方法构造,并调用其 init 函数初始化。sessionstatemodule 类实际上就是负责管理并创建会话,用户完全可以自行创建一个实现 ihttpmodule 接口的类,实现会话的控制,如实现支持集群的状态同步等等。
sessionstatemodule.init 方法主要负责 machine.config 文件中的 sessionstate 配置,调用 sessionstatemodule.initmodulefromconfig 方法建立相应的会话管理器。
以下内容为程序代码:
<system.web>
<sessionstate mode="inproc"
stateconnectionstring="tcpip=127.0.0.1:42424"
statenetworktimeout="10"
sqlconnectionstring="data source=127.0.0.1;integrated security=sspi"
cookieless="false"
timeout="20" />
</system.web>
sessionstate 的使用方法请参加 msdn 中相关介绍和 info: asp.net state management overview。关于不同 mode 的会话管理的话题我们后面再讨论,先继续来看会话的建立过程。
在从 machine.config 文件中读取配置信息后,initmodulefromconfig 方法会向 httpapplication 实例注册几个会话管理事件处理函数,负责在应用程序合适的情况下维护会话状态。
以下内容为程序代码:
private void sessionstatemodule.initmodulefromconfig(httpapplication app,
sessionstatesectionhandler.config config, bool configinit)
{
// 处理不使用 cookie 的情况
//...
app.addonacquirerequeststateasync(new begineventhandler(this.beginacquirestate),
new endeventhandler(this.endacquirestate));
app.releaserequeststate += new eventhandler(this.onreleasestate);
app.endrequest += new eventhandler(this.onendrequest);
// 创建会话管理器
//...
}
beginacquirestate 和 endacquirestate 作为一个异步处理器注册到 httpapplication._acquirerequeststateeventhandlerasync 字段上;onreleasestate 则负责在合适的时候清理会话状态;onendrequest 则是 onreleasestate 的一个包装,负责较为复杂的请求结束处理。前面提到的 httpapplication.initinternal 函数,在完成了初始化工作后,会将上述这些事件处理器,加入到一个执行队列中,由应用程序在合适的时候,使用流水线机制进行调用,最大化处理效率。有关 asp.net 中流水线事件模型的相关介绍,请参考 http pipelines
securely implement request processing, filtering, and content redirection with http pipelines in asp.net 一文中 the pipeline event model 小节,有机会我在写文章详细分析。
知道了会话建立的调用流程再来看会话的实现就比较简单了,sessionstatemodule.beginacquirestate 被 httpapplication 实例在合适的时候调用,处理各种会话的复杂情况后,使用 sessionstatemodule.completeacquirestate 函数完成实际的会话建立工作,并将封装会话的 httpsessionstate 对象以 "aspsession" 为 key 加入到 httpcontext 的哈希表中,也就是前面提到的 httpcontext.context 的由来。而 sessionstatemodule.onreleasestate 则从 httpcontext 中删除 "aspsession" 为 key 的 httpsessionstate 对象,并对会话管理器进行同步工作。