·您现在的位置: 云翼网络 >> 文章中心 >> 网站建设 >> 网站建设开发 >> ASP.NET网站开发 >> 从零开始编写自己的C#框架(19)——Web层后端权限模块

从零开始编写自己的C#框架(19)——Web层后端权限模块

作者:佚名      ASP.NET网站开发编辑:admin      更新时间:2022-07-23

从零开始编写自己的C#框架(19)——Web层后端权限模块

  不知不觉本系统写了快三个月了,最近写页面的具体功能时感觉到有点吃力,很多地方如果张嘴来讲的话可以说得很细,很全面,可写成文字的话,就不太会写了,有些地方想讲得清晰的话,得用多几倍的文字+实例+变化中的图片才能表达得清楚,而写这些又太费时间了,近段时间又特忙,所以只能是尽力而为,希望大家自行研究,如果有什么地方不明白的,发发评论或邮件给我,我再重新详细讲解。

  说回正题,对于页面访问权限以及每个按键的权限控制,很久以前用过好几种不同的方法,比如为每个控件分配名称或编码,然后在写代码时绑定这些值,又比如用xml来配置制权限等方法。这些方法都比较麻烦,而且由于都是使用编码方法,开发时需要一个个进行绑定,容易出错。经过后来不断的完善,最后完成了本系统所采用的页面控件注册管理来绑定控件权限(如有雷同,纯属巧合,哈哈...),首先创建菜单,并绑定好对应的文件(页面),然后将系统要用到的名称添加到公用标识库中,跟着在页面控件权限管理页面对各个页面控件进行绑定(只需要点击鼠标即可),通过职位(角色)来赋于不同的操作权限,只需要设置好管理员的职位,那么该管理员就拥有他所绑定的角色的全部权限了。

  如下面的说明

  首先在后端注册菜单(菜单绑定页面)

  创建公用页面权限标识,待用

  为需要绑定页面控件权限的菜单页面绑定操作控件(左列为上图录入的公共控件名称,右列为已绑定的页面控件,只需要点击鼠标就可以轻松绑定)

  创建好部门

  在不同部门创建相应的职位(角色)

  为不同角色设置菜单与页面控件操作权限

  开发说明:(主要讲讲与上一章中不同的内容)

  1、PagePowerSignPublicList.aspx.cs 公用页面控件权限标识列表管理文件

  这个页面是比较经典的普通列表页面,比较代码,有以下一些地方和菜单页面不一样的

 1         #region 加载数据 2         /// <summary>读取数据</summary> 3         public override void LoadData() 4         { 5             //设置排序 6             if (sortList == null) 7             { 8                 Sort(null); 9             }10 11             //绑定Grid表格12             bll.BindGrid(Grid1, Grid1.PageIndex + 1, Grid1.PageSize, null, sortList);13         }14 15         #endregion

  对于排序函数的调用,菜单页面是有层次感列表,所以要自定义排序函数,而对于正常的列表,我们直接调用父类的Sort(null)函数即可

  绑定Grid表格也与菜单页面调用的不一样,bll.BindGrid()函数使用的是参数中需要添加当前在第几页,每个页面显示多少行,null是条件参数,后面会详细解释它怎么使用,最后一个参数是排序规则参数

  另外,Delete()删除函数也使用批量删除功能,不过会在删除前进行检查,发现指定记录不能删除时,则弹出提示是那个Id的记录无法删除,大家自行比较一下两个列表文件就明白了。

  2、PagePowerSignPublicEdit.aspx.cs公用页面控件权限标识编辑文件

  这个文件要注意的地方是Save()函数

 1         #region 保存 2         /// <summary> 3         /// 数据保存 4         /// </summary> 5         /// <returns></returns> 6         public override string Save() 7         { 8             string result = string.Empty; 9             int id = ConvertHelper.Cint0(hidId.Text);10 11             try12             {13                 #region 数据验证14 15                 if (string.IsNullOrEmpty(txtCName.Text.Trim()))16                 {17                     return txtCName.Label + "不能为空!";18                 }19                 var sName = StringHelper.Left(txtCName.Text, 20);20                 if (PagePowerSignPublicBll.GetInstence().Exist(x => x.CName == sName && x.Id != id))21                 {22                     return txtCName.Label + "已存在!请重新输入!";23                 }24                 if (string.IsNullOrEmpty(txtEName.Text.Trim()))25                 {26                     return txtEName.Label + "不能为空!";27                 }28                 var sEname = StringHelper.Left(txtEName.Text, 50);29                 if (PagePowerSignPublicBll.GetInstence().Exist(x => x.EName == sEname && x.Id != id))30                 {31                     return txtEName.Label + "已存在!请重新输入!";32                 }33 34                 #endregion35 36                 #region 赋值37                 //定义是否更新标识——即当前记录的名称是否改变了38                 bool isUpdate = false;39 40                 //获取实体41                 var model = new PagePowerSignPublic(x => x.Id == id);42 43                 //判断是否有改变名称44                 if (id > 0 && (sName != model.CName || sEname != model.EName))45                 {46                     isUpdate = true;47                 }48 49                 //设置名称50                 model.CName = sName;51                 //设置英文名称52                 model.EName = sEname;53                 #endregion54 55                 //----------------------------------------------------------56                 //存储到数据库57                 PagePowerSignPublicBll.GetInstence().Save(this, model);58 59                 //判断是否需要同步更新关联表字段60                 if (isUpdate)61                 {62                     //调用更新函数,同步更新对应的所有记录63                     PagePowerSignBll.GetInstence().UpdateValue_For_PagePowerSignPublic_Id(this, model.Id, PagePowerSignTable.CName, model.CName, PagePowerSignTable.EName, model.EName);64                 }65             }66             catch (Exception e)67             {68                 result = "保存失败!";69 70                 //出现异常,保存出错日志信息71                 CommonBll.WriteLog(result, e);72             }73 74             return result;75         }76         #endregion
