为什么继承实现一个HttpHandler无法使用Session?
因为IHttpHandler默认没有实现IRequiresSessionState这个标记接口,所以对于这个调用方HttpContext不会提供Session。Page就是同时实现了IHttpHandler和IRequiresSessionState。
1、先引用System.Web.SessionState 这个命名空间,
2、如果是要在HttpHandler 中读取Session的内容,就要在实现IHttpHandler 的类中同时实现IReadOnlySessionState 这个接口。
3、如果是要在HttpHandler 中读写Session的内容,就要在实现IHttpHandler 的类中同时实现IRequiresSessionState
这样就可以在自定义的HttpHandler 中正常的使用Session了。
IHttpHandler中使用Session实现原理
前言
在实现自己的Handler的时候只需要继承IHttpHandler接口就行了,在Handler中使用Session时,只需要继承一下IRequiresSessionState就行了,到底为什么只需要实现一下接口就能使用Session了呢?下面和大家一起探讨一下。
工具
Reflector
正文
在Handler中使用Session的时候是从HttpContext中去取的,那么用Reflector直接去找到HttpContext,看他是如何做到的,把整个类用Reflector Disassembler出来,直接搜索关键字IRequiresSessionState,整个类里面只搜到一个,位置是1157行,下面我把代码一贴大家就明白了:
public IHttpHandler Handler { get { return this._handler; } set { this._handler = value; this.RequiresSessionState = false; this.ReadOnlySessionState = false; this.InAspCompatMode = false; if (this._handler != null) { if (this._handler is IRequiresSessionState) { this.RequiresSessionState = true; } if (this._handler is IReadOnlySessionState) { this.ReadOnlySessionState = true; } Page page = this._handler as Page; if ((page != null) && page.IsInAspCompatMode) { this.InAspCompatMode = true; } } } }
代码说明:
1. 非常关键的代码 this._handler is IRequiresSessionState 和 this._handler is IReadOnlySessionState ,我们再看关于IRequiresSessionState的说明:指定目标 HTTP 处理程序需要对会话状态值具有读写访问权。而this.RequiresSessionState和this.ReadOnlySessionState默认都是false的,也就是说默认是不能访问Session的数据,当你继承IRequiresSessionState或IReadOnlySessionState之后访问权被打开!至于在哪里打开,有兴趣的朋友可以继续深究一下,在SessionStateModule这个类里面有更深入的答案,他是通过访问这个类的属性来判断是否需要打开Session的访问权的。
结束
写这篇文章的目的有两个:
1. 不明白的时候一定要问为什么,不仅如此还是努力尽所能的深究一下。
2. 学习一下这正模式,虽然不知道是哪条设计模式,但是如果是我的话我可能会写一个abstract来实现这样的功能。
友情提示:至于Handler的实现可以参考HttpApplication的源代码。
浙公网安备 33010602011771号