网页过期弹出功能
该功能的引入目的很简单,防止人员离开工位时忘记登出系统,其他人员冒名操作,追责时产生争议。
首先,介绍下本文的参考资料:
0. Http请求处理流程
IIS 、Framework、Asp.Net 是如何协同工作处理每个Http请求、如何区分不同的请求、IIS、Framework、Asp.Net三者之间的数据如何流动?
能够处理各种后缀名的应用程序,通常被称为 ISAPI 应用程序(Internet Server Application Programe Interface,互联网服务器应用程序接口)
Asp.Net 只是服务器(IIS)的一个组成部分而已,它是一个 ISAPI扩展。
HttpRuntime类是Asp.Net的一个主要入口,它有一个称作 ProcessRequest 的方法,这个方法以一个 HttpWorkerRequest 类作为参数。HttpRuntime 类几乎包含着关于单个 Http请求的所有信息:
所请求的文件、服务器端变量、QueryString、Http 头信息 等等。
当 Web.config文件的内容发生改变 或者 .aspx文件发生变动的时候,为了能够卸载运行在同一个进程中的应用程序(卸载也是为了重新加载),Http请求被分放在相互隔离的应用程序域中。
对于IIS来说,它依赖一个叫做 HTTP.SYS 的内置驱动程序来监听来自外部的 HTTP请求。在操作系统启动的时候,IIS首先在HTTP.SYS中注册自己的虚拟路径。
当Http请求进入 Asp.Net Runtime以后,它的管道由托管模块(NOTE:Managed Modules)和处理程序(NOTE:Handlers)组成,并且由管道来处理这个 Http请求。
1. HttpModule介绍
一般来说,我们可以将Asp.Net中的事件分成三个级别,最顶层是 应用程序级事件、其次是页面级事件、最下面是控件级事件,事件的触发分别与 应用程序周期、页面周期、控件周期紧密相关。
而 Http Module 的作用是与应用程序事件 密切相关的。
Asp.Net 内置的 Http Modules
整个过程如下:
-
当站点第一个资源被访问的时候,Asp.Net会创建HttpApplication类的实例,它代表着站点应用程序,同时会创建所有在Web.Config中注册过的Module实例。
-
在创建Module实例的时候会调用Module的Init()方法。
-
在Init()方法内,对想要作出响应的HttpApplication暴露出的事件进行注册。(仅仅进行方法的简单注册,实际的方法需要另写)。
-
HttpApplication在其应用程序周期中触发各类事件。
-
触发事件的时候调用Module在其Init()方法中注册过的方法。
2. HttpModule模块作用之三通过Session判断用户是否登陆
3. 判断Session过期
上述两个参考文档是可以直接参考的代码,非原理性讲解。
4. 利用HttpModule开发asp.net页面、ashx等访问时session失效的统一处理入口
HttpApplication处理事件的先后顺序,不同事件会处理不同的事情,需要注意使用顺序。
5. ASP.NET三剑客 HttpApplication HttpModule HttpHandler 解析
详细介绍了上述博客提到的HttpApplication、HttpModule、HttpHandler等对象
上面介绍的方法都是通过HttpModule判断session是否失效来决定是否返回登陆页面。
那么什么是Session,怎么设定Session的存续事件,集群环境下Session如何处理?这些问题的答案可以参考6-8这3篇博客。
经过上面的参考文档,我们的代码如下:
public class ModuleBackLogin : IHttpModule { public ModuleBackLogin() { // // TODO: 在此处添加构造函数逻辑 // } // Init方法仅用于给期望的事件注册方法 public void Init(HttpApplication context) { context.PreRequestHandlerExecute += new EventHandler(context_PreRequestHandlerExecute); } // 处理context_PreRequestHandlerExecute事件的实际代码 void context_PreRequestHandlerExecute(object sender, EventArgs e) { try { HttpApplication ha = (HttpApplication)sender;//获得发生该事件的对象 string path = ha.Context.Request.Url.ToString();//获得请求的url路径 int n = path.IndexOf("Login.aspx"); //判断是否是登陆页面 int m = path.IndexOf("LoginHandler.ashx"); //不是登录页面,也不是登录操作 if (n < 0 && m < 0) { if (ha.Context.Session != null) { if (ha.Context.Session[KeyConst.UserId] == null) { ha.Response.Write("<script>alert('登陆超时或者非法登录,请重新登录!!');top.window.location.href='Login.aspx';</script>"); ha.Response.End(); } } } } catch { } } public void Dispose() { } }
<?xml version="1.0" encoding="utf-8"?> <!-- 有关如何配置 ASP.NET 应用程序的详细信息,请访问 http://go.microsoft.com/fwlink/?LinkId=169433 --> <configuration> <system.web> <compilation debug="true" targetFramework="4.5" /> <httpRuntime targetFramework="4.5" requestValidationMode="2.0"/> <!--<httpModules> <add name="MyModule" type="ModuleBackLogin" /> </httpModules>--> <sessionState mode="InProc" timeout="10"/> <!--<httpRuntime requestValidationMode="2.0" />--> <pages validateRequest="false"></pages> </system.web> <system.webServer> <modules> <add name="MyModule" type="ModuleBackLogin" /> </modules> </system.webServer> </configuration>