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

 

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

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

  如下面的说明

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

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

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

  创建好部门

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

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

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

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

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

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

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

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

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

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

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

 

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

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

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

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

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

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

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

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

  它的构造函数(public SqlqueryCondition(ConstraintType ctype, string columnname, Comparison cparsion, object value, bool isParentheses = false))一共有5个参数,其中4个为必填参数

  第一个参数ConstraintType ctype为查询的类型,主要是ConstraintType.Where、ConstraintType.And、ConstraintType.Or三种。

    如果有多个条件时,ConstraintType.Where只能放在最前面,且只能有一个条件使用这个参数,一般都很少用它。

    ConstraintType.And指的是当前参数与前面参数的关系是And关系

    ConstraintType.Or通常情况下指的是当前参数与前面参数的关系是Or关系

  第二个参数string columnname是条件列字段名称

  第三个参数Comparison cparsion是表达式,使用Comparison.X来设置,根据需求设置==、>、>=、<、<=、like、in、not in......

  第四个参数object value是条件值,如果是in与not in表达式时,条件值必须为数据类型,比如:string[]、int[]、object[]等

  第五个参数bool isParentheses是加左括号,而右括号使用new ConditionHelper.SqlqueryCondition()或new ConditionHelper.SqlqueryCondition(Comparison.CloseParentheses)来添加,然后in或not in表达式时,必须紧跟着右括号

  例子1:

  (A>2 Or A<= 10) And B=100

  1. 1   var wheres = new List<ConditionHelper.SqlqueryCondition>();
  2. 2
  3. 3   wheres.Add(new ConditionHelper.SqlqueryCondition(ConstraintType.Where, "A", Comparison.GreaterThan, 2, true));
  4. 4
  5. 5   wheres.Add(new ConditionHelper.SqlqueryCondition(ConstraintType.Or, "A", Comparison.LessOrEquals, 10));
  6. 6
  7. 7   wheres.Add(new ConditionHelper.SqlqueryCondition());
  8. 8
  9. 9   wheres.Add(new ConditionHelper.SqlqueryCondition(ConstraintType.And, "B", Comparison.Equals, 100));

  例子2:

  A == 2 And B in arr And C like 'abc%' (in查询必须加左右括号)

  1. 1   var wheres = new List<ConditionHelper.SqlqueryCondition>();
  2. 2
  3. 3   wheres.Add(new ConditionHelper.SqlqueryCondition(ConstraintType.Where, "A", Comparison.Equals, 2));
  4. 4   //加左括号
  5. 5   wheres.Add(new ConditionHelper.SqlqueryCondition(ConstraintType.And, "B", Comparison.In, arr, true));
  6. 6   //加右括号
  7. 7   wheres.Add(new ConditionHelper.SqlqueryCondition());
  8. 8
  9. 9   wheres.Add(new ConditionHelper.SqlqueryCondition(ConstraintType.And, "C", Comparison.Like, "abc%"));

  这个封装类最终会生成SubSonic3.0底层调用的条件参数,经过测试发现,SubSonic3.0底层调用的条件参数只支持单括号,不支持括号的嵌套,多重嵌套后最终生成的也只是单括号且会出错,所以多重嵌套括号时,最好使用其它方法来实现,比如Linq、存储过程、SQL语句拼接等。

  4、小结

  本次更新的代码功能比如多,已将部门、职位、公用页面控件权限标识、页面控件权限管理、在线用户列表、用户登陆日志、用户操作日志、错误日志等功能都已完成了,同时也对在线用户相关类和函数进行了优化处理。

  内容看起来好像挺多了,其实都是对之前所写的模板函数以及其他公共函数的调用,这么多页面查看cs代码时可以发现,里面的内容都差不多,都是很格式化的东西,如果你尝试过用这些已完成的模板页面添加新功能,就可以发现很简单,开发也很迅速。

  至于每个页面如何去实现,接下来就不必再像之前那样讲得很细致了,会针对一些特殊功能或函数的调用进行解说,往细讲也只能从逻辑层的各个函数应用来说起,所以就不再罗嗦一一细说,代码中有大量的注释,大家慢慢研究吧。

  最好附上几张页面的效果图

Web层后端权限模块.rar

 版权声明:

  本文由AllEmpty原创并发布于博客园,欢迎转载,未经本人同意必须保留此段声明,且在文章页面明显位置给出原文链接,否则保留追究法律责任的权利。如有问题,可以通过1654937@qq.com 联系我,非常感谢。

  发表本编内容,只要主为了和大家共同学习共同进步,有兴趣的朋友可以加加Q群:327360708 ,大家一起探讨。

  更多内容,敬请观注博客:http://www.cnblogs.com/EmptyFS/

只有将自己置空,才能装进更多的东西 

