"Value does not fall within the expected range" - while accessing publishing portal pages

This issue may occur because of any one of the following causes.

· This issue occurs if there is a problem with the Page Layout, or if the Page Layout is corrupted.

· This issue occurs if the publishing layout URL of a publishing page contains an incorrect top level site URL.

· This issue occurs if a content database was moved or a content deployment job was run.

I have worked with couple of cases in which my customer exported the unghosted site and imported it to a destination site and somehow the publishing layout URL of all publishing pages retained the old site collection URL. Their destination site collection worked perfectly but whenever they enables the output caching on page layouts then it throws an error with the following message.

“Value does not fall within the expected range.”

 

The reason for the page throws an exception when they set the OutPut Cache --> "Page Layouts Can use a different page output cache profile" was when they enable this option what will happen is, the internal API tries to cache the page template, before caching it uses the property value PublishingPage.LayoutUrl to get the PageLayout template. For eg: if their default.aspx page contains a layout page Home.aspx, then that API will tries to get a page template called Home.aspx, by using the wrong URL ,eg :"<https://old-server/_catalogs/masterpage/Home.aspx>" , since they don’t have such URL the API throws the exception from GetFileOrFolderObject() function.

 

The only work-around was - modify the publishing page layout URL <mso:PublishingPageLayout >

We can either open the site in SharePoint designer and edit it or download a copy of that file from the pages library and edit it and upload it to the library again. The painful part was, consider if there are more than 100 pages which were affected by this issue; in that case manual editing will be a tedious job.

Thus I have created a tool to modify all the pages in a web application. Below code snippet will check the collaboration, publishing and News template sites in a top level site and will check for corrupted publishing pages. If any pages are corrupted then it will update the publishing layout URL with the current site collection URL. Also it will leave the pages which has been checked out by somebody.

 

Finally it will generate a report in a text file which contains the information about the files which has been modified and the files which are not been modified because of checking out. Code snippet contains the logic for retain the pages in the old state after modifying it. For eg: consider page1.aspx was on published mode and page2.aspx was on draft mode. Whenever the code modify those pages then it will check the current level of that page and based upon that it will publish the page or keep it in the draft state.

 

This code snippet may help you if you face this kind of issue any time.

using System;

using System.Collections.Generic;

using System.Text;

using Microsoft.SharePoint;

using Microsoft.SharePoint.Publishing;

using System.IO;

namespace PortalLayoutTest

{

    class Program

    {

        static void Main(string[] args)

        {

            TextWriter reportfile = new StreamWriter("LayoutUpdateReport.txt");

            string strURL = Console.ReadLine();

            SPSite oSite = new SPSite(strURL);

            SPWebCollection oWebs = oSite.AllWebs;

          

            Console.WriteLine("Total number of sites :" + oWebs.Count.ToString());

            foreach (SPWeb oWeb in oWebs)

            {

                if (oWeb.WebTemplate == "SPS" || oWeb.WebTemplate =="CMSPUBLISHING" || oWeb.WebTemplate == "SPSNHOME")

                {

                    Console.WriteLine(oWeb.Title + " is a portal member");

                    PublishingWeb pweb = PublishingWeb.GetPublishingWeb(oWeb);

                    PublishingPageCollection pages = pweb.GetPublishingPages();

                    foreach (PublishingPage page in pages)

                    {

                      

                        Console.WriteLine("Iterating all the pages in the pages library");

                        SPFieldUrlValue url = new SPFieldUrlValue((string)page.ListItem[FieldId.PageLayout]);

                        string temp = pweb.Web.Site.ServerRelativeUrl.TrimEnd('/') + url.Url.Substring(url.Url.IndexOf("/_catalogs/"));

                        temp = pweb.Web.Site.MakeFullUrl(temp);

                        string strOldURL = url.Url;

                        if (url.Url == temp)

                            continue;

                           

                       

                        Console.WriteLine("old URL :" + url.Url + " new URL :" + temp);

                        url.Url = temp;

                       

                        if (page.ListItem.File.Level == SPFileLevel.Checkout)

                        {

                            Console.WriteLine("This page has been checked out by "+ page.ListItem.File.CheckedOutBy.LoginName +" please contact him and let him know the udpate");

                            reportfile.WriteLine(page.ListItem.File.Name + " has been checked out by " + page.ListItem.File.CheckedOutBy.LoginName + " and we are skipping this file");

                        }

                        else

                        {

                            Console.WriteLine("checking out the page");

                            if(page.ListItem.File.Level == SPFileLevel.Draft)

                            {

                                page.CheckOut();

                                page.ListItem[FieldId.PageLayout] = url;

                                page.ListItem.UpdateOverwriteVersion();

                                page.ListItem.File.CheckIn("Fixed URL to page layout.", SPCheckinType.MajorCheckIn);

                            }

                            else if (page.ListItem.File.Level == SPFileLevel.Published)

                            {

                                page.CheckOut();

                                page.ListItem[FieldId.PageLayout] = url;

                                page.ListItem.UpdateOverwriteVersion();

                                page.ListItem.File.CheckIn("Checked in - Fixed URL to page layout.", SPCheckinType.MajorCheckIn);

                                page.ListItem.File.Publish("Publihsed - Fixed URL to page layout.");

                            }

                            Console.WriteLine("checked in the page with modification");

                            reportfile.WriteLine("WebSite : " + oWeb.Url + " >> Old Page Layout :" + strOldURL + ">> New Page Layout :" + temp);

                       }

                    }

                }

            }

            reportfile.Close();

            reportfile.Dispose();

            oSite.Dispose();

            Console.WriteLine("operation has been completed successfully !");

            Console.ReadLine();

           

        }

    }

}