继承实现验证机制【上】

来源:互联网 发布:seo怎么建站 编辑:程序博客网 时间:2024/06/08 13:53

在ASP.NET网站中网站管理后台需要经常验证用户身份,要实现这种功能就可以利用那个继承机制和ASP.NET的事件机制.首先定义一个需要进行身份验证的BasePage类,继承自Page类,在BasePage类的构造函数中定义它的加载事件的处理代码,这样所有继承自BasePage类的页面都能自动执行身份验证.

 

C#代码 复制代码 收藏代码
  1. /// <summary>   
  2. /// 验证登陆类   
  3. /// </summary>   
  4. public class ValidateLogin : System.Web.UI.Page //继承自System.Web.UI.Page   
  5. {   
  6.     public ValidateLogin()   
  7.     {   
  8.         //当页面加载时执行该事件   
  9.         this.Load += new EventHandler(BasePage_Load);   
  10.     }   
  11.   
  12.     //对登录进行验证   
  13.     protected void BasePage_Load(object sender,EventArgs e)   
  14.     {   
  15.         if (Session["uid"] == "" || Session["uid"] == null)   
  16.         {   
  17.             Response.Redirect("~/login.aspx");   
  18.         }   
  19.     }   
  20. }  

 

  

C#代码 复制代码 收藏代码
  1. public partial class Default3 : ValidateLogin //继承自ValidateLogin类  
  2. {   
  3.     protected void Page_Load(object sender, EventArgs e)   
  4.     {   
  5.           //继承自ValidateLogin类,实现继承身份验证   
  6.     }   
  7. }  

 

 

在.net内部存在一些默认机制,具体说来有如下:
(1)如果类的实例字段没有赋初始值,那么它们就会被赋默认值,对于引用类型字段的默认值为null,对于简单值类型字段(即数值类型)默认值为对应形式的0(如sbyte、byte、short、ushort、int、uint、long 和 ulong都是0,而char类型字段的默认值值是’\0x0000’,float类型字段是0.0f,double类型字段是0.0d等等)。


(2)如果类中赋初值的静态字段,那么自动生成一个静态构造函数,在静态函数中完成赋初值。


(3)如果一个类没有明确指明派生自哪个类,默认会派生自Object类。


(4)如果一个类没有定义任何构造函数,默认会给该类生成一个构造函数。


(5)在调用子类的非静态构造函数的时候,默认会调用父类的构造函数。例如A继承B,B继承C,C没有明确指明继承哪个类(实际上是继承Object),那么在实例化A的时候,会首先调用B的构造函数,在调用的构造函数的时候又会调用C的构造函数,在调用C的构造函数的时候又会去调用Object的构造函数,因此实例化一个A对象时,在内部会经历一连串的构造函数调用,就上面的继承层次来说,构造函数的调用顺序从先到后依次为:object->C->B->A。
下面这部分代码可以演示这个演示这个过程:

 

C#代码 复制代码 收藏代码
  1. using System;      
  2.      
  3. public class C      
  4. {      
  5.     public C()      
  6.     {      
  7.         Console.WriteLine("C");      
  8.     }      
  9. }      
  10. public class B:C      
  11. {      
  12.     public B()      
  13.     {      
  14.         Console.WriteLine("B");      
  15.     }      
  16. }      
  17. public class A:B      
  18. {      
  19.     public A()      
  20.     {      
  21.         Console.WriteLine("A");      
  22.     }      
  23. }      
  24.      
  25. public class Demo:A      
  26. {      
  27.     static int d=5;      
  28.     public Demo()      
  29.     {      
  30.     }      
  31.     public static void Main()      
  32.     {      
  33.         Demo d = new Demo();      
  34.         Console.ReadLine();      
  35.     }      
  36. }    

 

将上面程序编译成控制台应用程序,执行会得到如下结果:

 

 

如果将生成的Demo.exe文件用ILDASM.exe打开的话,会看到如下情形:

 

 

上面说的这些都不是我今天要说的重点,不过我们可以它们来实现一些功能。在早期的时候我开发项目的时候,做后台身份控制的时候总是觉得比较麻烦,每页都会写检查用户是否登录的代码,后来asp.net2.0出来之后就使用了母板页,这样对用户的身份验证就可以在母板页中的Load事件中来控制。这样虽然能完成功能,不过由于母板页的Load事件是晚于内容页的Load事件的,所以这个时候验证用户身份可以看到页面上的部分内容了。

