• 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{}

    后台对应的效果

    image

    XML注释说明

           /// <IsShow>True</IsShow>   表示是否在导航菜单显示
           /// <IsHeader>False</IsHeader>  表示是否是导航标题  通常用于Controler类
           /// <Title>选择用户</Title>     标题
           /// <IsAllowedNoneRoles>False</IsAllowedNoneRoles>  是否允许匿名访问
           /// <IsAllowedAllRoles>False</IsAllowedAllRoles>   是否允许所有登录用户访问

    读取XML注释

    首先配置MVC项目,生成XML文件

    属性 --生成  -- 输出

    image

      在网站启动的时候,执行初始化任务

    // 执行启动任务
                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、读取时用到了反射,用于读取控制器和方法,用返回值和类型做为过滤条件

  • 相关阅读:
    Mysql group by语句的优化
    Mysql join语句的优化
    jquery 只读
    【Unity Shaders】Transparency —— 使用渲染队列进行深度排序
    oracle多表查询之内连接,外连接语句总结
    String比较相等的问题探索
    markdown实例
    集合list里存储list,要遍历最底层list的对象元素的遍历方法
    System.out.println(i++); System.out.println(++i);的区别
    windows自动快捷方式
  • 原文地址:https://www.cnblogs.com/xiaoqi/p/2397990.html
Copyright © 2020-2023  润新知