3

I have a farm where we create site collections programatically coming from SQL information via timer job.

We have a HOME site collection at http://ourcompany/, the top navigation bar ALL should point to the HOME site collection pages for all other site collections.

We want to change this from absolute to relative because when we move from PROD to QA or TEST for debugging, then we also get the absolute URLS which is a big deal, people that goes to QA can end up in PRODUCTION.

However it seems that its not possible? see my code below

  private static SPNavigationNode AddXXXDMSTopNavigationNode(PublishingWeb pubWeb, String nodeLinkFileName, String nodeTitle, SPNavigationNode rootNode = null)
        {
            try
            {
                PublishingPage p = null;
                String dmsPortalUrl = HelperFunctions.GetDMSApplicationSetting(Constants.ApplicationSettings.Keys.DMSPortalUrl);

                string webapplicationUrl = pubWeb.Web.Site.WebApplication.Sites.First<SPSite>().Url;

                if (!String.IsNullOrEmpty(dmsPortalUrl))
                {
                    using (SPSite portalSite = new SPSite(dmsPortalUrl))
                    {
                        PublishingWeb portalWeb = PublishingWeb.GetPublishingWeb(portalSite.RootWeb);

                        LoggingService.LogInfo(LoggingCategory.Feature, String.Format("Checking if the filename {0} can be found inside the Publishing Pages Library on the Portal site: {1}", nodeLinkFileName, portalSite.Url));
                        p = portalWeb.GetPublishingPages().ToList().Find(x => x.Name.Equals(nodeLinkFileName, StringComparison.InvariantCultureIgnoreCase));

                        if (p != null)
                        {
                            LoggingService.LogInfo(LoggingCategory.Feature, String.Format("File found at location: {0} ", p.Uri.ToString()));
                            if (rootNode == null)
                            {
                                webapplicationUrl = "/../..";
                                LoggingService.LogInfo(LoggingCategory.Feature, String.Format("Creating heading navigation: {0} with link: {1}", nodeTitle, p.Uri.ToString()));
                                return pubWeb.Navigation.GlobalNavigationNodes.AddAsLast(new SPNavigationNode(nodeTitle, String.Format("{0}/{1}", webapplicationUrl, p.Uri.AbsolutePath)));
                            }
                            else
                            {
                                webapplicationUrl = "/../..";
                                LoggingService.LogInfo(LoggingCategory.Feature, String.Format("Creating child navigation node: {0} with link: {1}", nodeTitle, p.Uri.ToString()));
                                rootNode.Children.AddAsLast(new SPNavigationNode(nodeTitle, String.Format("{0}/{1}", webapplicationUrl, p.Uri.AbsolutePath)));
                                return null;
                            }
                        }
                        else
                        {
                            LoggingService.LogWarning(LoggingCategory.Feature, String.Format("The filename {0} cannot be found inside the Publishing Pages Library, therefore we cannot create a navigation link.", nodeLinkFileName));
                        }
                    }
                }
                else
                {
                    LoggingService.LogWarning(LoggingCategory.Feature, "DMS portal URL is null or empty. Check applicationSettings.");
                }
            }
            catch (Exception ex)
            {
                LoggingService.LogError(LoggingCategory.Feature, ex);
            }

            return null;
        }

I get this exception:

Cannot open "/sites/XYZ/../..///Pages/myclients.aspx": no such file or folder.

