2009-07-02 198 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实现区域支持。

“定义站点地图结点”

...

区|可选| 指定控制器的区域应为 链接到

...