zoukankan      html  css  js  c++  java
  • 仿SiteMap实现Asp.net 网站的菜单和权限管理

    在Asp.net中,SiteMap用于站点导航,可以与Menu等控件一起使用实现网站的菜单和权限管理。但是SiteMap提供的方法都是只读的,无法再运行时修改(菜单)导航文件,需要手动修改配置web.sitemap文件,某些情况下,这样做很不方便。

    本文即针对这个问题,模仿SiteMap,实现一个可写的菜单和权限控制组件,称之为 MenuMap。

    MenuMap高仿SiteMap,使用方法类似,下面进入主题。

    1. 模仿Web.sitemap定义配置文件,文件名和位置自定义,比如叫menu.xml。注意在部署是保证network services 账号对该文件有读和写的权限。

    格式如下:

    <?xml version="1.0" encoding="utf-8"?>
    <menuMap>
      <menuMapNode url="" title="管理系统" description="" icon="" roles="">
        <menuMapNode url="" title="业务管理" description="" icon="" roles="">
          <menuMapNode url="Business/b1.aspx" title="待办事宜" description="" icon="" roles="超级管理员,总部经理,地区经理" />
          <menuMapNode url="Business/b2.aspx" title="积分管理" description="" icon="" roles="超级管理员,总部经理,地区经理" />
          <menuMapNode url="Business/b4.aspx" title="工作流" description="" icon="" roles="超级管理员,总部经理" />
          <menuMapNode url="Business/b5.aspx" title="统计报表" description="" icon="" roles="超级管理员,总部经理" />
        </menuMapNode>
        <menuMapNode url="" title="系统管理" description="" icon="" roles="系统管理员,超级管理员">
          <menuMapNode url="SysAdmin/UserMgr.aspx" title="用户管理" description="" icon="" roles="超级管理员,系统管理员" />
          <menuMapNode url="SysAdmin/RolesAndMenu.aspx" title="权限设置" description="" icon="" roles="超级管理员" />
          <menuMapNode url="SysAdmin/AreaMgr.aspx" title="区域信息" description="" icon="" roles="超级管理员" />
          <menuMapNode url="SysAdmin/ClearCache.aspx" title="清理缓存" description="" icon="" roles="超级管理员" />
        </menuMapNode>
      </menuMapNode>
    </menuMap>

    基本上同sitemap文件,这里menuMapNode, 多一个属性"icon", 用于给菜单添加图标

    2. 实现MenuMapNode类,直接上代码:

      1 using System.Collections.Generic;
      2 using System.Linq;
      3 using System.Text;
      4 
      5 namespace NorthRiver
      6 {
      7     public class MenuMapNode
      8     {
      9         public string Title { get; set; }
     10         public string Url { get; set; }
     11         public string Description { get; set; }
     12         public string Roles { get; set; }
     13         public string IconUrl { get; set; }
     14         public MenuMapNode Parent { get; set; }
     15         public IList<MenuMapNode> ChildNodes { get; set; }
     16 
     17         public bool HasChildren
     18         {
     19             get
     20             {
     21                 if (ChildNodes != null && ChildNodes.Count > 0)
     22                     return true;
     23 
     24                 return false;
     25             }
     26         }
     27 
     28         public override string ToString()
     29         {
     30             return string.Format("<menuMapNode url="{0}" title="{1}" description="{2}" icon="{3}" roles="{4}" />", Url, Title, Description,IconUrl, Roles);
     31         }
     32 
     33         public void RemoveRole(string roleName)
     34         {
     35             if (string.IsNullOrEmpty(roleName))
     36                 return;
     37 
     38             if (HasChildren)
     39             {
     40                 foreach (MenuMapNode child in ChildNodes)
     41                 {
     42                     child.RemoveRole(roleName);
     43                 }
     44             }
     45             if (!string.IsNullOrEmpty(Roles))
     46             {
     47                 string[] roleArray = Roles.Split(',');
     48                 StringBuilder sb = new StringBuilder();
     49                 for (int i = 0; i < roleArray.Length; i++)
     50                 {
     51                     if (roleArray[i] != roleName)
     52                     {
     53                         if (i > 0 && sb.Length > 0)
     54                             sb.Append(',');
     55                         sb.Append(roleArray[i]);
     56                     }
     57                 }
     58                 Roles = sb.ToString();
     59             }
     60         }
     61 
     62         public bool HasRole(string role)
     63         {
     64             if (string.IsNullOrEmpty(Roles))
     65                 return true;
     66 
     67             string[] roleArray = Roles.Split(',');
     68             return roleArray.Contains(role);
     69         }
     70 
     71         public bool HasRoles(string[] roleArray)
     72         {
     73             if (string.IsNullOrEmpty(Roles))
     74                 return true;
     75 
     76             if (roleArray == null)
     77                 return false;
     78 
     79             foreach (string role in roleArray)
     80             {
     81                 if (HasRole(role))
     82                     return true;
     83             }
     84 
     85             return false;
     86         }
     87         //是否有角色
     88         public bool HasRoles(string roles)
     89         {
     90             if (string.IsNullOrEmpty(roles))
     91                 return false;
     92 
     93             string[] roleArray = roles.Split(',');
     94             return HasRoles(roleArray);
     95         }
     96         //添加节点
     97         public void AddNode(MenuMapNode childNode)
     98         {
     99             if (childNode != null)
    100             {
    101                 if (this.ChildNodes == null)
    102                     this.ChildNodes = new List<MenuMapNode>();
    103 
    104                 childNode.Parent = this;
    105                 this.ChildNodes.Add(childNode);
    106             }
    107         }
    108 
    109         public bool TryMatchUrl(string url, ref MenuMapNode matchNode)
    110         {
    111             if (this.Url == url)
    112             {
    113                 matchNode = this;
    114                 return true;
    115             }
    116 
    117             if (this.HasChildren)
    118             {
    119                 foreach (MenuMapNode child in ChildNodes)
    120                 {
    121                     if (child.TryMatchUrl(url, ref matchNode))
    122                         return true;
    123                 }
    124             }
    125 
    126             return false;
    127         }
    128     }
    129 }
    MenuMapNode

    3.实现MenuMap类,直接上代码:

    using System;
    using System.Collections.Generic;
    using System.Web;
    using System.Configuration;
    using System.Xml;
    using System.Text;
    
    namespace NorthRiver
    {
        public class MenuMap
        {
            private static string _menuFileName = "MenuMapFile";
            private static string _rootCacheKey = "MenuMapCache";
    
            public static MenuMapNode RootNode
            {
                get
                {
                    return LoadMenu();
                }
            }
    
            public static MenuMapNode LoadMenu()
            {
                object objRoot = GetCache(_rootCacheKey);
                if (objRoot == null)
                {
                    string filename = ConfigurationManager.AppSettings[_menuFileName];
                    filename = HttpContext.Current.Server.MapPath(filename);
    
    
                    XmlReaderSettings setting = new XmlReaderSettings();
                    setting.IgnoreComments = true;
                    using (XmlReader xmlReader = XmlReader.Create(filename, setting))
                    {
                        XmlDocument xmlDoc = new XmlDocument();
                        xmlDoc.Load(xmlReader);
    
                        XmlNode xmlRoot = xmlDoc.DocumentElement.FirstChild;
                        MenuMapNode menuRoot = new MenuMapNode();
                        menuRoot.Title = xmlRoot.Attributes["title"] == null ? "" : xmlRoot.Attributes["title"].Value;
                        menuRoot.Url = xmlRoot.Attributes["url"] == null ? "" : xmlRoot.Attributes["url"].Value;
                        menuRoot.Description = xmlRoot.Attributes["description"] == null ? "" : xmlRoot.Attributes["description"].Value;
                        menuRoot.IconUrl = xmlRoot.Attributes["icon"] == null ? "" : xmlRoot.Attributes["icon"].Value;
                        menuRoot.Roles = xmlRoot.Attributes["roles"] == null ? "" : xmlRoot.Attributes["roles"].Value;
    
                        menuRoot.ChildNodes = new List<MenuMapNode>();
    
                        if (xmlRoot.HasChildNodes)
                        {
                            foreach (XmlNode xmlNode in xmlRoot.ChildNodes)
                                CreateMenuNode(xmlNode, menuRoot);
                        }
    
                        SetCache(_rootCacheKey, menuRoot);
                        return menuRoot;
                    }
                }
    
                return (MenuMapNode)objRoot;
            }
    
            private static void CreateMenuNode(XmlNode xmlNode, MenuMapNode parentNode)
            {
                MenuMapNode menuNode = new MenuMapNode();
                menuNode.Title = xmlNode.Attributes["title"] == null ? "" : xmlNode.Attributes["title"].Value;
                menuNode.Url = xmlNode.Attributes["url"] == null ? "" : xmlNode.Attributes["url"].Value;
                menuNode.Description = xmlNode.Attributes["description"] == null ? "" : xmlNode.Attributes["description"].Value;
                menuNode.IconUrl = xmlNode.Attributes["icon"] == null ? "" : xmlNode.Attributes["icon"].Value;
                menuNode.Roles = xmlNode.Attributes["roles"] == null ? "" : xmlNode.Attributes["roles"].Value;
                menuNode.Parent = parentNode;
                menuNode.ChildNodes = new List<MenuMapNode>();
    
                if (xmlNode.HasChildNodes)
                {
                    foreach (XmlNode node in xmlNode.ChildNodes)
                        CreateMenuNode(node, menuNode);
                }
    
                parentNode.ChildNodes.Add(menuNode);
            }
    
            public static void Save()
            {
                XmlWriterSettings settings = new XmlWriterSettings();
                //要求缩进
                settings.Indent = true;
                //注意如果不设置encoding默认将输出utf-16
                //注意这儿不能直接用Encoding.UTF8如果用Encoding.UTF8将在输出文本的最前面添加4个字节的非xml内容
                settings.Encoding = new UTF8Encoding(false);
                //设置换行符
                settings.NewLineChars = Environment.NewLine;
    
                string filename = ConfigurationManager.AppSettings[_menuFileName];
                filename = HttpContext.Current.Server.MapPath(filename);
    
                MenuMapNode rootNode = RootNode;
                lock (rootNode)
                {
                    using (XmlWriter xmlWriter = XmlWriter.Create(filename, settings))
                    {
                        //写xml文件开始<?xml version="1.0" encoding="utf-8" ?>
                        xmlWriter.WriteStartDocument();
                        //写根节点
                        xmlWriter.WriteStartElement("menuMap");
                        //递归写SiteMapNode
                        WriteMenuMapNode(xmlWriter, rootNode);
                        xmlWriter.WriteEndElement();
    
                        XmlDocument doc = new XmlDocument();
                        doc.Save(xmlWriter);
                    }
                }
            }
    
            private static void WriteMenuMapNode(XmlWriter xmlWriter, MenuMapNode node)
            {
                xmlWriter.WriteStartElement("menuMapNode");
                xmlWriter.WriteAttributeString("url", node.Url);
                xmlWriter.WriteAttributeString("title", node.Title);
                xmlWriter.WriteAttributeString("description", node.Description);
                xmlWriter.WriteAttributeString("icon", node.IconUrl);
                xmlWriter.WriteAttributeString("roles", node.Roles);
    
                if (node.HasChildren)
                {
                    foreach (MenuMapNode child in node.ChildNodes)
                        WriteMenuMapNode(xmlWriter, child);
                }
    
                xmlWriter.WriteEndElement();
            }
        
            public static object GetCache(string CacheKey)
            {
                System.Web.Caching.Cache objCache = HttpRuntime.Cache;
                return objCache[CacheKey];
    
            }
    
            public static void SetCache(string CacheKey, object objObject)
            {
                System.Web.Caching.Cache objCache = HttpRuntime.Cache;
                objCache.Insert(CacheKey, objObject);
            }
    
            public static void RemoveCache()
            {
                System.Web.Caching.Cache objCache = HttpRuntime.Cache;
                objCache.Remove(_rootCacheKey);
            }
    
        }
    }
    View Code

    4.在web.config中配置菜单文件路径,如:

      <appSettings>
        <add key="MenuMapFile" value="~\menu.xml" />    
      </appSettings>

    5.使用举例:

            private void CreateMenu()
            {
                IList<MenuMapNode> lv1Nodes = MenuMap.RootNode.ChildNodes;
                foreach (MenuMapNode node in lv1Nodes)
                {
                    MenuPanel menuPanel = CreateMenuPanel(node);
                    if (CheckPermissions(node))
                        this.LeftPanel.Items.Add(menuPanel);
                }
            }
    
            private MenuPanel CreateMenuPanel(MenuMapNode node)
            {
                MenuPanel menuPanel = new MenuPanel();
                menuPanel.Title = node.Title;
                menuPanel.Border = false;
    
                if (node.HasChildren)
                {
                    foreach (MenuMapNode child in node.ChildNodes)
                    {
                        Ext.Net.MenuItem item = new Ext.Net.MenuItem();
                        item.Text = child.Title;
                        item.Icon = Icon.ApplicationHome;
                        item.Listeners.Click.Handler = string.Format("e.stopEvent(); loadPage('{0}', '{1}','{2}');",
                            child.Url, "id" + child.Url.GetHashCode(), child.Title);
                        // object o = child.Roles;
    
                        if (CheckPermissions(child))
                            menuPanel.Menu.Items.Add(item);
                    }
                }
                return menuPanel;
            }
    
            private bool CheckPermissions(MenuMapNode node)
            {
                //未做标记的菜单,对所有角色可见
                if (string.IsNullOrEmpty(node.Roles))
                    return true;
    
                if (Session["user_roles"] == null)
                    return false;
    
                return node.HasRoles((string[])Session["user_roles"]);
            }

    补充,MenuMap是可写的,示例:

                    if (MenuMap.RootNode.HasChildren)
                        MenuMap.RootNode.ChildNodes.Clear();
    
                    foreach (SubmittedNode sNode in e.RootNode.Children)
                    {
                        MenuMapNode mNode = CreateMenuMapNode(sNode);
                        MenuMap.RootNode.AddNode(mNode);
                    }
    
                    MenuMap.Save();
  • 相关阅读:
    软件的概念
    打开别人Android项目的方法
    软件工程
    数据预处理技术
    机器学习之监督学习
    C语言指针与二维数组
    徐涛政治押题
    求二叉树的宽度
    解决在某些IE浏览器下字符乱码的问题
    mac系统不能使用127.0.0.2的解决方案
  • 原文地址:https://www.cnblogs.com/northriver/p/3229681.html
Copyright © 2011-2022 走看看