从零开始编写自己的C#框架(16)——Web层后端父类
本章节讲述的各个类是后端系统的核心之一,涉及到系统安全验证、操作日志记录、页面与按键权限控制、后端页面功能封装等内容,希望学习本系列的朋友认真查看新增的类与函数,这对以后使用本框架进行开发时非常重要。
1、父类(基类)的实现
在开发后端首页与相关功能页面前,我们首先要实现的是所有页面的基类(父类),将常用的功能都预先实现出来,而后面的相关UI类则直接继承它,这样就能简单的自动实现了相关页面功能,不用再每个页面去编写某些按键功能或其他一些功能,如果有特殊的需要,再重写对应的功能类就可以了,对于常用功能,由于之前的逻辑层与数据层已使用模板生成好了,所以直接调用,这样的话比如实现一个列表页面的一些功能(如下图),只需要简单的在页面控件使用指定名称,那么一些实现代码就不用再编写了,这些控件自动拥有对应的功能,比如刷新、自动排序、保存排序(直接修改下图中排序列的输入框后点击保存排序就可以了,这个功能不用编写任何一个代码,只需要将按键放到下图位置,然后使用指定名称就可以了)等功能。这样操作将使我们后面的开发工作更加轻松。而对于列表的话,也只需要调用逻辑层函数直接绑定(bll.BindGrid(this, Grid1, Grid1.PageIndex + 1, Grid1.PageSize, InquiryCondition(), _order);)就可以实现列表、分页、翻页、排序等功能。当然列表点击审核的√与×就会同步更改数据库对应记录的字段与图标,也只需要在列表控件对应函数复制进简单的几行代码就可以实现,这些会在后面相应章节中具体讲述。
先上父类与接口代码
有朋友可能会有疑问,为什么本类要用abstract修饰成抽象类,而实现类中只有接口Init()函数是抽象函数,这样设置主要是强制要求Init()函数在子类中必须实现,因为在开发过程中,不这样强制的话,一些页面开发时很容易忘记去给父类的相关对象赋值,那么父类中的一些功能在调用时就无法正常运行。
代码中的OnInit()函数,在页面启动的时候会调用到,主要用于检查用户登陆情况,用户是否有当前页面的访问权限和页面按键的使用权限,记录用户访问记录,以及运行UI页面初始化函数,方便父类相关函数功能的调用(比如保存排序、分页等功能)。
另外,预先定义好了页面各种常用按键事件,只要在页面里放置这些按键,就可以自动调用这些事件功能,部分按键功能已实现的就不用再编写代码,未实现的则直接重写对应的虚函数,就可以达到想要的效果。
而虚函数,大多都没有实现其功能的代码,可能有朋友会说,为什么不用接口呢?呃......在这里再重新说明一下,定义成接口的话就必须要去实现,而对于多数页面来说,并不一定要用到这个功能,那么这些页面代码看起来就很罗嗦,充斥大量无用代码,可读性就会非常的差,而用虚方法只是放在那里就可以了,需要使用时才去重写,这样操作会比较灵活,页面代码看起来也非常整洁干净。
由于下面不少功能都是重新沟思后编写的,所以可能会存在一些不合理的地方,且未经过运行测试,以后会根据情况进行增删。
2、逻辑层添加了接口,且抽象类实现这个接口并增加对应的抽象函数
为了方便上面父类的调用,减少重复代码的编写,在逻辑层增加了接口类ILogicBase,而原来的逻辑层抽象类LogicBase(所有模板都必须继承的类)也实现了该接口
原来的模板根据需要也对应做出了相应调整
我们在第1点时不是强制要求实现Init()函数吗,这里就是主要为PageBase类(父类)的逻辑层接口赋值用的。
比如我们要实现一个信息列表的功能,由于我们的逻辑层都继承了ILogicBase类,所以我们只要在Init()函数中给PageBase类的protected ILogicBase bll = null;这个定义重新赋值就可以了,那么在执行下面代码时就会通过这个接口的调用来执行对应类的功能
在Init()初始化函数中,给逻辑层对象赋值例子
1 using System; 2 using Solution.Logic.Managers; 3 using Solution.Web.Managers.WebManage.Application; 4 5 namespace Solution.Web.Managers 6 { 7 public partial class WebForm1 : PageBase 8 { 9 protected void Page_Load(object sender, EventArgs e) 10 { 11 12 } 13 14 15 #region 接口函数,用于UI页面初始化,给逻辑层对象、列表等对象赋值 16 /// <summary> 17 /// 接口函数,用于UI页面初始化,给逻辑层对象、列表等对象赋值 18 /// </summary> 19 public override void Init() 20 { 21 //给逻辑层对象赋值 22 bll = InformationBll.GetInstence(); 23 //给表格赋值 24 grid = Grid1; 25 } 26 #endregion 27 } 28 }
PageBase类执行逻辑层程序代码——实际上这些代码可以再次进行封装成一个公共函数,不过都是用模板生成的,有变动不用一个个改就懒得再重构了
1 /// <summary> 2 /// 保存排序 3 /// </summary> 4 /// <returns>返回保存结果</returns> 5 public virtual void SaveSort() 6 { 7 //保存排序 8 if (grid != null && bll != null) 9 { 10 //更新排序 11 if (bll.UpdateSort(this, grid, "tbxOrderID")) 12 { 13 //重新加载列表 14 LoadData(); 15 16 Alert.ShowInParent("操作成功", "保存排序成功", "window.location.reload();"); 17 } 18 else 19 { 20 Alert.ShowInParent("操作成失败", "保存排序失败", "window.location.reload();"); 21 } 22 } 23 } 24 25 /// <summary> 26 /// 保存自动排序 27 /// </summary> 28 public virtual void SaveAutoSort() 29 { 30 if (bll == null) 31 { 32 Alert.ShowInParent("保存失败", "逻辑层对象为null,请联系开发人员给当前页面的逻辑层对象赋值"); 33 return; 34 } 35 36 if (bll.UpdateAutoSort(this, "", true)) 37 { 38 Alert.ShowInParent("保存成功", "保存自动排序成功", "window.location.reload();"); 39 } 40 else 41 { 42 Alert.ShowInParent("保存失败", "保存自动排序失败", "window.location.reload();"); 43 } 44 }
3、MenuInfoBll逻辑类
它是后端所有页面权限、页面控件权限,以及页面访问链接加密处理的功能类
它会将后端所有菜单与页面记录全部加载到缓存当中,优化后端检查权限时的性能;
用户对后端页面的所有访问,都会经过CheckPagePower函数的处理,只要在系统中绑定了菜单与页面,后端页面开发时,就不必去考虑页面权限,即不用对每个页面的权限进行赋值,CheckPagePower函数会自动检查并判断用户是否有访问权限并做出相应处理;
后端所有页面的加密解密处理函数也在这里,所有访问链接都需要加上对应的加密函数,不然该页面无法正常访问,这种功能可以使我们的后端在管理相关业务时,用户不能通过复制页面链接后修改链接参数中的Id访问,以达到查看当前用户查看无权限访问的信息,防止业务信息被非常查看(当然也不是不能**,这种算法将加大其难度),另外该链接只有当前浏览器上有效,通过复制发送给他人马上失效。
看看效果:
这个是编辑页面的路径,KeyEncrypt参数值就是加密后的字串
将地址复制出来在同一个浏览器换个标签访问,修改Id参数,加密串不变时,显示没权限访问
换个浏览器使用同样的链接访问效果
4、OnlineUsersBll逻辑类
它是后端所有在线缓存、列表数据读写操作的功能类
主要功能大家自己研究吧,由于未经过运行测试,后面开发时可能会对一些函数进行比较大的修改。
本文转自 AllEmpty 博客园博客,原文链接:http://www.cnblogs.com/EmptyFS/p/3779256.html,如需转载请自行联系原作者