3

我重写了这篇文章以使其更简单。这是我得到的代码(a HtmlHelper):

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 不存在。本教程不涵盖MVC Areas Lib,因此该问题的解决方案不起作用。

4

4 回答 4

11

在 Codeplex 上签出 MvcSitemap

于 2009-07-08T03:36:57.953 回答
5

是时候庆幸了:Change Set 24979实现了区域支持。

“定义站点地图节点”

...

面积 | 可选 | 节点应链接到的指定控制器的区域

...

于 2009-08-10T07:33:57.957 回答
0

这段代码在我看来有点偏离轨道。.NET MVC 的主要思想是分离关注点,因此当您填充 StringBuilder 对象时,您有点忽略了这一点。我期望的是代码返回所有可能节点的集合,然后将其发送到您的视图并执行实际的 HTML 布局。

现在,您无法使 .../myaction/{id} 工作的原因可能是因为 SiteMapNode 不知道您的数据结构 - 仅知道应用程序中的路由。如果他们让它在http://mvcsitemap.codeplex.com/中工作,也许值得一看,但我猜他们没有。您必须自己填充该区域(例如,对于每个具有参数的节点,检查它是什么节点并从您的数据存储中加载所有可能的值)。再一次 - 从你的帮助类传回对象,而不是 HTML。

于 2009-07-12T00:09:31.680 回答
0

看,在 asp.net 中,SiteMap 的实现与它在 asp.net mvc 中的“非标准”实现不同:)。我还必须为我的应用程序选择如何组织站点地图。我认为这个解决方案远非理想和优雅,但对我来说似乎非常好。在我用于在视图上显示数据的基本数据视图对象中,我为了商品而流畅地制作了所有这些功能(我喜欢流畅的代码),所以有一种方法可以生成依赖于“”的硬编码路径关联''。那么什么是链接?,链接代表一个静态类,其中包含我网站中的所有链接。例如,您的:

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

在“链接”中意味着:Links.ContractView 在我的控制器中我有这样的东西:

BaseDV.SetPageMapBasedOnLink(Links.ContractView)

在 SetPageMapBasedOnLink 中,您有一个基于 Links 值的开关设置适当的标题或您想要的任何内容。我希望你有这个想法,这将帮助你做出决定!

于 2009-07-03T13:58:47.190 回答