通用权限系统设计——第四章
今天我们讲解第四章,前三章,我们是通过数据库把所有用到的权限的数据库表都已经全部,该用到的视图也一并说明。从第四章开始,我们将结合程序来实现权限的分配,和设计。
首先我们先用vs2011建立一个《web应用程序》程序,前期结构如下:
然后添加:实体、业务逻辑、和数据访问层的代码。这里我要说明一下,由于本人的习惯,一般不会使用DataTable和DataSet,所以我讲视图做完一张表,建立相应的实体、业务和数据访问层。搭建完成之后就开始正式编码了。
由于出于演示,代码编写不是很严格,界面不是很美观,请大家见谅!
首先是模块的问题:
在一般的系统中,系统中的模块基本上是完全固定的,在程序编写完成之后,模块也就完成了,也就是说,数据库中的Modules表中的数据就不会发生什么变化了。所以,在我们系统第一次运行的时候,我们将所有的模块将保持到静态变量来保存,片段代码如下:
首先声明一个静态变量来保持模块
/// <summary> /// 保存系统所有模块 /// </summary> public static List<Entity.ModuleInfo> objModuleList = new List<Entity.ModuleInfo>(); //然后在Global.asax中加上这段代码 void Application_Start(object sender, EventArgs e) { // 在应用程序启动时运行的代码,获取系统说有的模块 if(Config.GlobalConfig.objModuleList == null || Config.GlobalConfig.objModuleList.Count<= 0) { Config.GlobalConfig.objModuleList= new BLL.ModuleBLL().GetModuleList(); } }
同样保存系统中的模块也可以用缓存来做,在这里,我就用这种方式来做,相对来说简单一点,这种也是一种缓存。
在做完这些工作之后,我们现在来讲解系统登录,登录之后,我们首先要保登录用户的信息,这里我分别用了两种方式来保存,一种是cookie另一种是session,cookie是保存用户编号,而session是保存整个用户对象(UserInfo),这里为什么需要用两种方式来保存了,可能是我庸人自扰了,因为我担心客户端可能禁用cookie的情况就是用session,但是session又极不稳定,所以我这里用到了两种情况。当然,我首先取值是从cookie里面取值的。
片段代码如下:
/// <summary> /// 用户登录 /// </summary> private void ValidataUser() { string userName = this.txtUserName.Text.Trim(); string password = this.txtPassword.Text.Trim(); UserInfo objInfo = new UserInfo(); objInfo = newBLL.UserBLL().ValidataUser(userName,password); if(objInfo != null && objInfo.UserID >0) { //保存用户编号 (这里应该加密,但是我这里先省略) CookieHelper.SetCookie(GlobalConfig.CookieUserID,objInfo.UserID.ToString(), DateTime.Now.AddHours(1)); //万一Cookie禁用,就用session Session[GlobalConfig.SessionUserInfo] = objInfo; //记住用户名 if(this.RememberMe.Checked) { //设置保存用户名7天 (这里应该加密,但是我这里先省略) CookieHelper.SetCookie(GlobalConfig.RememberMe, userName, DateTime.Now.AddDays(7)); } else { CookieHelper.Remove(GlobalConfig.RememberMe); } //登录成功跳转 Response.Redirect("~/Default.aspx"); } else { MessageBox.Show(this.Page, "用户名或密码错误!"); } }
登录完成之后,整体效果如下:
现在来说说登录之后,模块的问题:
首先当系统初次运行的时候,整个系统中的模块就已经获取了,现在我们做的就是根据用户的所属角色,获取用户的所属的模块。
获取用户的模块片段代码如下:
/// <summary> /// 根据登录用户角色编号,获取模块 /// </summary> /// <paramname="roleId">角色编号</param> /// <returns>List</returns> private List<ModuleInfo> GetModuleList(string roleId) { List<int> objList = newList<int>(); //根据用户编号,获取对应的模块编号 objList = newBLL.RoleBLL().GetRoleIdByModuleID(roleId); List<ModuleInfo> objModuleList = new List<ModuleInfo>(); foreach(var item inobjList) { //GlobalConfig.objModuleList获取相应的模块 objModuleList.Add(GlobalConfig.objModuleList.Find(T => T.ModuleID== item)); } if(objModuleList == null || objModuleList.Count<= 0) return null; return objModuleList; }
系统中的模块详细都是从GlobalConfig.objModuleList变量中得到。
登录完成之后,所有需要登录之后可以看到的页面,都继承BasePage类,此类中,有验证用户是否已经登录的相关验证,还有就是里面得到用户信息的相关变量。
片段代码如下:
/// <summary> /// 用户编号 /// </summary> public int UserID { get { UserInfo objInfo = new UserInfo(); stringid = CookieHelper.GetCookie(GlobalConfig.CookieUserID); if(!string.IsNullOrEmpty(id)) { objInfo = new BLL.UserBLL().GetUserEntity(Convert.ToInt32(id)); return objInfo.UserID; } else { if(Session[GlobalConfig.SessionUserInfo] != null) { objInfo = Session[GlobalConfig.SessionUserInfo] asUserInfo; return objInfo.UserID; } else { return 0; } } } } /// <summary> /// 用户信息 /// </summary> public UserInfo Users { get { if(this.UserID > 0) { return new BLL.UserBLL().GetUserEntity(this.UserID); } else { if(Session[GlobalConfig.SessionUserInfo] != null) { return Session[GlobalConfig.SessionUserInfo]asUserInfo; } else { return null; } } } } /// <summary> /// 角色名称 /// </summary> public string RoleName { get { List<UserRoleInfo> objList = new List<UserRoleInfo>(); objList = new BLL.UserRoleBLL().GetUserRoleList(this.UserID); if(objList == null || objList.Count <= 0) return null; string str = string.Empty; foreach(var item inobjList) { str += item.RoleName + ","; } returnstr.TrimEnd(','); } }
由于基本的数据库查询,我都做了相对应的缓存,所以不必担心反复的读取数据库。
今天的编写先告一段落,一遍写这个文档,一遍写代码,实在是太难受了。由于代码完成量比较少,先不给大家源码了,等到下下章看看能不能给到大家源码,下章开始讲解 权限控件,预计拿两个章节来说,敬请期待!
最后献上四个不同角色的用户登录效果:
Admin
Admin1
Admin2
Admin3