mvc权限控制案例.doc

上传人:laozhun 文档编号:2385045 上传时间:2023-02-17 格式:DOC 页数:20 大小:676.50KB
返回 下载 相关 举报
mvc权限控制案例.doc_第1页
第1页 / 共20页
mvc权限控制案例.doc_第2页
第2页 / 共20页
mvc权限控制案例.doc_第3页
第3页 / 共20页
mvc权限控制案例.doc_第4页
第4页 / 共20页
mvc权限控制案例.doc_第5页
第5页 / 共20页
点击查看更多>>
资源描述

《mvc权限控制案例.doc》由会员分享,可在线阅读,更多相关《mvc权限控制案例.doc(20页珍藏版)》请在三一办公上搜索。

1、A MVC权限设计思考 (一)数据库建库部分 目前各类的权限设计已经困扰了我们好久,对于MVC,下面我将通过ActionFilter来扩展我们的权限认证,以下示例是从我的一个课程中心项目中提取出来,希望对各位初学者起到抛砖引玉的作用。下面首先来设计我们的权限控制的数据库层。下面我来依次介绍每个字段的说明RoleGroup 权限组表 该表主要对系统权限进行分组,我们的用户可以直接赋予该分组,拥有所有该组权限RoleID 权限组ID 例:01RoleName 权限组名称 例:系统管理员RoleState 组状态 (是否启用) 例:TrueRoleGroupAppList 表 组权限对应表 该表主要

2、复制每个权限组对应的权限详细列表ID ID主键 例:1RoleID 对应权限组的ID 例:01SysAppID 对应的详细权限组ID 例:01StartTime 该权限使用的起始日期 例:2009-01-01 ,该字段属性默认为:all ,即不限制起始日期EndTime 该权限使用的结束日期 例:2009-01-01 ,该字段属性默认为:all ,即不限制结束日期SysAppCate 表 该表主要是对SysAppList详细权限表做分类,当我们的权限页面特别多的时候,该表主要为了方便管理。可省略SysAppCateID 大类ID 例:01SysAppCateName 大类名称 例:新闻管理Sy

3、sAppCateEName 大类英文名SysAppList 权限详细表 该表主要负责所有权限的基础列表SysAppID 权限ID 例:01SysAppCateID 权限大类ID 例:01SysAppName 权限名称 例:新闻添加SysAppEName 权限英文名称SysAppController 权限对应的Controller 例:NewsSysAppAction 权限对应的Action 例:Add 本权限设计针对对Action权限限制IsView 是否为可见 例:True 该字段的设计主要是便于后台的管理和设置,因为有部分Action是没有View层的,比如Post,但是在后台权限管理中我

4、们又要用到他。好了,建库部分就到这里了,下一篇我会介绍逻辑部分,其中会涉及到Repository模式,缓存,自定义的AuthorizeAttribute。A MVC权限设计思考 (二)逻辑部分实现 在我的项目中,我还是使用的LINQ TO SQL ,因为我的项目不会涉及太多很太复杂的数据库操作业务。当然如果设计,我相信LINQ TO SQL的自定义扩展也能满足需求。使用Repository模式是最近MVC很多项目采用的解决方案,能把原来我们杂乱的LINQ TO SQL统一封装起来。让我们的架构更清晰。现在来看看具体实现。IRepository接口:代码 interfaceIRepository

5、whereTEntity:classIQueryableFindAll(ExpressionFuncexp);TEntityFind(ExpressionFuncexp);voidAdd(TEntityentity);voidDelete(TEntityentity);voidSave();Repository实现:代码 publicclassRepository:IRepositorywhereTEntity:classprotectedDAL.CourseCenterDatadb;publicRepository()db=newDAL.CourseCenterData();/查找所有数据/

6、publicIQueryableFindAll()returndb.GetTable().Where(p=1=1);/查找所有数据/条件表达式/publicIQueryableFindAll(ExpressionFuncexp)returndb.GetTable().Where(exp);/查找一个数据/条件表达式/publicTEntityFind(ExpressionFuncexp)returndb.GetTable().FirstOrDefault(exp);/添加数据/实体publicvoidAdd(TEntityentity)db.GetTable().InsertOnSubmit(

7、entity);/删除数据/实体publicvoidDelete(TEntityentity)db.GetTable().DeleteOnSubmit(entity);/批量添加数据/实体列表publicvoidAddAll(IEnumerableentity)db.GetTable().InsertAllOnSubmit(entity);/批量删除数据/实体列表publicvoidDeleteAll(IEnumerableentity)db.GetTable().DeleteAllOnSubmit(entity);/对数据做插入,更新,删除操作/publicvoidSave()db.Subm

