利用ASP.NET SiteMap生成与Bootstrap"兼容"菜单

简介:

Bootstrap是Twitter推出的一个开源的用于前端开发的工具包。它由Twitter的设计师Mark Otto和Jacob Thornton合作开发,是一个CSS/HTML框架。本文提供了一个解决方案利用ASP.NET SiteMap生成与Bootstrap“兼容”的菜单。具体的原理很简单,就是利用SiteMap读取预先定义的网站结构,按照Bootstrap的标准生成相应的HTML。[源代码从这里下载]

我们将基于菜单的呈现定义在HtmlHelper的扩展方法中。如下面的代码片断,扩展方法RenderBootstrapMenu具有一个缺省的参数siteMapProviderName ,表示读取SiteMap结构采用的SiteMapProvider的配置名称。在该方法中,我们通过指定的SiteMapProvider(如果没有指定,则采用默认配置的SiteMapProvider)得到代表整个SiteMap根节点的SiteMapNode对象,并将其子节点(以及子节点的子节点,…)转换成相应的HTML。

   1: public static class BootstrapMenuExtensions
   2: {        
   3:     public static MvcHtmlString RenderBootstrapMenu(this HtmlHelper helper, string siteMapProviderName = "")
   4:     {
   5:         SiteMapProvider siteMapProvider = !string.IsNullOrEmpty(siteMapProviderName) ?
   6:             SiteMap.Providers[siteMapProviderName] :
   7:             SiteMap.Provider ?? SiteMap.Providers.Cast<SiteMapProvider>().First();
   8:         return new MvcHtmlString( RenderMenu(siteMapProvider.RootNode.ChildNodes));
   9:     }
  10:  
  11:     private static string RenderMenu(SiteMapNodeCollection siteMapNodes)
  12:     {
  13:         TagBuilder ul = new TagBuilder("ul");
  14:         ul.AddCssClass("nav");
  15:         ul.AddCssClass("nav-pills");
  16:  
  17:         foreach (SiteMapNode node in siteMapNodes)
  18:         {
  19:             ul.InnerHtml += GetMenuItemHtml(node);
  20:         }
  21:         return ul.ToString();
  22:     }
  23:  
  24:     private static string GetMenuItemHtml(SiteMapNode siteMapNode)
  25:     {
  26:         TagBuilder li = new TagBuilder("li");
  27:         li.AddCssClass("dropdown");
  28:  
  29:         TagBuilder link = new TagBuilder("a");
  30:         link.Attributes.Add("href", siteMapNode.Url);
  31:         link.Attributes.Add("title", siteMapNode.Description);
  32:         link.SetInnerText(siteMapNode.Title);
  33:  
  34:         if (!siteMapNode.HasChildNodes)
  35:         {
  36:             li.InnerHtml += link.ToString();
  37:             return li.ToString();
  38:         }
  39:  
  40:         link.AddCssClass("dropdown-toggle");
  41:         link.Attributes.Add("data-toggle", "dropdown");
  42:         TagBuilder caret = new TagBuilder("b");
  43:         caret.AddCssClass("caret");
  44:         link.InnerHtml += caret.ToString();
  45:  
  46:         TagBuilder ul = new TagBuilder("ul");
  47:         ul.AddCssClass("dropdown-menu");
  48:         foreach (SiteMapNode node in siteMapNode.ChildNodes)
  49:         {
  50:             ul.InnerHtml += GetSubItemHtml(node);
  51:         }
  52:         li.InnerHtml += link.ToString();
  53:         li.InnerHtml += ul.ToString();
  54:         return li.ToString();
  55:     }
  56:  
  57:     private static string GetSubItemHtml(SiteMapNode siteMapNode)
  58:     {
  59:         TagBuilder li = new TagBuilder("li");
  60:  
  61:         TagBuilder link = new TagBuilder("a");
  62:         link.Attributes.Add("href", siteMapNode.Url);
  63:         link.Attributes.Add("title", siteMapNode.Description);
  64:         link.SetInnerText(siteMapNode.Title);
  65:         li.InnerHtml += link.ToString();
  66:  
  67:         if (siteMapNode.HasChildNodes)
  68:         {
  69:             link.AddCssClass("dropdown-toggle");
  70:             link.Attributes.Add("data-toggle", "dropdown");
  71:  
  72:             li.AddCssClass("dropdown-submenu");
  73:             TagBuilder ul = new TagBuilder("ul");
  74:             ul.AddCssClass("dropdown-menu");
  75:             foreach (SiteMapNode node in siteMapNode.ChildNodes)
  76:             {
  77:                 ul.InnerHtml += GetSubItemHtml(node);
  78:             }
  79:             li.InnerHtml += ul.ToString();
  80:         }
  81:         return li.ToString();
  82:     }
  83: }