Web层后端权限模块的更多相关文章

  1. 从零开始编写自己的C#框架(18)——Web层后端权限模块——菜单管理

    从本章开始,主要讲解的是页面中对框架相关功能的调用方法,比如列表页面(又分为有层次感列表和普通列表).编辑页面.多标签页面等,只要熟悉了这些函数的使用方法,那么开发起来就会很便捷了. 1.如图先创建菜 ...

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

    不知不觉本系统写了快三个月了,最近写页面的具体功能时感觉到有点吃力,很多地方如果张嘴来讲的话可以说得很细,很全面,可写成文字的话,就不太会写了,有些地方想讲得清晰的话,得用多几倍的文字+实例+变化中的 ...

  3. 从零开始编写自己的C#框架(16)——Web层后端父类

    本章节讲述的各个类是后端系统的核心之一,涉及到系统安全验证.操作日志记录.页面与按键权限控制.后端页面功能封装等内容,希望学习本系列的朋友认真查看新增的类与函数,这对以后使用本框架进行开发时非常重要. ...

  4. 从零开始编写自己的C#框架(17)——Web层后端首页

    后端首页是管理员登陆后进入的第一个页面,主要是显示当前登陆用户信息.在线人数.菜单树列表.相关功能按键和系统介绍.让管理员能更方便的找到息想要的内容. 根据不同系统的需要,首页会显示不同的内容,比如显 ...

  5. 从零开始编写自己的C#框架(15)——Web层后端登陆功能

    对于一个后端管理系统,最重要内容之一的就是登陆页了,无论是安全验证.用户在线记录.相关日志记录.单用户或多用户使用帐号控制等,都是在这个页面进行处理的. 1.在解决方案中创建一个Web项目,并将它设置 ...

  6. 微服务迁移记(五):WEB层搭建(4)-简单的权限管理

    一.redis搭建 二.WEB层主要依赖包 三.FeignClient通用接口 以上三项,参考<微服务迁移记(五):WEB层搭建(1)> 四.SpringSecurity集成 参考:< ...

  7. Web应用程序系统的多用户权限控制设计及实现-权限模块【10】

    前五章均是从整体上讲述了Web应用程序的多用户权限控制实现流程,本章讲述Web权限管理系统的权限配置模块.页面模块涉及到的数据表为权限表.权限配置模块是按照用户组和页面,栏目结合组成的.通过配置一个用 ...

  8. C#进阶系列——DDD领域驱动设计初探(七):Web层的搭建

    前言:好久没更新博客了,每天被该死的业务缠身,今天正好一个模块完成了,继续来完善我们的代码.之前的六篇完成了领域层.应用层.以及基础结构层的部分代码,这篇打算搭建下UI层的代码. DDD领域驱动设计初 ...

  9. Web层的搭建

    Web层的搭建 前言:好久没更新博客了,每天被该死的业务缠身,今天正好一个模块完成了,继续来完善我们的代码.之前的六篇完成了领域层.应用层.以及基础结构层的部分代码,这篇打算搭建下UI层的代码. DD ...

随机推荐

  1. JS数组学习笔记

    原文:JS数组学习笔记 最近在备课数组,发现很多ES5的方法平时很少用到.细节比较多,自己做了大量例子和整理,希望对大家了解JavaScript中的Array有所帮助. 概念 数组是值的有序集合.每个 ...

  2. 嘿嘿。今天学习了AJAX的几个方法

    原文:嘿嘿.今天学习了AJAX的几个方法 今天学习了AJAX的几个方法,其实我很早在公司实习的时间就认识了它,但是对它一无所知,也并没有去学习它,今天学习它让我感到很兴奋因为重新了解了它,嘿嘿,下面就 ...

  3. 怎样改动、扩展并重写Magento代码

    作为一个开发人员的你,肯定要改动Magento代码去适应你的业务需求,可是在非常多时候我们不希望改动Magento的核心代码,这里有非常多原因, 比如将来还希望升级Magento.还想使用很多其它的M ...

  4. UVA11080- Place the Guards(二分图染色)

    题目链接 题意:放最少的士兵去监视全部的道路, 但士兵不可相邻,符合的话,就输出最少的士兵数,否则输出-1 思路:事实上就是二分图染色,即黑白染色,然后选择黑白染色最少的那个颜色累加,但要注意可能有多 ...

  5. wikioi 1002 旁路

    意甲冠军:这个问题刚开始的问题,有错误的含义,原桥始建于一条直线.无论多么遥远. 思维:dfs寻求答案的第一个问题.然后做最小生成树,双方不能大桥将设置INF即可了.然后假设用到INF的边就加上0即可 ...

  6. DropDownListFor使用ViewData进行绑定的示例

    特别注意,经实践: 此方法的ViewBag的名称必须和new SelectList()中的最后一个参数,即下拉框的默认值的名称必须相同,如: ViewBag.Title = WebConst.UnSe ...

  7. ASP.NET MVC+EF框架+EasyUI实现权限管理系列(21)-用户角色权限基本的实现说明

    原文:ASP.NET MVC+EF框架+EasyUI实现权限管理系列(21)-用户角色权限基本的实现说明     ASP.NET MVC+EF框架+EasyUI实现权限管系列 (开篇)   (1):框 ...

  8. POJ 3013 Big Christmas Tree(最短Dijkstra+优先级队列优化,SPFA)

    POJ 3013 Big Christmas Tree(最短路Dijkstra+优先队列优化,SPFA) ACM 题目地址:POJ 3013 题意:  圣诞树是由n个节点和e个边构成的,点编号1-n. ...

  9. csdn 博客,你很努力,有人帮你-2015年03一个月17日本

    今天泛化 开始使用简书 正则表达式的博客写了两篇文章 回顾 Core Data 基本使用 总结 Xcode6新特性 简单聊聊 简书,事实上一開始学 MarkDown 语法的时候,已经用了,但是,一直认 ...

  10. Swift # 柯里化函数

    前言 此次文章,讲述的是Swift的一个新特性(柯里化函数),可能很多iOS开发人员是第一次听这个词汇,包括我自己也是,自己也用了几天时间才总结出来,希望能帮助到各位咯,个人感觉偏向有开发经验的码友, ...