HttpModule可以实现很多有用的功能,例如如果您想要给web站点的每个页面上都添加文本(如日期、时间等),而不希望修改应用程序中的每个页面,那么,它就是您需要的。本文介绍的是通过HttpModule实现用户的登陆状态检查。
1.编写自定义的HttpModule
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.SessionState; namespace Web { public class CheckLoginStatus : IHttpModule, IRequiresSessionState { public void Dispose() { } public void Init(HttpApplication context) { context.AcquireRequestState += new EventHandler(context_AcquireRequestState); } void context_AcquireRequestState(object sender, EventArgs e) { HttpApplication application = (HttpApplication)sender; // 获取请求Url string requestUrl = application.Request.Url.ToString(); if (requestUrl.EndsWith("aspx")) { // 检查用户是否已经登录 if (application.Context.Session["用户名"] == null || application.Context.Session["用户名"].ToString().Trim() == "") { string requestPage = requestUrl.Substring(requestUrl.LastIndexOf('/') + 1); // 如果请求的页面不是登录页面,刚重定向到登录页面。 if (requestPage != "Login.aspx") { application.Server.Transfer("Login.aspx"); } } } } } }
2.在web.config文件中注册自定义的HttpModule
<?xml version="1.0"?> <!-- 有关如何配置 ASP.NET 应用程序的详细信息,请访问 http://go.microsoft.com/fwlink/?LinkId=169433 --> <configuration> <connectionStrings> <add name="MysqlConnectionString" connectionString="server=localhost;User Id=root;password=11170407;Database=web" providerName="MySql.Data.MySqlClient" /> </connectionStrings> <system.web> <compilation debug="true" targetFramework="4.0" /> <authentication mode="Forms"> <forms loginUrl="Login.aspx" timeout="30" /> </authentication> <membership> <providers> <clear/> <add name="AspNetSqlMembershipProvider" type="System.Web.Security.SqlMembershipProvider" connectionStringName="ApplicationServices" enablePasswordRetrieval="false" enablePasswordReset="true" requiresQuestionAndAnswer="false" requiresUniqueEmail="false" maxInvalidPasswordAttempts="5" minRequiredPasswordLength="6" minRequiredNonalphanumericCharacters="0" passwordAttemptWindow="10" applicationName="/" /> </providers> </membership> <profile> <providers> <clear/> <add name="AspNetSqlProfileProvider" type="System.Web.Profile.SqlProfileProvider" connectionStringName="ApplicationServices" applicationName="/"/> </providers> </profile> <roleManager enabled="false"> <providers> <clear/> <add name="AspNetSqlRoleProvider" type="System.Web.Security.SqlRoleProvider" connectionStringName="ApplicationServices" applicationName="/" /> <add name="AspNetWindowsTokenRoleProvider" type="System.Web.Security.WindowsTokenRoleProvider" applicationName="/" /> </providers> </roleManager> <globalization requestEncoding="gb2312" responseEncoding="gb2312" culture="zh-CN" fileEncoding="gb2312"/> <httpModules> <add name="CheckLoginStatus" type="Web.CheckLoginStatus"/> </httpModules> </system.web> <system.webServer> <modules runAllManagedModulesForAllRequests="true" /> </system.webServer> </configuration>
需要特别注意的是,如下写法可能会出现css样式、图片等无法显示。
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.SessionState; namespace Web { public class CheckLoginStatus : IHttpModule, IRequiresSessionState { public void Dispose() { } public void Init(HttpApplication context) { context.AcquireRequestState += new EventHandler(context_AcquireRequestState); } void context_AcquireRequestState(object sender, EventArgs e) { HttpApplication application = (HttpApplication)sender; // 检查用户是否已经登录 if (application.Context.Session["用户名"] == null || application.Context.Session["用户名"].ToString().Trim() == "") { // 获取请求Url string requestUrl = application.Request.Url.ToString(); string requestPage = requestUrl.Substring(requestUrl.LastIndexOf('/') + 1); // 如果请求的页面不是登录页面,刚重定向到登录页面。 if (requestPage != "Login.aspx") { application.Server.Transfer("Login.aspx"); } } } } }
具体的原因是HttpModule会将所有的Request都进行处理,因此需要进行请求的类型判断,如果请求的是aspx,我们才会进行登陆状态检查,请求css文件和图片文件时,我们自定义的HttpModule都将忽略该请求。