Search code examples
sharepointportalsitemapprovider

PortalSiteMapProvider


Everytime I instantiate a PortalSiteMapProvider instance it always defaults to the Root Web Site Collection.

I want to be able to acquire a site map from a different collection from an application page.

Because of this, the context defaults to the root web since this application page resides under _layouts and is not hosted under any site collection.

How do I acquire an instance to a site collection other than the root web from an application page?

Thanks.


Solution

  • You can't read another site collection's hierarchy through a PortalSiteMapProvider. E.g., if you are in Site Collection A, PSMP will only traverse A's tree, not B. You have to be in B to traverse B.

    A workaround I implemented was to write a simple web service that runs in a site collection and takes a path as a parameter. It reads its own PSMP and writes an XML tree from that point in the hierarchy. Calling the web service living in SC-B from code running in SC-A is extremely fast, especially since the PSMP can rip through B's structure so quickly.

    Edit:

    Here are instructions for creating a web service in WSS3/MOSS.

    Here is some totally non-functional code to get you headed in the right direction:

    //method exposed through the web service
    public XmlDocument GetTree(string path)
    {
        PortalSiteMapProvider psmp = PortalSiteMapProvider.GlobalNavSiteMapProvider;
        SiteMapNode node = psmp.FindSiteMapNode(path);
        return BuildXmlFromNode(node);
    }
    
    private XmlNode BuildXmlFromNode(SiteMapNode node)
    {
        XmlDocument xml = new XmlDocument();
        reutrn BuildXmlFromNode(node, xml);
    }
    
    //recurses down the sitemapnode children
    private XmlNode BuildXmlFromNode(SiteMapNode node, XmlNode xml)
    {
        XmlElement element = doc.CreateElement("Node")
        element.SetAttribute("title", node.Title);
        element.SetAttribute("url", node.Url);
    
        xml.AppendChild(element);
    
        foreach(SiteMapNode childNode in node.ChildNodes)
        {
            BuildXmlFromNode(childNode, element);
        }
    
        return xml;
    }
    

    Please note if you don't set a limit on the number of recursions and your site map hierarchy is very deep and/or wide, this could produce a HUGE xml document. Use with caution!