假设我们采用XmlSiteMapProvider,SiteMap结构通过如下的XML来定义,整个结构具有三个层次。

   1: <?xml version="1.0" encoding="utf-8" ?>
   2: <siteMap xmlns="http://schemas.microsoft.com/AspNet/SiteMap-File-1.0" >
   3:   <siteMapNode url="Root" title="Root"  description="">
   4:     <siteMapNode url="A1" title="A1"  description="1st Level 1" />
   5:     <siteMapNode url="A2" title="A2"  description="1st Level 2" />
   6:     <siteMapNode url="A3" title="A3"  description="1st Level 3">
   7:       <siteMapNode url="B1" title="B1"  description="2nd Level 1" />
   8:       <siteMapNode url="B2" title="B2"  description="2nd Level 2" />
   9:       <siteMapNode url="B3" title="B3"  description="2nd Level 3">
  10:         <siteMapNode url="C1" title="C1"  description="3rd Level 1" />
  11:         <siteMapNode url="C2" title="C2"  description="3rd Level 2" />
  12:         <siteMapNode url="C3" title="C3"  description="3rd Level 3" />
  13:       </siteMapNode>
  14:     </siteMapNode>
  15:   </siteMapNode>
  16: </siteMap>

在如下一个View中,我们调用扩展方法RenderBootstrapMenu将由上面这个XML定义的菜单节点呈现出来。

   1: <!DOCTYPE html>
   2: <html>
   3: <head>
   4:     <title>Bootstrap Menu</title>
   5:     <link href="bootstrap/css/bootstrap.min.css" rel="stylesheet" />    
   6: </head>
   7: <body>
   8:     <script type="text/javascript" src="http://code.jquery.com/jquery-latest.js"></script>
   9:     <script type="text/javascript" src="bootstrap/js/bootstrap.min.js"></script>
  10:     <div>
  11:         @Html.RenderBootstrapMenu()
  12:     </div>
  13: </body>
  14: </html>

最终呈现的效果如下所示:

image

菜单对应的HTML为:

   1: <ul class="nav-pills nav">
   2:     <li class="dropdown"><a href="/A1" title="1st Level 1">A1</a></li>
   3:     <li class="dropdown"><a href="/A2" title="1st Level 2">A2</a></li>
   4:     <li class="dropdown"><a class="dropdown-toggle" data-toggle="dropdown" href="/A3" title="1st Level 3">A3<b class="caret"></b></a>
   5:         <ul class="dropdown-menu">
   6:             <li><a href="/B1" title="2nd Level 1">B1</a></li>
   7:             <li><a href="/B2" title="2nd Level 2">B2</a></li>
   8:             <li class="dropdown-submenu"><a href="/B3" title="2nd Level 3">B3</a>
   9:                   <ul class="dropdown-menu">
  10:                        <li><a href="/C1" title="3rd Level 1">C1</a></li>
  11:                        <li><a href="/C2" title="3rd Level 2">C2</a></li>
  12:                        <li><a href="/C3" title="3rd Level 3">C3</a></li>
  13:                   </ul>
  14:             </li>
  15:         </ul>
  16:     </li>
  17: </ul>

作者:蒋金楠
微信公众账号:大内老A
微博: www.weibo.com/artech
如果你想及时得到个人撰写文章以及著作的消息推送,或者想看看个人推荐的技术资料,可以扫描左边二维码(或者长按识别二维码)关注个人公众号(原来公众帐号 蒋金楠的自媒体将会停用)。
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
相关文章
|
6月前
|
前端开发
【前端异常】解决前端引入Bootstrap的dropdowns 菜单时报错,Uncaught TypeError: Bootstrap‘s dropdowns require Popper.js
【前端异常】解决前端引入Bootstrap的dropdowns 菜单时报错,Uncaught TypeError: Bootstrap‘s dropdowns require Popper.js
56 0
|
3月前
|
开发框架 .NET 定位技术
asp.net core3.1 c# 生成三种sitemap
asp.net core3.1 c# 生成三种sitemap
17 0
|
前端开发
bootstrap如何去除自带的样式----导航栏中的菜单实现平滑的过渡到对应的菜单区域-------动态跟换模态框中的内容
bootstrap如何去除自带的样式----导航栏中的菜单实现平滑的过渡到对应的菜单区域-------动态跟换模态框中的内容
|
开发框架 前端开发 JavaScript
ASP.NET Core 2.1以上Bootstr ap4前端模板文件,开发环境与发布环境前端模板environment的使用
ASP.NET Core 2.1以上Bootstr ap4前端模板文件,开发环境与发布环境前端模板environment的使用
213 0
ASP.NET Core 2.1以上Bootstr ap4前端模板文件,开发环境与发布环境前端模板environment的使用
|
移动开发 前端开发 JavaScript
Bootstrap 4/3 页面基础模板 与 兼容旧版本浏览器
Bootstrap 4/3 页面基础模板 与 兼容旧版本浏览器
411 0
|
JavaScript 前端开发
|
Web App开发
Bootstrap学习笔记--下拉菜单,折叠,菜单,标签,Pills
下拉菜单: 下拉菜单是比较常见的 直接看源码: .dropdown表示下拉框 按钮和下拉框都要放在dropdown类的div下 要打开下拉菜单,请使用按钮或具有属性的类.
3194 0
|
前端开发 .NET 数据库
ASP.NET Core 一步步搭建个人网站(3)_菜单管理
上一章,我们实现了用户的注册和登录,登录之后展示的是我们的主页,页面的左侧是多级的导航菜单,定位并展示用户需要访问的不同页面。目前导航菜单是写死的,考虑以后菜单管理的便捷性,我们这节实现下可视化配置菜单的功能,这样以后我们可以动态的配置导航菜单,不用再编译发布网站程序了。
1405 0