用sitemap做主页的菜单栏
首先打开vs--> 新建项-->选择站点地图.
站点地图建好了 其中具体的节点根据自己情况配好就行。
接下来是两个非常重要的类:
using System.Collections.Generic; using System.Web.Routing; //code from Telerik MVC Extensions namespace PowerInspact.Menu { public class SiteMapNode { /// <summary> /// Initializes a new instance of the <see cref="SiteMapNode"/> class. /// </summary> public SiteMapNode() { RouteValues = new RouteValueDictionary(); ChildNodes = new List<SiteMapNode>(); } /// <summary> /// Gets or sets the title. /// </summary> /// <value>The title.</value> public string Title { get; set; } /// <summary> /// Gets or sets the name of the controller. /// </summary> /// <value>The name of the controller.</value> public string ControllerName { get; set; } /// <summary> /// Gets or sets the name of the action. /// </summary> /// <value>The name of the action.</value> public string ActionName { get; set; } /// <summary> /// Gets or sets the route values. /// </summary> /// <value>The route values.</value> public RouteValueDictionary RouteValues { get; set; } /// <summary> /// Gets or sets the URL. /// </summary> /// <value>The URL.</value> public string Url { get; set; } /// <summary> /// Gets or sets the child nodes. /// </summary> /// <value>The child nodes.</value> public IList<SiteMapNode> ChildNodes { get; set; } /// <summary> /// Gets or sets the image path /// </summary> /// <value>The name of the image path.</value> public string ImageUrl { get; set; } /// <summary> /// Gets or sets the item is visible /// </summary> /// <value>A value indicating whether the item is visible</value> public bool Visible { get; set; } } }
//code from Telerik MVC Extensions using System; using System.IO; using System.Linq; using System.Web.Routing; using System.Xml; namespace PowerInspact.Menu { public class XmlSiteMap { public XmlSiteMap() { RootNode = new SiteMapNode(); } public SiteMapNode RootNode { get; set; } public virtual SiteMapNode LoadFrom(string physicalPath) { string str = AppDomain.CurrentDomain.SetupInformation.ApplicationBase; string content = File.ReadAllText(str + physicalPath); if (!string.IsNullOrEmpty(content)) { using (var sr = new StringReader(content)) { using (var xr = XmlReader.Create(sr, new XmlReaderSettings { CloseInput = true, IgnoreWhitespace = true, IgnoreComments = true, IgnoreProcessingInstructions = true })) { var doc = new XmlDocument(); doc.Load(xr); if ((doc.DocumentElement != null) && doc.HasChildNodes) { XmlNode xmlRootNode = doc.DocumentElement.FirstChild; Iterate(RootNode, xmlRootNode); } } } } return RootNode; } private static void Iterate(SiteMapNode siteMapNode, XmlNode xmlNode) { PopulateNode(siteMapNode, xmlNode); foreach (XmlNode xmlChildNode in xmlNode.ChildNodes) { if (xmlChildNode.LocalName.Equals("siteMapNode", StringComparison.InvariantCultureIgnoreCase)) { var siteMapChildNode = new SiteMapNode(); siteMapNode.ChildNodes.Add(siteMapChildNode); Iterate(siteMapChildNode, xmlChildNode); } } } private static void PopulateNode(SiteMapNode siteMapNode, XmlNode xmlNode) { try { //title siteMapNode.Title = GetStringValueFromAttribute(xmlNode, "title"); //routes, url string controllerName = GetStringValueFromAttribute(xmlNode, "controller"); string actionName = GetStringValueFromAttribute(xmlNode, "action"); string url = GetStringValueFromAttribute(xmlNode, "url"); if (!string.IsNullOrEmpty(controllerName) && !string.IsNullOrEmpty(actionName)) { siteMapNode.ControllerName = controllerName; siteMapNode.ActionName = actionName; } else if (!string.IsNullOrEmpty(url)) { siteMapNode.Url = url; } //image URL siteMapNode.ImageUrl = GetStringValueFromAttribute(xmlNode, "ImageUrl"); //permission name var permissionNames = GetStringValueFromAttribute(xmlNode, "PermissionNames"); string pers=System.Web.HttpContext.Current.Session["persioons"].ToString(); string[] arr1 = pers.Substring(0, pers.Length-1).Split(','); //当前该用户的权限 if (siteMapNode.Title == "组织/企业管理" || siteMapNode.Title == "检测报告" || siteMapNode.Title == "系统设置" || siteMapNode.Title == "标准库" || siteMapNode.Title == "用户设置") { string[] arr = permissionNames.Split(','); if (IsVisible(arr, arr1)) { siteMapNode.Visible = true; } else { siteMapNode.Visible = false; ; } } else { if (IsVisible(arr1, permissionNames)) { siteMapNode.Visible = true; } else { siteMapNode.Visible = false; ; } } } catch (Exception) { } } public static bool IsVisible(string[] arr, string[] arr1) { bool b = false; for (int i = 0; i < arr.Length; i++) { for (int j = 0; j < arr1.Length; j++) { if (arr[i] == arr1[j]) { b = true; break; } } } return b; } public static bool IsVisible(string[] arr, string permissionNames) { bool b = false; for (int i = 0; i < arr.Length; i++) { if (permissionNames == arr[i]) { b = true; break; } } return b; } private static string GetStringValueFromAttribute(XmlNode node, string attributeName) { string value = null; if (node.Attributes.Count > 0) { XmlAttribute attribute = node.Attributes[attributeName]; if (attribute != null) { value = attribute.Value; } } return value; } } }
这两个类完全可以直接拿去用,只是第二个类里面有一些判断要改一下(登陆成功是否显示),其他都不用动。
最后来看看在母版页里如何调用:
<!-- 左边菜单栏 style can be found in sidebar.less --> <ul class="sidebar-menu" data-widget="tree"> <li class="header">MAIN NAVIGATION</li> @{ string strUrl = Request.Url.ToString(); //load sitemap 注意命名空间 var siteMap = new PowerInspact.Menu.XmlSiteMap(); PowerInspact.Menu.SiteMapNode Nodes = siteMap.LoadFrom("sitemap.config"); //注意站点地图路劲 string str = ""; if (Nodes.ChildNodes.Count > 0) { for (int i = 0; i < Nodes.ChildNodes.Count; i++) //父级 { if (Nodes.ChildNodes[i].Visible) { bool IsActive=false; string[] Persionns = Nodes.ChildNodes[i].ImageUrl.ToString().Split(','); for (int k = 0; k < Persionns.Length; k++) { if (strUrl.Contains(Persionns[k])) { IsActive = true; } } string ico = ""; if (IsActive) { ico = "fa-suitcase"; str += " <li class='active treeview'>"; } else { ico = "fa-cogs"; str += " <li class='treeview'>"; } if (Nodes.ChildNodes[i].ChildNodes.Count > 0) //子级fa fa-cogs fa-suitcase { str += "<a href='#'><i class='fa "+ico+"'></i><span>" + Nodes.ChildNodes[i].Title + "</span><span class='pull-right-container'><i class='fa fa-angle-left pull-right'></i></span></a>"; str += "<ul class='treeview-menu left_menu'>"; for (int j = 0; j < Nodes.ChildNodes[i].ChildNodes.Count; j++) { if (Nodes.ChildNodes[i].ChildNodes[j].Visible) { if (strUrl.Contains(Nodes.ChildNodes[i].ChildNodes[j].ControllerName)) { str += @"<li class='active'><a href='/" + Nodes.ChildNodes[i].ChildNodes[j].ControllerName + "'><i class='fa fa-circle-o'></i>" + Nodes.ChildNodes[i].ChildNodes[j].Title + "</a></li>"; } else { str += @"<li><a href='/" + Nodes.ChildNodes[i].ChildNodes[j].ControllerName + "'><i class='fa fa-circle-o'></i>" + Nodes.ChildNodes[i].ChildNodes[j].Title + "</a></li>"; } } } str += "</ul>"; } str += "</li>"; } } } ViewData["strhtnl"] = str; } @Html.Raw(ViewData["strhtnl"])</ul>
人生的成功不在于拿到一副好牌,而是怎样将坏牌打好。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· 三行代码完成国际化适配,妙~啊~
· .NET Core 中如何实现缓存的预热?
· 如何调用 DeepSeek 的自然语言处理 API 接口并集成到在线客服系统