对于动态菜单生成,在很多具有权限控制的项目中非常常见。最近遇到一个需求就是不同用户具有不同权限,该权限是页面级的,所以需要根据不同用户的权限情况动态生成菜单项。
首先,我把菜单项中的内容先存储在一个XML里面,在加载模板页时只需根据查找到的权限集合找到相应菜单项信息,然后添加到菜单项中就可以。
<?xml version="1.0" encoding="utf-8" ?>
<accessMenu>
<rootItem key="A" value="A页面">
<childItem key="A01" value="~/About.aspx" text="页面A01"></childItem>
<childItem key="A02" value="~/About.aspx" text="页面A02"></childItem>
</rootItem>
<rootItem key="B" value="B页面">
<childItem key="B01" value="~/About.aspx" text="页面B01"></childItem>
<childItem key="B02" value="~/About.aspx" text="页面B02"></childItem>
<childItem key="B03" value="~/About.aspx" text="页面B03"></childItem>
</rootItem>
<rootItem key="C" value="C页面">
<childItem key="C01" value="~/About.aspx" text="页面C01"></childItem>
<childItem key="C02" value="~/About.aspx" text="页面C02"></childItem>
<childItem key="C03" value="~/About.aspx" text="页面C03"></childItem>
<childItem key="C04" value="~/About.aspx" text="页面C04"></childItem>
</rootItem>
<rootItem key="D" value="D页面">
<childItem key="D01" value="~/About.aspx" text="页面D01"></childItem>
</rootItem>
</accessMenu>
其中 rootItem节点代表根菜单项,value代表的显示文字,childItem代表二级菜单项,key代表页面编号,数据库中存放的是用户与页面的对应。value为菜单项的导航链接,text为子菜单项显示文字。
然后写了个XML读取节点的类,只为演示,很不严谨。
public class XMLHelper
{
private string xmlPath = string.Empty;
private XmlDocument doc = null;
public XMLHelper(string path)
{
xmlPath = path;
doc = new XmlDocument();
doc.Load(path);
}
/// <summary>
/// 获取根菜单项的文本
/// </summary>
/// <param name="key"></param>
/// <returns></returns>
public string GetRootValue(string key)
{
XmlNode accnode = doc.SelectSingleNode("/*/rootItem[@key='" + key + "']");
return accnode.Attributes["value"].Value;
}
/// <summary>
/// 获取子菜单项的文本
/// </summary>
/// <param name="key"></param>
/// <returns></returns>
public string GetChildItemText(string key)
{
XmlNode accnode = doc.SelectSingleNode("/*/rootItem/childItem[@key='" + key + "']");
return accnode.Attributes["text"].Value;
}
/// <summary>
/// 获取子菜单项的导航链接
/// </summary>
/// <param name="key"></param>
/// <returns></returns>
public string GetChildItemValue(string key)
{
XmlNode accnode = doc.SelectSingleNode("/*/rootItem/childItem[@key='" + key + "']");
return accnode.Attributes["value"].Value;
}
当我们的模板页加载的时候,从数据库中读取相应用户的权限,演示为手动生成一个集合。
private IList<string> AccessList()
{
return new List<string> { "A01", "B02", "B03", "C01", "C04", "D01" };
}
最后只需在 模板页加载的时候处理一下就可以了。
protected void Page_Load(object sender, EventArgs e)
{
IList<string> access = AccessList();
XMLHelper xml = new XMLHelper(Server.MapPath("~/Access.xml"));
MenuItem aRoot = null;
MenuItem bRoot = null;
MenuItem cRoot = null;
MenuItem dRoot = null;
foreach (var item in access)
{
//获取指定权限页面的根菜单项
string preString = item.Substring(0, 1);
switch (preString)
{
case "A":
if (aRoot == null)
{
aRoot = new MenuItem();
aRoot.Text = xml.GetRootValue(preString);
}
MenuItem achildItem = new MenuItem();
achildItem.Text = xml.GetChildItemText(item);
achildItem.NavigateUrl = xml.GetChildItemValue(item);
aRoot.ChildItems.Add(achildItem);
break;
case "B":
if (bRoot == null)
{
bRoot = new MenuItem();
bRoot.Text = xml.GetRootValue(preString);
}
MenuItem bchildItem = new MenuItem();
bchildItem.Text = xml.GetChildItemText(item);
bchildItem.NavigateUrl = xml.GetChildItemValue(item);
bRoot.ChildItems.Add(bchildItem);
break;
case "C":
if (cRoot == null)
{
cRoot = new MenuItem();
cRoot.Text = xml.GetRootValue(preString);
}
MenuItem cchildItem = new MenuItem();
cchildItem.Text = xml.GetChildItemText(item);
cchildItem.NavigateUrl = xml.GetChildItemValue(item);
cRoot.ChildItems.Add(cchildItem);
break;
case "D":
if (dRoot == null)
{
dRoot = new MenuItem();
dRoot.Text = xml.GetRootValue(preString);
}
MenuItem dchildItem = new MenuItem();
dchildItem.Text = xml.GetChildItemText(item);
dchildItem.NavigateUrl = xml.GetChildItemValue(item);
dRoot.ChildItems.Add(dchildItem);
break;
default:
break;
}
}
if (aRoot != null)
Menu1.Items.Add(aRoot);
if (bRoot != null)
Menu1.Items.Add(bRoot);
if (cRoot != null)
Menu1.Items.Add(cRoot);
if (dRoot != null)
Menu1.Items.Add(dRoot);
}
private IList<string> AccessList()
{
return new List<string> { "A01", "B02", "B03", "C01", "C04", "D01" };
}