最近系统中要添加一个对用户是否登录的判断,没登陆就不允许直接查看相关的页面。经过了3个阶段的摸索,终于解决。
虽然解决的办法不复杂,但通过不同的实现方式进行对比总结,可以加深对.NET运行机制的理解。
1.PageBase基类
在PageBase基类中重载OnInit方法,添加对登录Session的判断,如果未登录重定向跳转到登录页面;如已登录可不用做任何操作。
参考:http://bbs.csdn.net/topics/380033008 #31楼chenpeng0118帖子
这种处理方式简单、好理解,通过重载的办法直接验证;但需要每个页面重载PageBase基类,每个aspx页面继承该类,而不是System.Web.UI.Page
2.ASP.NET HttpHandles
老大说了,PageBase基类方法太麻烦了,每个页面添加繁琐。研究下HttpHandle之类的东西来搞。
大致的过程可参考:http://www.cnblogs.com/goody9807/archive/2009/06/30/1513649.html “三、http handles类的实现”,将拓展名换成.aspx,为了实现对Session的访问,还需继承System.Web.SessionState.IrequiresSessionState,最后在Web.Config进行注册。
MyHandler.NewHandler类代码实现如下:
namespaceMyHandler
{
///<summary>
///增加*.aspx页面登录状态判断
///</summary>
publicclassNewHandler :IHttpHandler,System.Web.SessionState.IRequiresSessionState
{
public NewHandler()
{
//
//TODO: 在此处添加构造函数逻辑
//
}
System.Web.SessionState.HttpSessionStateSession;
#regionImplementation of IHttpHandler
publicvoidProcessRequest(System.Web.HttpContextcontext)
{
HttpResponseobjResponse = context.Response;
Session = context.Session;
//context.Response.WriteFile(context.Request.PhysicalPath);
//objResponse.Write("<script>alert('登录失效,请重新登录!');url='" +context.Request.ApplicationPath + "/index.aspx';if(window.parent!=null){window.parent.location=url;}else{this.location=url;};</script>");
if(context.Request.Path.IndexOf("index.aspx")>= 0)
{
context.Response.Flush();
}
elseif (Session["UserID"]!="")//已经登录情况
{
context.Response.Flush();
}
else
{
objResponse.Write("<script>alert('登录失效,请重新登录!');url='"+ context.Request.ApplicationPath + "/index.aspx';if(window.parent!=null){window.parent.location=url;}else{this.location=url;};</script>");
}
}
publicboolIsReusable
{
get
{
returntrue;
}
}
#endregion
}
}
Web.Config添加如下:
<httpHandlers>
<addpath="*.aspx"verb="*"type="MyHandler.NewHandler" />
</httpHandlers>
Path中可通过通配符进行过滤筛选,经过调试。在每个页面加载前,会执行ProcessRequest()方法,如果未登录,可重定向跳转到登录页面。但是如果已登录,无法实现“什么都不做”。
经过反复查阅资料,找到相关的原因解释:如果自己定义了新的HttpHandler,而且在web.config中指定,则系统只会使用这个新的HttpHandler,而不再使用原先默认的或者指定的。
所以自定义了新的HttpHandler,如已登录,无法用原先的HttpHandler处理。显然,HttpHandler处理登录验证不太合适。
详细可参见:http://www.cnblogs.com/jeffwongishandsome/archive/2009/07/20/1513524.html
3.ASP.NET HttpModule
和HttpHandler类似,自定义HttpModule类如下:
namespaceMyHandler
{
///<summary>
///增加*.aspx页面登录状态判断,HttpModule处理效果更好
///</summary>
publicclassNewModule :IHttpModule,IReadOnlySessionState
{
publicvoidDispose()
{
}
publicvoidInit(HttpApplication context)
{
context.PreRequestHandlerExecute +=new EventHandler(PreRequestHandlerExecute);
}
void PreRequestHandlerExecute(object sender,EventArgse)
{
HttpApplicationha = (HttpApplication)sender;
stringpath = ha.Context.Request.Url.ToString();
//排除首页
if(path.IndexOf("index.aspx") >0)
{
}
elseif (ha.Context.Session["UserID"]==null || ha.Context.Session["UserID"] =="")//验证是否登录
{
ha.Context.Response.Write("<script>alert('登录失效,请重新登录!');url='"+ ha.Context.Request.ApplicationPath + "/index.aspx';if(window.parent!=null){window.parent.location=url;}else{this.location=url;};</script>");
//ha.Context.Response.Redirect(ha.Context.Request.ApplicationPath+ "/RedirectIndex.html" + (isRedircetPre ? "?url=" + path :""));
ha.Context.Response.End();
}
}
}
}
Web.Config添加如下:
<httpModules>
<addname="NewModule"type="MyHandler.NewModule"></add>
</httpModules>
问题完美解决,没有HttpHandler类似的问题。如需了解HttpHandler和HttpHandler之间的区别,可自行搜索,可参考:http://www.cnblogs.com/changrulin/p/4769339.html
2017年04月13日