ASP.NET MVC 巧用代码注释做权限控制以及后台导航
请先看:http://www.cnblogs.com/xiaoqi/archive/2011/01/24/1942880.html
权限控制需要将控制器和Action信息写入到数据库,手动添加的话比较麻烦,有没有更简单的办法呢?
那就用反射把吧,我们可以借助代码注释( 将权限控制的详细用xml注释的方式写到代码里)+反射技术来巧妙的实现
同时,还可以用来作后台导航哦
效果篇#
/// <IsShow>True</IsShow>
/// <IsHeader>True</IsHeader>
/// <Title>个人信息</Title>
/// <IsAllowedNoneRoles>False</IsAllowedNoneRoles>
/// <IsAllowedAllRoles>False</IsAllowedAllRoles>
class UserInfoController{}
后台对应的效果
XML注释说明#
/// <IsShow>True</IsShow> 表示是否在导航菜单显示
/// <IsHeader>False</IsHeader> 表示是否是导航标题 通常用于Controler类
/// <Title>选择用户</Title> 标题
/// <IsAllowedNoneRoles>False</IsAllowedNoneRoles> 是否允许匿名访问
/// <IsAllowedAllRoles>False</IsAllowedAllRoles> 是否允许所有登录用户访问
读取XML注释#
在网站启动的时候,执行初始化任务
// 执行启动任务 IoC.ResolveAll().ForEach(t => t.Execute()); |
相关代码:
/// /// 启动任务 /// public interface IBootstrapperTask { void Execute(); } |
具体实现代码:
public class InitSystemConfig : IBootstrapperTask { private readonly IDomainObjectFactory _factory; private readonly IUserRepository _userRepository; private readonly IRoleRepository _roleRepository; private readonly IResourceRepository _resourceRepository; private readonly DefaultRole[] _defaultRoles; private readonly DefaultUser[] _defaultUsers; private readonly DefaultResource[] _defaultResources; public InitSystemConfig(IDomainObjectFactory factory, IUserRepository userRepository, IRoleRepository roleRepository, IResourceRepository resourceRepository, DefaultRole[] defaultRoles, DefaultUser[] defaultUsers, DefaultResource[] defaultResources) { Check.Argument.IsNotNull(factory, "factory" ); Check.Argument.IsNotNull(userRepository, "userRepository" ); Check.Argument.IsNotNull(roleRepository, "roleRepository" ); Check.Argument.IsNotNull(defaultRoles, "defaultRoles" ); Check.Argument.IsNotNull(defaultUsers, "defaultUsers" ); _factory = factory; _userRepository = userRepository; _roleRepository = roleRepository; _resourceRepository = resourceRepository; _defaultRoles = defaultRoles; _defaultUsers = defaultUsers; _defaultResources = defaultResources; } public void Execute() { CreateResourceIfNotrExist(); CreateDefaultController(); CreateRoleIfNotExist(); CreateUserIfNotrExist(); } /// /// 为没有配置信息的控制器和Action创建记录,默认设为所有用户可访问 /// void CreateDefaultController() { using (IUnitOfWork unitOfWork = UnitOfWork.Begin()) { IConfigurationManager configurationManager = IoC.Resolve(); var assemblyName = configurationManager.AppSettings[ "WebAssemblyName" ]; if ( string .IsNullOrEmpty(assemblyName)) { assemblyName = "MarkerPlatform.Web" ; } Assembly assembly = Assembly.Load(assemblyName); Type[] types = assembly.GetTypes(); var assemblyXml = HttpContext.Current.Server.MapPath( "~/bin/" + assemblyName + ".xml" ); XmlDocument assembleDoc = new XmlDocument(); if (File.Exists(assemblyXml)) assembleDoc.Load(assemblyXml); foreach (Type type in types) { if (type.BaseType != null ) { if (type.Name.Contains( "Controller" ) && type.BaseType.Name == "BaseController" ) { // 查询数据库有没有controler信息 var controllerName = type.Name.Replace( "Controller" , "" ); var dbController = _resourceRepository.FindController(controllerName); // controller为空或者允许所有人访问并且不允许匿名用户访问 // 如果允许匿名用户访问,则这个控制器默认所有Action均可访问 if (dbController == null || dbController.IsAllowedAllRoles && !dbController.IsAllowedNoneRoles) { if (dbController == null ) { // 获取controller dbController = GetController(assembleDoc, type, controllerName); if (dbController != null ) _resourceRepository.Add(dbController); } //获取方法信息 MethodInfo[] myMethodInfo = type.GetMethods(); try { foreach ( var methodInfo in myMethodInfo) { if (methodInfo.ReturnType.Name == "ActionResult" ) { var actionName = methodInfo.Name; var dbresource = _resourceRepository.FindAction(controllerName, actionName); if (dbresource == null ) { // 默认设为所有用户可访问 dbresource = GetDbresource(assembleDoc, controllerName, methodInfo, actionName); if (dbresource != null ) _resourceRepository.Add(dbresource); } } } } catch (Exception ex) { Console.Write(ex); } } } } } unitOfWork.Commit(); } } /// /// 为方法创建实体 /// /// /// /// /// /// private IResource GetDbresource(XmlDocument assembleDoc, string controllerName, MethodInfo methodInfo, string actionName) { IResource dbresource; dbresource = _factory.CreateResource(actionName, controllerName, false , false , true ); var path = "M:" + methodInfo.DeclaringType.FullName + "." + methodInfo.Name; XmlNode node = GetNode(assembleDoc, path); if (node == null ) { dbresource.IsHeader = false ; dbresource.IsShow = false ; dbresource.Title = controllerName + "/" + actionName; } else { var child = node.SelectSingleNode( "IsShow" ); dbresource.IsShow = child != null && bool .Parse(child.InnerText); child = node.SelectSingleNode( "IsHeader" ); dbresource.IsHeader = child != null && bool .Parse(child.InnerText); child = node.SelectSingleNode( "Title" ); if (child == null ) child = node.SelectSingleNode( "summary" ); dbresource.Title = child != null ? child.InnerText.Trim() : "" ; if ( string .IsNullOrEmpty(dbresource.Title)) { dbresource.Title = controllerName + "/" + actionName; } child = node.SelectSingleNode( "IsAllowedAllRoles" ); dbresource.IsAllowedAllRoles = child != null && bool .Parse(child.InnerText); child = node.SelectSingleNode( "IsAllowedNoneRoles" ); dbresource.IsAllowedNoneRoles = child != null && bool .Parse(child.InnerText); } return dbresource; } /// /// 为控制器创建实体 /// /// /// /// /// private IResource GetController(XmlDocument assembleDoc, Type type, string controllerName) { IResource dbController; XmlNode controllerNode = GetNode(assembleDoc, "T:" + type.FullName); // 默认匿名用户不能访问 登录用户均可访问 dbController = _factory.CreateResource(controllerName, controllerName, true , false , true ); if (controllerNode != null ) { var child = controllerNode.SelectSingleNode( "IsShow" ); dbController.IsShow = child != null && bool .Parse(child.InnerText); child = controllerNode.SelectSingleNode( "IsShow" ); dbController.IsHeader = child != null && bool .Parse(child.InnerText); child = controllerNode.SelectSingleNode( "Title" ); if (child == null ) child = controllerNode.SelectSingleNode( "summary" ); dbController.Title = child != null ? child.InnerText.Trim() : "" ; if ( string .IsNullOrEmpty(dbController.Title.Trim())) { dbController.Title = controllerName; } child = controllerNode.SelectSingleNode( "IsAllowedAllRoles" ); dbController.IsAllowedAllRoles = child != null && bool .Parse(child.InnerText); child = controllerNode.SelectSingleNode( "IsAllowedAllRoles" ); dbController.IsAllowedAllRoles = child != null && bool .Parse(child.InnerText); } else { dbController.IsHeader = false ; dbController.IsShow = false ; dbController.Title = controllerName; } return dbController; } private XmlNode GetNode(XmlDocument assembleDoc, string name) { var nodes = assembleDoc.SelectNodes( "/doc/members/member" ); XmlNode node = null ; if (nodes != null ) foreach (XmlNode xmlNode in nodes) { if (xmlNode.Attributes != null ) if (xmlNode.Attributes[ "name" ].Value.Contains((name))) { node = xmlNode; break ; } } return node; } void CreateRoleIfNotExist() { using (IUnitOfWork unitOfWork = UnitOfWork.Begin()) { foreach ( var role in _defaultRoles) { var dbRole = _roleRepository.GetByName(role.Name); if (dbRole == null ) { dbRole = _factory.CreateRole(role.Name, role.Description); // 添加资源 var resources = role.Resources.Split( ',' ); foreach ( var resourceName in resources) { var defaultResource = IoC.Resolve(resourceName); if (defaultResource != null ) { if (String.IsNullOrEmpty(defaultResource.Name)) { continue ; } var resource = defaultResource.IsController ? _resourceRepository.FindController(defaultResource.Name) : _resourceRepository.FindAction(defaultResource.ControllName, defaultResource.Name); if (resource != null ) { dbRole.AddResouce(resource); } } } _roleRepository.Add(dbRole); } } unitOfWork.Commit(); } } void CreateUserIfNotrExist() { using (IUnitOfWork unitOfWork = UnitOfWork.Begin()) { foreach ( var user in _defaultUsers) { // account 为email var dbUser = _userRepository.FindByAccountName(user.Email); if (dbUser == null ) { dbUser = _factory.CreateUser(user.Email, user.Name, user.Password, " " , " " ); dbUser.Gender = user.Gender; var role = _roleRepository.GetByName(user.Role.Name); if (role != null ) { dbUser.AddToRole(role); } _userRepository.Add(dbUser); } } unitOfWork.Commit(); } } void CreateResourceIfNotrExist() { using (IUnitOfWork unitOfWork = UnitOfWork.Begin()) { foreach ( var resource in _defaultResources) { var dbresource = resource.IsController ? _resourceRepository.FindController(resource.Name) : _resourceRepository.FindAction(resource.ControllName, resource.Name); if (dbresource == null ) { dbresource = _factory.CreateResource(resource.Name, resource.ControllName, resource.IsController, resource.IsAllowedNoneRoles, resource.IsAllowedAllRoles); dbresource.IsHeader = resource.IsHeader; dbresource.IsShow = resource.IsShow; dbresource.Title = resource.Title; _resourceRepository.Add(dbresource); } } unitOfWork.Commit(); } } } |
代码说明#
1、需要在系统启动时执行,放在Global.asax中即可
2、每次加载时只创建不存在的记录(CreateResourceIfNotrExist)
3、读取时用到了反射,用于读取控制器和方法,用返回值和类型做为过滤条件
关注作者
作者: JadePeng
出处:https://www.cnblogs.com/xiaoqi/archive/2012/03/15/2397990.html
版权:本文采用「署名-非商业性使用-相同方式共享 4.0 国际(欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文链接) 」知识共享许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了