Is there a way to overcome this?

  • can you try it as below and check ? webapplicationUrl = "/../.."; LoggingService.LogInfo(LoggingCategory.Feature, String.Format("Creating heading navigation: {0} with link: {1}", nodeTitle, p.Uri.ToString())); SPNavigationNode node = new SPNavigationNode(nodeTitle, String.Format("{0}/{1}", webapplicationUrl, p.Uri.AbsolutePath), false); return pubWeb.Navigation.GlobalNavigationNodes.AddAsLast(node); – Gautam Sheth Mar 23 '18 at 16:17
  • 1
    same error, it doesnt work, any other idea? – Luis Valencia Mar 26 '18 at 7:04
  • can you try it as webapplicationUrl = "/../.."; LoggingService.LogInfo(LoggingCategory.Feature, String.Format("Creating heading navigation: {0} with link: {1}", nodeTitle, p.Uri.ToString())); SPNavigationNode node = new SPNavigationNode(nodeTitle, String.Format("{0}/{1}", webapplicationUrl, p.Uri.AbsolutePath), true); return pubWeb.Navigation.GlobalNavigationNodes.AddAsLast(node); and check ? I have set the SPNavigationNode parameter, IsExternal to true. I guess this will not validate whether the link exists in sharepoint. – Gautam Sheth Mar 26 '18 at 12:35
  • You have an SPSite object, why can't you store the url in a variable? – Derek Gusoff Mar 26 '18 at 13:39
  • I dont understand the last comment – Luis Valencia Mar 26 '18 at 13:58
2

The issue you are facing is because you are using the default constructor of SPNavigationNode object which has 2 arguments.

When you want to use relative url in global/quick launch navigation, you need to use the constructor with 3 arguments. The 3rd argument being IsExternal like - (new SPNavigationNode(title,url,isExternal). You should set the value of IsExternal to true. By default, that value is false.

When you set it to true, it tells SharePoint that the URL is an External URL (and by External .. I mean "not in the current web").

Even if the URL is a relative URL to the same site collection, you still have to set this value to true! Its not entirely obvious.

So, modify your code as below:

LoggingService.LogInfo(LoggingCategory.Feature, String.Format("File found at location: {0} ", p.Uri.ToString()));
if (rootNode == null)
{
    webapplicationUrl = "/../..";
    LoggingService.LogInfo(LoggingCategory.Feature, String.Format("Creating heading navigation: {0} with link: {1}", nodeTitle, p.Uri.ToString()));
    return pubWeb.Navigation.GlobalNavigationNodes.AddAsLast(new SPNavigationNode(nodeTitle, String.Format("{0}/{1}", webapplicationUrl, p.Uri.AbsolutePath), true));
}
else
{
    webapplicationUrl = "/../..";
    LoggingService.LogInfo(LoggingCategory.Feature, String.Format("Creating child navigation node: {0} with link: {1}", nodeTitle, p.Uri.ToString()));
    rootNode.Children.AddAsLast(new SPNavigationNode(nodeTitle, String.Format("{0}/{1}", webapplicationUrl, p.Uri.AbsolutePath), true));
    return null;
}

Or something like :

LoggingService.LogInfo(LoggingCategory.Feature, String.Format("File found at location: {0} ", p.Uri.ToString()));
if (rootNode == null)
{
    webapplicationUrl = "/../..";
    LoggingService.LogInfo(LoggingCategory.Feature, String.Format("Creating heading navigation: {0} with link: {1}", nodeTitle, p.Uri.ToString()));

    SPNavigationNode node = new SPNavigationNode(nodeTitle, String.Format("{0}/{1}", webapplicationUrl, p.Uri.AbsolutePath), true); 
    return pubWeb.Navigation.GlobalNavigationNodes.AddAsLast(node);     

}
else
{
    webapplicationUrl = "/../..";
    LoggingService.LogInfo(LoggingCategory.Feature, String.Format("Creating child navigation node: {0} with link: {1}", nodeTitle, p.Uri.ToString()));

    SPNavigationNode node = new SPNavigationNode(nodeTitle, String.Format("{0}/{1}", webapplicationUrl, p.Uri.AbsolutePath), true); 

    rootNode.Children.AddAsLast(new SPNavigationNode(node);
    return null;
}

Reference - SPNavigationNode

Creating “External” URLs in the Quick Launch menu

| improve this answer | |
  • any luck with this @luis ? – Gautam Sheth Mar 29 '18 at 11:31

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.