ASP.NET MVC 巧用代碼注釋做許可權控制以及後台導航

來源:互聯網
上載者:User

請先看: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注釋

首先配置MVC項目,產生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、讀取時用到了反射,用於讀取控制器和方法,用傳回值和類型做為過濾條件

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.