Hello to everyone,

in our team we are using the WCM features for Moss 2007 for some customers. It’s a common practice to backup the production environments up to a certain degree and restore them into our development environments. Until now, this approach worked well until we noticed an interesting exception when we tried to change the page properties of a publishing page:

8e2s    Medium      Unknown SPRequest error occurred. More information: 0x80070057 03/24/2010 08:09:26.88     w3wp.exe (0x3AA8)  0x27AC CMS  Publishing  6wyd    Medium      GetFileFromUrl: ArgumentException when attempting get file Url http://productionServerUrl/_catalogs/masterpage/pageTemplateUrl.aspx
Value does not fall within the expected range.

Moss 2007 is not able to open the resource located on that URL. This is clear, we are working on our development environment and Moss tries to access a resource from the productive environment. How should it be possible to get a resource that is not reachable? :) The absolute path stored in the page layouts property ensures that we get one of these beautiful yellow pages that probably every developers encountered once in a SharePoint life.

My basic idea was to solve this issue by changing the page layout reference that is defined in our site collection. Instead of using the absolute path it would be better to store as page layout the relative path. In this way we ensure that the reference also works in our development environment.

My first approach was to try to modify this property directly in the publishing object model of Moss 2007. So I simply tried to reassign the page layout on the development environment. Unfortunately, without success. When you try to access the PageLayout property of the publishing page, you will get exactly the exception you saw before.

Therefore, I changed the approach and went to the more general object model. I used the SPItem class and the Field properties of this class to modify the page layouts settings. The layout settings are stored into a property called “PublishingPageLayout” in your list item. The information is stored in comma-delimited format:

- Address of the Resource, Title of the Resource

The code snipped below uses a publishing page (the variable page):

String[] pageLayouts = page.ListItem.Properties  ["PublishingPageLayout"].ToString().Split(','); 

if (Uri.IsWellFormedUriString(pageLayouts[0], UriKind.Absolute)) 
{ 
  String newPageLayout = Regex.Replace(page.ListItem.Properties["PublishingPageLayout"].ToString(), @"^([a-zA-Z]+:\/\/)?([^\/]*)", String.Empty);

  page.CheckOut();  
  page.ListItem.Properties["PublishingPageLayout"] = newPageLayout; 

  page.ListItem.Update(); 
  page.CheckIn("Publishing PageLayout correction"); 

  if (page.ListItem.ParentList.EnableModeration) 
  { 
    page.ListItem.File.Approve("Publishing PageLayout correction"); 
  } 

} 

At line 1-2 we check if we really have an absolute page layout. If this is true, remove with the regular expression the domain name. In this case we are getting the relative path to the resource (please read the warning afterwards). Then the code checks-out the page and assigns the new value to the "PublishingPageLayout” property (line 5 and 6). After an update and a check-in, we get in business.

this piece of code was only tested with a site collection residing directly in the host. For solutions like http://host/siteCollectionName this solution has to be adapted.

After running this code it was possible for me to change the wrong page layouts address with a relative one. After this change, the development environment worked as expected and the exception above vanished.

 

Hope this helps,

Patrick