View Code

  在函数中,大家可以找到下面这些代码

 1   //定义是否更新标识——即当前记录的名称是否改变了 2   bool isUpdate = false; 3  4   //判断是否有改变名称 5   if (id > 0 && (sName != model.CName || sEname != model.EName)) 6   { 7     isUpdate = true; 8   } 9 10   //判断是否需要同步更新关联表字段11   if (isUpdate)12   {13     //调用更新函数,同步更新对应的所有记录14     PagePowerSignBll.GetInstence().UpdateValue_For_PagePowerSignPublic_Id(this, model.Id, PagePowerSignTable.CName, model.CName, PagePowerSignTable.EName, model.EName);15   }

  这是用于我们修改A表记录的名称时,同步修改其他关联表引用了这个记录名称字段的所有记录

  为什么要这么处理呢?大家在看数据字典的数据库结构时,会发现很多表与其他表关联时,不单将其他表的Id引用了过来,还将这个Id对应的名称也引用了,这种操作方式使我们在编写查询语句时,几乎可以做到不用多表关联,因为我们想要显示的内容已经在查询的表中存在了,这样处理后,我们在修改相关表的名称时,就必须同步修改关联表中的名称,对于这些关联表名称的修改,我们的T4模板也生成了相应的函数,如:UpdateValue_For_表名_Id()函数,然后直接按上面代码编写方法实现就可以了。

  3、UseLogList.aspx.cs用户操作日志管理文件

  这个文件要注意的是InquiryCondition()函数

 1         /// <summary> 2         /// 查询条件 3         /// </summary> 4         /// <returns></returns> 5         PRivate List<ConditionHelper.SqlqueryCondition> InquiryCondition() 6         { 7             var wheres = new List<ConditionHelper.SqlqueryCondition>(); 8  9             //如果Id有值时,即表示查询的是指定管理员的操作日志10             if (_id != 0)11             {12                 wheres.Add(new ConditionHelper.SqlqueryCondition(ConstraintType.Where, LoginLogTable.Manager_Id, Comparison.Equals, _id));13             }14 15             //起始时间16             if (!string.IsNullOrEmpty(dpStart.Text.Trim()))17             {18                 wheres.Add(new ConditionHelper.SqlqueryCondition(ConstraintType.And, LoginLogTable.AddDate, Comparison.GreaterOrEquals, StringHelper.FilterSql(dpStart.Text)));19                 //终止时间20                 if (!string.IsNullOrEmpty(dpEnd.Text.Trim()))21                 {22                     wheres.Add(new ConditionHelper.SqlqueryCondition(ConstraintType.And, LoginLogTable.AddDate, Comparison.LessOrEquals, StringHelper.FilterSql(dpEnd.Text)));23                 }24             }25 26             //ip地址27             if (!string.IsNullOrEmpty(txtIp.Text.Trim()))28             {29                 wheres.Add(new ConditionHelper.SqlqueryCondition(ConstraintType.And, LoginLogTable.Ip, Comparison.Equals, StringHelper.FilterSql(txtIp.Text)));30             }31             //登录备注信息32             if (!string.IsNullOrEmpty(txtloginfo.Text.Trim()))33             {34                 wheres.Add(new ConditionHelper.SqlqueryCondition(ConstraintType.And, LoginLogTable.Notes, Comparison.Like, "%" + StringHelper.FilterSql(txtloginfo.Text) + "%"));35             }36 37             return wheres;38         }

  这是查询条件函数,ConditionHelper.SqlqueryCondition这个类是自定义封装条件类

  它的构造函数(public SqlqueryCondition(ConstraintType ctype, string columnname, Comparison cparsion, object value, bool isParent