8、itChanges();网上已经有很多Repository的例子,但是请注意Find中的条件必须是Expression Tree的扩展,否则在数据查询的SQL语句中,你会发现捕获到的将是select一个表之后再来做数据的查询,这在我们海量数据查询时不允许的。现在我们已经有了自己的Repository,下面来建立一个数据库视图把我们上一讲需要的数据拿出来。新建视图ViewRoleGroup,选定一下表和字段我们通过VS2008新建一个LINQ TO SQL类,拖入这个视图。然后我们需要思考,这个权限分组视图是系统频繁读取的,需要为他创建一个缓存。新建一个缓存类Caches:代码 /缓存操作基类/

9、publicclassCaches/建立缓存/publicstaticobjectTryAddCache(stringkey,objectvalue,CacheDependencydependencies,DateTimeabsoluteExpiration,TimeSpanslidingExpiration,CacheItemPrioritypriority,CacheItemRemovedCallbackonRemovedCallback)if(HttpRuntime.Cachekey=null&value!=null)returnHttpRuntime.Cache.Add(key,val

10、ue,dependencies,absoluteExpiration,slidingExpiration,priority,onRemovedCallback);elsereturnnull;/移除缓存/publicstaticobjectTryRemoveCache(stringkey)if(HttpRuntime.Cachekey!=null)returnHttpRuntime.Cache.Remove(key);elsereturnnull;/移除键中带某关键字的缓存/publicstaticvoidRemoveMultiCache(stringkeyInclude)IDictionar