利用上面的第(5)个机制,就可以比较好的解决这个问题。我们可以首先定义一个后台所有需要进行身份验证的页的基类,这个基类继承自System.Web.UI.Page类(因为在asp.net中所有的asp.net页所对应的类必须直接或者简介继承自System.Web.UI.Page类)。我们直到当访问一个页面的时候,肯定要实例化这个页面对应的类,由于内部机制必须要首先调用我们编写的基类中定义的构造方法(如果有的话,然后又鸡生蛋、蛋生鸡一样地追朔到object类,不过那些我们不用管)。我们要下手的话,就应该在这个我们自定义的基类的构造方法里面。这时候有两种选择:

一是直接在基类的构造函数进行身份验证,比如在基类构造函数里检查Cookie或者Session集合中是否存在某个特定的名称的Session或者Cookie(用Session或者用Cookie或者二者兼用取决于具体项目要求),这个特定名称的Session或者Cookie是当用户登录了后台时才会设定的,因此只要存在这个Cookie或者Session就可以判断用户是登录过的。

二是再利用一些机制来做,比如在基类的构造函数中再利用一个asp.net页面的生命周期中必经的事件来进行处理。比如这个在构造函数中定义基类的某个事件的处理方法,在这个处理方法中进行身份判断。
我记得有人说过这么一句话:“最直接的方法往往是最难的方法。”上面的办法中,第一种是实现不了的,因为构造函数调用的时候,很多信息刚刚被初始化,有很多还没有被初始化,在基类的构造方法中Session和Cookie都是没有被实例化的。


看来只有用第二种办法了,看过《asp.net夜话之五:Page类和回调技术》之五的朋友应该有印象,所有的Page类都会经历一个加载事件,我们就选择在基类的构造函数中定义基类的加载事件的处理方法,在这个方法里检查用户是否登录。至于为什么要选择这个事件而不用其它事件,那是因为有些事件发生得还是太早,怕Session和Cookie还是不可用,有些事件又太晚,用加载事件是刚刚好(郭德钢有一首歌正好叫《刚刚好》,呵呵)。
因为我们的这个基类没有任何显示部分代码,所以我们可以在项目中添加一个类文件,代码如下:

C#代码 复制代码 收藏代码
  1. using System;      
  2. using System.Data;      
  3. using System.Configuration;      
  4. using System.Web;      
  5. using System.Web.Security;      
  6. using System.Web.UI;      
  7. using System.Web.UI.WebControls;      
  8. using System.Web.UI.WebControls.WebParts;      
  9. using System.Web.UI.HtmlControls;      
  10.      
  11. /// <summary>      
  12. /// AdminPage是后台所有需要身份验证的页的基类      
  13. /// </summary>      
  14. public class AdminPage:System.Web.UI.Page      
  15. {      
  16.     public AdminPage()      
  17.     {      
  18.         //处理加载事件      
  19.         this.Load += new EventHandler(AdminPage_Load);      
  20.     }      
  21.      
  22.     void AdminPage_Load(object sender, EventArgs e)      
  23.     {      
  24.         //假设用户登录成功之后会设置一个名为“UserInfo”的Session     
  25.         //假设用户登录页面login.aspx位于网站根目录下的Admin文件下     
  26.         if (Session["UserInfo"] == null)      
  27.         {      
  28.             //使用~来保证无论在什么目录层次进行身份验证都能跳转到后台登录页面     
  29.             Response.Redirect("~/Admin/Login.aspx");      
  30.         }      
  31.     }      
  32. }    

 

这样,对于后台任何需要进行身份验证的页面,只需将它更改为继承自AdminPage类即可,这样这些类中就不需要编写任何身份验证的代码了。


如下,就是一个类的代码,这里没有任何手动编写的代码,却已经能实现验证了,因为它继承自AdminPage类:

 

C#代码 复制代码 收藏代码
  1. using System;      
  2. using System.Data;      
  3. using System.Configuration;      
  4. using System.Collections;      
  5. using System.Web;      
  6. using System.Web.Security;      
  7. using System.Web.UI;      
  8. using System.Web.UI.WebControls;      
  9. using System.Web.UI.WebControls.WebParts;      
  10. using System.Web.UI.HtmlControls;      
  11.      
  12. public partial class Admin_News_Index : AdminPage      
  13. {      
  14.     protected void Page_Load(object sender, EventArgs e)      
  15.     {      
  16.      
  17.     }      
  18. }    

 

对上面的处理方法还可以进一步处理,比如某些页面不光要求用户必须登录,还要求用户必须具有相关权限,读者朋友可以利用这种思想去实现。此外,还可以利用这种机制做一些其它的业务处理。

0 0