2009-07-02 75 views
3

我已經重寫了這篇文章,使它更簡單。這是我已經得到了代碼(HtmlHelper):SiteMap HtmlHelper ASP.NET MVC

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Web; 
using System.Runtime.CompilerServices; 
using System.Web.Mvc; 
using System.Text; 

using System.Web.Routing; 

namespace Intranet.Helpers 
{ 
    public static class MenuHelper 
    { 
    private static string GetBackLink(SiteMapNode parentNode) 
    { 
     return "<li class='li-back'><a href='" + parentNode.Url + "' title='" + parentNode.Title + "'></a></li>"; 
    } 

    public static string Menu(this HtmlHelper helper) 
    { 
     var sb = new StringBuilder(); 
     SiteMapNodeCollection siteMapNodeCollection; 
     sb.Append("<ul>"); 
     SiteMapNode currentNode = SiteMap.CurrentNode; 

     if (!SiteMap.CurrentNode.Equals(SiteMap.RootNode)) 
     { 
     if (!SiteMap.CurrentNode.HasChildNodes) 
      sb.Append(GetBackLink(SiteMap.CurrentNode.ParentNode.ParentNode)); 
     else 
      sb.Append(GetBackLink(SiteMap.CurrentNode.ParentNode)); 
     } 

     if (!SiteMap.CurrentNode.HasChildNodes) 
     siteMapNodeCollection = SiteMap.CurrentNode.ParentNode.ChildNodes; 
     else 
     siteMapNodeCollection = SiteMap.CurrentNode.ChildNodes; 

     foreach (SiteMapNode node in siteMapNodeCollection) 
     { 
     if(node.Description.Equals("hidden")) continue; 

     if (node.Url.Length == 0 && node.Description.Equals("separator")) 
      sb.Append("<li class=\"li-separator\"></li>"); 
     else if (node.Url.Length == 0 && node.Description.Equals("heading")) 
      sb.Append("<li class=\"li-heading\">" + node.Title + "</li>"); 
     else 
     { 
      if (node.HasChildNodes) 
      { 
      if (node.NextSibling != null) 
       sb.Append("<li class=\"li-sub\"><a href=\"" + node.Url + "\">" + node.Title + "</a></li>"); 
      else 
       sb.Append("<li class=\"li-sub last-child\"><a href=\"" + node.Url + "\">" + node.Title + "</a></li>"); 
      } 
      else 
      { 
      if (node.NextSibling != null) 
       sb.Append("<li><a href='" + node.Url + "'>" + node.Title + "</a></li>"); 
      else 
       sb.Append("<li class='last-child'><a href='" + node.Url + "'>" + node.Title + "</a></li>"); 
      } 
     } 
     } 

     sb.Append("</ul>"); 
     return sb.ToString(); 
    } 
    } 
} 

這是this改編版。我正在使用MVC Areas Lib,所以我看不到MvcSiteMap可以如何工作,因爲它不再像以前那樣通過{controller}/{action}工作。

假設我有一個像http://localhost/mycontroller/myaction這樣的頁面,它存在於SiteMap中,那麼菜單會很好地生成。但是說我做http://localhost/mycontroller/myaction/50並指定一個參數,SiteMap生成器將不再工作,因爲這個URL不存在。 tutorial不包括MVC Areas Lib,所以此問題的解決方案不起作用。

回答

0

看起來,在asp.net中,SiteMap的實現與asp.net mvc中的'非標準'實現不同。我還必須爲我的應用程序選擇如何組織網站地圖。我認爲這個解決方案遠非理想和優雅,但它對我來說似乎非常好。在我用於在視圖中顯示數據的基本數據視圖對象中,爲了商品(我喜歡流暢的代碼),我使用了所有這些功能,所以有一種方法可以根據''生成硬編碼路徑鏈接''。那麼鏈接是什麼?這個鏈接代表了一個靜態類,其中包含我網站中的所有鏈接。因此,例如您:

http://localhost/myarea/contract/viewcontract/12 

在'鏈接'方式:Links.ContractView和我的控制器我有水木清華這樣的:

BaseDV.SetPageMapBasedOnLink(Links.ContractView) 

和SetPageMapBasedOnLink您有基於開關鏈接值設置適當的標題或任何你想要的。 我希望你明白了,這會幫助你決定!

+0

如果你檢查我的編輯,你會看到它自動生成我的菜單基於HtmlHelper按照我鏈接到的文章的建議。根據你的翻譯,我不確定,這對我個人而言是如何工作的。不過,我可以看到它背後的想法。 – Kezzer 2009-07-07 11:13:16

11
+0

是的,但我正在使用區域庫,所以我沒有看到如何工作。 – Kezzer 2009-07-08 07:56:37

+0

今天測試過,它肯定不會工作,因爲MvcSiteMap基於{controller}/{action}而不是area/{controller}/{action}。 – Kezzer 2009-07-09 09:14:10

+0

Gah,我現在使用它,因爲它有地區的支持,但我不能標記你的答案是正確的:( – Kezzer 2009-10-14 08:19:30

0

此代碼看起來有點偏離軌道給我。 .NET MVC的主要思想是分離關注點,所以當你填充一個StringBuilder對象時,你會錯過這一點。我期望的代碼是返回所有可能節點的集合,然後將其發送到您的視圖,並執行實際的HTML佈局。

現在,您無法獲得.../myaction/{id}工作的原因可能是因爲SiteMapNode不知道您的數據結構 - 只有您的應用程序中的路徑。如果他們使它在http://mvcsitemap.codeplex.com/工作,也許它值得一看,但我的猜測是他們沒有。您必須自己填充該區域(例如,對於每個有參數的節點,檢查它是哪個節點並從數據存儲裝載所有可能的值)。再次 - 從你的助手類傳回對象,而不是HTML。

5

現在是時候欣喜:Change Set 24979實現區域支持。

「定義站點地圖結點」

...

區|可選| 指定控制器的區域應爲 鏈接到

...