11、yEnumeratorCacheEnum=HttpRuntime.Cache.GetEnumerator();while(CacheEnum.MoveNext()if(CacheEnum.Key.ToString().IndexOf(keyInclude.ToString()=0)HttpRuntime.Cache.Remove(CacheEnum.Key.ToString();/移除所有缓存/publicstaticvoidRemoveAllCache()IDictionaryEnumeratorCacheEnum=HttpRuntime.Cache.GetEnumerator();whil

12、e(CacheEnum.MoveNext()HttpRuntime.Cache.Remove(CacheEnum.Key.ToString(); 来看看我们的ViewRoleGroupRepository怎么写。新建类:ViewRoleGroupRepository代码 publicclassViewRoleGroupRepository:Repository/获取权限视图缓存列表,Key:ViewGroupList/publicListGetCacheAll()ListviewRoleGroup;stringkey=ViewGroupList;if(HttpRuntime.Cachekey!

13、=null)viewRoleGroup=(List)HttpRuntime.Cachekey;elseviewRoleGroup=FindAll().ToList();Caches.TryAddCache(key,viewRoleGroup,null,Cache.NoAbsoluteExpiration,TimeSpan.FromMinutes(20),System.Web.Caching.CacheItemPriority.Normal,null);returnviewRoleGroup;接下来我们将自定义自己的AuthorizeAttribute,新建类CenterAuthorizeAtt

14、ribute代码 publicclassCenterAuthorizeAttribute:AuthorizeAttributepublicoverridevoidOnAuthorization(AuthorizationContextfilterContext)stringaction=(string)filterContext.RouteData.ValuesAction;stringcontroller=(string)filterContext.RouteData.ValuesController;stringfullName=filterContext.HttpContext.User

15、.Identity.Name;if(!filterContext.HttpContext.User.Identity.IsAuthenticated)filterContext.HttpContext.Response.Redirect(string.Format(/Account/LogOn?returnUrl=0,filterContext.HttpContext.Request.Url.PathAndQuery);elseif(newLogin().IsLock(fullName)thrownewException(string.Format(【用户:0】对不起,该用户已被锁定。,ful

16、lName);varr=newBLL.RoleGroupRepository().GetUserRoleGroup(fullName);varq=newBLL.ViewRoleGroupRepository().GetCacheAll().FindAll(c=c.RoleID=r.RoleID&c.SysAppController=controller&c.SysAppAction=action&(c.StartTime.Equals(Anytime,StringComparison.CurrentCultureIgnoreCase)?true:(DateTime.Parse(c.StartT

17、ime)=DateTime.Now);if(q.Count=0)thrownewException(string.Format(【用户:0】对不起,您没有访问该页面的权限。,fullName);请注意varr=newBLL.RoleGroupRepository().GetUserRoleGroup(fullName);这个是我项目中通过用户名获得用户权限分组的实现,大家参考自己项目修改。大功告成,那怎么用呢,很简单。创建了需要的权限组,例如超级管理员 然后把对应的Controller和Action权限加入到组后,在需要的Action上进行标注,例如CenterAuthorizepublicA

18、ctionResultIndex()ViewDataMessage=WelcometoASP.NETMVC!;returnView();是不是很简单就通过数据库控制到每个需要权限控制的Action咯?当然很多朋友可能还很迷糊,第一次写这类文章。部分代码也没调试。因为从项目剥离出来,所以大家见谅。UI部分和数据库的操作这里想滤过啦。这些比较简单的东西,大家应该很容易就能实现咯。A MVC权限设计思考 (三)后台UI设计 一些朋友提出让我加上细节部分,也有朋友PM说很多地方看不懂不知道该怎么用,由于目前正在赶学校的课程中心,暂没有时间来详细介绍使用,这里我把后台的一些设计截图出来,大家参考设计另外

19、在第二篇提到的CenterAuthorizeAttribute部分,已经做部分修改,原来的会出现逻辑判断的BUG。权限大类管理 SysAppCate可以看出,权限大类其实对应的是上部的大类菜单,当添加新的大类,该菜单将加载相应的项并呈现出来。权限列表管理 SysAppList这个界面对应系统所有的权限,有朋友提出如果出现相同的Action,那么将无法分类管理,其实我认为不然,相同的Action一般用到的设计无非是Post和Get的请求变更,那么如果一个页面只可以访问却无法操作,这样还有必要呈现给用户么?大家请注意观察,在这里的设置中如果为是否现实为:False,那么该权限将不会按照分组呈现在左

20、侧的管理菜单中。权限组管理RoleGroup这个表建立我们需要的系统权限组,这样更方便我们的管理。按照我的项目经验,一个项目很少会出现上百个权限组的要求,在课程中心这个项目中,当然也不会涉及到那么多的权限分类。这里为每一个权限多了一个“设置”的选项,下面来看看“设置”是怎么完成的.这里我做了一个Tab,按照权限的大类分别放置所属的权限并进行加载。开始时间和结束时间是控制该权限在权限组中可以操作的时间,那么设置为Anytime,也就表示开始或者结束为无限期。我在该项目中间会用到申报等一些流程,那么我们必须控制时间来按照需要进行申报。这里我们还要考虑,应该是当权限发生的更改,才提交这个数据,否则每

21、次都提交这么多权限进行更新,效率上讲我们犯了一个低级的错误。上图的逻辑最终将更新至RoleGroupAppList表中。好了,现在权限整体的结构都已经设计好,接下来将看看怎么把权限应用在对应用户上,这个很简单,但是还是比较说明一下我们现在只需要把对应的权限组分配给用户,就可以获得该组分配的权限。大家还可以看到我最上面的几个截图中有“帮助” ,这并不是一个固定的页面,我通过这样的形式来创建连接,那么可以把它放在MasterPage里,不同的页面中连接其实会变成对应的controller和action,这样建立对应的表,可以很简单的对应这个View视图来加载帮助信息。最近手头的工作实在太忙,由于时

22、间比较紧,就不一一介绍了。其实MVC给我们更大的灵活度和对视图的控制。我从MVC1 RC版就开始使用MVC做一些小项目,很早抛弃了我认为相对臃肿的WEBFORM,有朋友也曾质疑MVC的编程模式接近ASP,其实这无疑是对于MVC整个框架及应用不了解所造成的。Asp.Net MVC2中扩展ModelMetadata的DescriptionAttribute。 在MVC2中默认并没有实现DescriptionAttribute(虽然可以找到这个属性,通过阅读MVC源码,发现并没有实现方法),这很不方便,特别是我们使用EditorForModel的时候,我们需要对字段进行简要的介绍,下面来扩展这个属性

23、。新建类 DescriptionMetadataProvider然后重写DataAnnotationsModelMetadataProvider的CreateMetadata方法:publicclassDescriptionMetadataProvider:DataAnnotationsModelMetadataProviderprotectedoverrideModelMetadataCreateMetadata(IEnumerableattributes,TypecontainerType,FuncmodelAccessor,TypemodelType,stringpropertyName

24、)ListattributeList=newList(attributes);DataAnnotationsModelMetadataresult=(DataAnnotationsModelMetadata)base.CreateMetadata(attributes,containerType,modelAccessor,modelType,propertyName);DescriptionAttributedescriptionAttribute=attributeList.OfType().FirstOrDefault();if(descriptionAttribute!=null)re

25、sult.Description=descriptionAttribute.Description;returnresult;接下来在Global.asax的Application_Start()中注册DescriptionMetadataProviderModelMetadataProviders.Current=newDescriptionMetadataProvider();接着你就可以使用如下方进行标注:DisplayName(办公地址)RequiredDescription(请填写真实的办公地址)publicstringOfficeAddressget;set;来看看实际效果:MVC

26、2给我们带来了很好的模板机制,给大家提供一个学习地址:而上面扩展这个方法,我们可以这样来设计模板。在Shared目录中新建EditorTemplates文件夹,添加MVC用户控件Object.ascx,请注意当我们使用方法的时候,MVC会自动寻找Object.ascx,其顺序是Views=ControllerName=EditorTemplates=Object.ascx当在对应Controller的View中找不到Object.ascx,那么会继续在Shared=EditorTemplates文件夹找(还会找对应模板aspx)。来看看一个简单的Object.ascx代码 1)%名称内容信息pm.ShowForEdit&!ViewData.TemplateInfo.Visited(pm)%tr有了这个模板的定义,大家可以尝试使用方法,看看效果有什么不同呢?

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 建筑/施工/环境 > 项目建议


备案号:宁ICP备20000045号-2

经营许可证:宁B2-20210002

宁公网安备 64010402000987号