在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 }