閱讀101 返回首頁    go 技術社區[雲棲]


利用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="https://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
如果你想及時得到個人撰寫文章以及著作的消息推送,或者想看看個人推薦的技術資料,可以掃描左邊二維碼(或者長按識別二維碼)關注個人公眾號(原來公眾帳號蔣金楠的自媒體將會停用)。
本文版權歸作者和博客園共有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁麵明顯位置給出原文連接,否則保留追究法律責任的權利。
原文鏈接

最後更新:2017-10-25 16:33:41

  上一篇:go  如何在調用WCF服務之前彈出一個確認對話框?
  下一篇:go  利用EntLib授權機製實現對ASP.NET頁麵的自動授權