在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类,直接上代码:

 using System.Collections.Generic;
using System.Linq;
using System.Text; namespace NorthRiver
{
public class MenuMapNode
{
public string Title { get; set; }
public string Url { get; set; }
public string Description { get; set; }
public string Roles { get; set; }
public string IconUrl { get; set; }
public MenuMapNode Parent { get; set; }
public IList<MenuMapNode> ChildNodes { get; set; } public bool HasChildren
{
get
{
if (ChildNodes != null && ChildNodes.Count > )
return true; return false;
}
} public override string ToString()
{
return string.Format("<menuMapNode url=\"{0}\" title=\"{1}\" description=\"{2}\" icon=\"{3}\" roles=\"{4}\" />", Url, Title, Description,IconUrl, Roles);
} public void RemoveRole(string roleName)
{
if (string.IsNullOrEmpty(roleName))
return; if (HasChildren)
{
foreach (MenuMapNode child in ChildNodes)
{
child.RemoveRole(roleName);
}
}
if (!string.IsNullOrEmpty(Roles))
{
string[] roleArray = Roles.Split(',');
StringBuilder sb = new StringBuilder();
for (int i = ; i < roleArray.Length; i++)
{
if (roleArray[i] != roleName)
{
if (i > && sb.Length > )
sb.Append(',');
sb.Append(roleArray[i]);
}
}
Roles = sb.ToString();
}
} public bool HasRole(string role)
{
if (string.IsNullOrEmpty(Roles))
return true; string[] roleArray = Roles.Split(',');
return roleArray.Contains(role);
} public bool HasRoles(string[] roleArray)
{
if (string.IsNullOrEmpty(Roles))
return true; if (roleArray == null)
return false; foreach (string role in roleArray)
{
if (HasRole(role))
return true;
} return false;
}
//是否有角色
public bool HasRoles(string roles)
{
if (string.IsNullOrEmpty(roles))
return false; string[] roleArray = roles.Split(',');
return HasRoles(roleArray);
}
//添加节点
public void AddNode(MenuMapNode childNode)
{
if (childNode != null)
{
if (this.ChildNodes == null)
this.ChildNodes = new List<MenuMapNode>(); childNode.Parent = this;
this.ChildNodes.Add(childNode);
}
} public bool TryMatchUrl(string url, ref MenuMapNode matchNode)
{
if (this.Url == url)
{
matchNode = this;
return true;
} if (this.HasChildren)
{
foreach (MenuMapNode child in ChildNodes)
{
if (child.TryMatchUrl(url, ref matchNode))
return true;
}
} return false;
}
}
}

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);
} }
}

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();

仿SiteMap实现Asp.net 网站的菜单和权限管理的更多相关文章

  1. 【Ecshop】后台菜单与权限管理

    主要php文件: 1,admin/includes/inc_menu.php ECSHOP管理中心菜单数组--配置菜单组及URL 2,languages/zh_cn/admin/common.php  ...

  2. ASP.NET MVC 基于页面的权限管理

    菜单表 namespace AspNetMvcAuthDemo1.Models { public class PermissionItem { public int ID { set; get; } ...

  3. ecshop 管理后台菜单及权限管理机制

    ecshop 所有的一级菜单选项存放于languages\zh_cn\admin\common.php 文件里面,使用 $_LANG['02_cat_and_goods'] = '商品管理';  这样 ...

  4. ASP.NET权限管理

    ASP.NET Web Forms权限管理: 我要将一个文件夹只能让一个用户组访问怎么办? 可否在网站根目录下的web.config里这样设置: <location path="adm ...

  5. 多年前写的一个ASP.NET网站管理系统,到现在有些公司在用

    多年前写的一个ASP.NET网站管理系统,到现在有些公司在用 今早上接到一个电话,自已多年前写的一个ASP.NET网站管理系统,一个公司在用,出了点问题, 第一点是惊奇,5,6年前的东东,手机号码换了 ...

  6. 64位Win7下运行ASP+Access网站的方法

    64位Win7下运行ASP+Access网站的方法 近日系统升级为WIN7 64位之后,突然发现原本运行正常的ASP+ACCESS网站无法正常连接数据库. 网上搜索多次,终于解决了问题,总结了几条经验 ...

  7. 构建ASP.NET网站十大必备工具(2)

    正常运行时间 当一个网站发布以后,你肯定希望你的网站不会遇到任何问题,一直处在正常运行状态之中.现在,我使用下面这些工具来监控“Superexpert.com”网站,确保它一直处在正常运行状态之中. ...

  8. 如何在IIS6,7中部署ASP.NET网站

    http://www.cnblogs.com/fish-li/archive/2012/02/26/2368989.html 阅读目录 开始 查看web.config文件 在IIS中创建网站 IIS6 ...

  9. 解决64位系统下IIS 8下Asp+Access网站配置

    一.IIS7的安装 Windows 中IIS8是默认不安装的,所以在安装完windows 8,之后如果需要安装IIS8的话,就要自己动手了. 安装的步骤为:开始>控制面板>程序>打开 ...

随机推荐

  1. JS 計算文本域還能輸入多少個字符

    //輸入計數 //count:能輸入的數據總量    function Calculation(v, count) {        var span = $(v).next();        va ...

  2. web.xml的首页调用struts2的action解决方法

    1,首先在struts.xml里添加如下代码:注意位置 <constant name="struts.action.extension" value="do,act ...

  3. Hadoop HDFS编程 API入门系列之从本地上传文件到HDFS(一)

    不多说,直接上代码. 代码 package zhouls.bigdata.myWholeHadoop.HDFS.hdfs5; import java.io.IOException; import ja ...

  4. java应用死循环排查方法或查找程序消耗资源的线程方法(面试)

    今天遇到一个面试,怎么在一堆线程中查找一个死循环? 如果遇到线上应用cpu飙升,并出现OutOfMemery怎么办? 首先线上应用的jvm配置要养成良好的习惯,增加一下配置则可以在jvm发生 oom的 ...

  5. 基于WDF的PCI/PCIe接口卡Windows驱动程序(3)- 驱动程序代码(头文件)

    原文出处:http://www.cnblogs.com/jacklu/p/4679304.html 在WDF的PCIe驱动程序中,共有四个.h文件(Public.h  Driver.h  Device ...

  6. 树莓派USB摄像头与camera模块对比

    http://www.cnblogs.com/weixinforspurs/p/5575962.html ——————————————————————————————————————————————— ...

  7. jdk代理和cglib代理

    1.jdk静态代理(静态代理和动态代理) 本质:在内存中构建出接口的实现类. 缺陷:只能对实现接口的类实现动态代理, 使用cglib可以对没有实现接口的类进行动态代理. 2.cglib动态代理     ...

  8. cognos函数学习

    1.aggregate(currentMeasure within set set([意健险], [财产险], [车险])) 汇总所有 2.tuple([保费],[车险]) 3.percentage( ...

  9. Tlist

    Tlist (Classes.pas) 在我刚开始接触TList的时候,TList搞得我迷雾重重,都是Capacity属性惹的祸.我查了Delphi的帮助,它说Capacity是TList的最大容量, ...

  10. Selenium2+python自动化19-单选框和复选框(radiobox、checkbox)

    本篇主要介绍单选框和复选框的操作 一.认识单选框和复选框 1.先认清楚单选框和复选框长什么样 2.各位小伙伴看清楚哦,上面的单选框是圆的:下图复选框是方的,这个是业界的标准,要是开发小伙伴把图标弄错了 ...