Ответ 1
@ScottE, мне кажется, мне удалось воспроизвести код, который я использовал для решения этой проблемы:
using System;
using System.Web;
using Microsoft.SharePoint;
using Microsoft.SharePoint.Publishing;
using Microsoft.SharePoint.Publishing.Navigation;
namespace StackOverflow.SharePoint
{
public class Question2602537PortalSiteMapProvider : PortalSiteMapProvider
{
public override SiteMapNodeCollection GetChildNodes(System.Web.SiteMapNode node)
{
bool expandChildNodes = false;
if (SPContext.Current != null)
{
expandChildNodes = NodeIsAncestorOfCurrentNode(node);
}
if (expandChildNodes)
{
return base.GetChildNodes(node);
}
else
{
return new SiteMapNodeCollection();
}
}
private bool NodeIsAncestorOfCurrentNode(System.Web.SiteMapNode node)
{
bool returnvalue = false;
SPSecurity.RunWithElevatedPrivileges(delegate()
{
using (SPSite thisSite = new SPSite(SPContext.Current.Site.ID))
{
using (SPWeb nodeWeb = this.OpenWeb(thisSite, node))
{
using (SPWeb currentWeb = this.OpenNavWeb(thisSite))
{
returnvalue = this.AncestorDescendantWebs(nodeWeb, currentWeb);
}
}
}
});
return returnvalue;
}
private SPWeb OpenWeb(SPSite thisSite, System.Web.SiteMapNode node)
{
// need to use Uri objects, as sometimes the node URL contains a query string
// but calling OpenWeb(...) with a ? in your URL throws an exception
// using Uri.LocalPath removes the Query String
Uri siteUri = new Uri(thisSite.Url);
Uri nodeUri = new Uri(siteUri, node.Url);
return thisSite.OpenWeb(nodeUri.LocalPath.Split(new string[] { "/_" }, StringSplitOptions.RemoveEmptyEntries)[0], false);
}
private SPWeb OpenNavWeb(SPSite thisSite)
{
using (SPWeb currentWeb = thisSite.OpenWeb(this.CurrentWeb.ID))
{
SPWeb web = currentWeb;
PublishingWeb publishingWeb = PublishingWeb.GetPublishingWeb(web);
// Loop all the way up the webs until we find the one which doesn't inherit
// (there gotta be a better way of doing this)
while (publishingWeb.InheritCurrentNavigation &&
!web.ID.Equals(thisSite.RootWeb.ID))
{
web = web.ParentWeb;
publishingWeb = PublishingWeb.GetPublishingWeb(web);
}
return web;
}
}
private bool AncestorDescendantWebs(SPWeb ancestor, SPWeb descendant)
{
// check the URLs to determine if descendant is a subweb or ancestor
// (there gotta be a better way...)
if ((descendant.ServerRelativeUrl + "/").ToUpper().StartsWith(ancestor.ServerRelativeUrl.ToUpper() + "/"))
{
return true;
}
return false;
}
}
}
Возможно, это не лучшее решение... но решение.