问题
I've rewritten this post to make it more simple. This is the code I've got (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();
}
}
}
which is an altered version of this. I'm using MVC Areas Lib so I can't see how MvcSiteMap can work with this as it no longer works by {controller}/{action}
like it did before.
Say I have a page like http://localhost/mycontroller/myaction
and it exists in the SiteMap, then the menu will be generated fine. But say I do http://localhost/mycontroller/myaction/50
and specify a parameter, the SiteMap generator will no longer work because this URL does not exist. The tutorial doesn't cover MVC Areas Lib, so the solution to this problem doesn't work.
回答1:
Checkout MvcSitemap on Codeplex
回答2:
It is time to rejoice: Change Set 24979 implements area support.
"Defining sitemap nodes"
...
area | Optional | Area of the specified controller the node should link to
...
回答3:
look, in asp.net the SiteMap is greatly implemented unlike it's 'non standard' implementation in asp.net mvc :). I have to choose also for my app how to organise a site map. I think this solution is far to be ideal and elegant, but it seems very nice for me. In my Base data view object that I use for displaying data on the view I make all this functionality fluently for the sake of commodity (I love fluent code ), so there is there a method that generates hard coded path in dependanse of the ''link''. So what is link?, the link represents a static class with all my links in my site. So for example your :
http://localhost/myarea/contract/viewcontract/12
In ''links'' means: Links.ContractView and in my controller I have smth like this:
BaseDV.SetPageMapBasedOnLink(Links.ContractView)
and in SetPageMapBasedOnLink you have a switch that based on Links value sets the appropriate title or what ever you want. I hope you got the idea, and this will help you to decide!
回答4:
This code looks a bit off-track to me. The main idea of .NET MVC is separating concerns, so when you populate a StringBuilder object, you're missing the point a bit. What I'd expect is code to return a collection of all possible nodes, and then you send it to your View and it does the actual HTML layouting.
Now, the reason you can't get .../myaction/{id} to work is probably because SiteMapNode is not aware of your data structure - only of the Routes in your application. If they made it work in http://mvcsitemap.codeplex.com/ perhaps it worths a look, but my guess is they didn't. You'll have to populate that area yourself (e.g. for each node which has a parameter, check what node it is and load all the possible values from your data store). And again - pass objects back from your helper class, not HTML.
来源:https://stackoverflow.com/questions/1075152/sitemap-htmlhelper-asp-net-mvc