Wednesday, December 4, 2013

Problem with connecting to catalog on site collections imported with SPExport/SPImport API in Sharepoint

Some time ago I wrote about problem with TaxonomyHiddenList on site collections which were created using SPExport/SPImport API (see Fix TaxonomyHiddenList guid after export/import of site collections in Sharepoint). In this post I will tell about one more problem on imported site collection and will show how to fix it.

When you try to connect to catalog on this site collection (Site settings > Manage catalog connections) you will get the following error:

The specified view is invalid

The error comes from CatalogSource.aspx page, more specifically from its codebehind method Microsoft.SharePoint.Publishing.Internal.CodeBehind.CatalogSourcePage.InitializeControlsForAdd() when it tries to populate list of masterpages:

   1:  private void InitializeControlsForAdd()
   2:  {
   3:      ...
   4:      List<DropDownListWithDetails.ItemInfo> masterPagesDataList =
   5:  DesignUtilities.GetMasterPagesDataList(base.Site, false);
   6:      this.rollupMasterPageSelectionControl.DataList = masterPagesDataList.ToArray();
   7:      this.viewerMasterPageSelectionControl.DataList = masterPagesDataList.ToArray();
   8:  }

Method DesignUtilities.GetMasterPagesDataList() calls other method GetHtmlMasterPages() which causes the mentioned error:

   1:  internal static SPListItemCollection GetHtmlMasterPages(SPWeb web)
   2:  {
   3:      SPList catalog = web.GetCatalog(SPListTemplateType.MasterPageCatalog);
   4:      Guid guid = new Guid(web.Properties["HtmlDesignViewNameHtmlMasterPages"]);
   5:      SPView view = catalog.Views[guid];
   6:      SPQuery query = new SPQuery(view);
   7:      query.RowLimit = 0;
   8:      return catalog.GetItems(query);
   9:  }

I.e. after import web property bag value remain the same, while object identities are changed if you don’t use RetainObjectIdentity = true. As you can see from the code above in the HtmlDesignViewNameHtmlMasterPages property in the property bag of the root site of site collection, list view id is stored for /_catalogs/masterpage list. The question is what exactly view should be used? Analysis showed that it is view with title “Html Master Pages”. So in order to fix it you may use the following script:

   1:  param( 
   2:      [string]$url
   3:  )
   5:  function Fix-Html-Master-Pages-View($w)
   6:  {
   7:      $pv = $w.Properties["HtmlDesignViewNameHtmlMasterPages"]
   8:      $c = $w.GetCatalog([Microsoft.SharePoint.SPListTemplateType]::MasterPageCatalog);
   9:      $id = $c.Views["Html Master Pages"].ID
  10:      Write-Host "Property bag value: '$pv', view id: '$id'"
  11:      if ($pv.ToString().ToLower() -ne $id.ToString().ToLower())
  12:      {
  13:          Write-Host "Property bag value differs from view id. It will be fixed" -foregroundcolor yellow
  14:          $w.Properties["HtmlDesignViewNameHtmlMasterPages"] = $id
  15:          $w.Properties.Update()
  16:          Write-Host "Property bag value was successfully fixed" -foregroundcolor green
  17:      }
  18:      else
  19:      {
  20:          Write-Host "Property bag value equals to view id. Nothing should be fixed" -foregroundcolor green
  21:      }
  22:  }
  24:  if (-not $url)
  25:  {
  26:      Write-Host "Specify web app url in url parameter" -foregroundcolor red
  27:      return
  28:  }
  30:  $wa = Get-SPWebApplication $url
  31:  foreach ($s in $wa.Sites)
  32:  {
  33:      Write-Host "Checking $s.Url..."
  34:      Fix-Html-Master-Pages-View $s.RootWeb
  35:  }

It will enumerate through all site collections and will fix the property bag value to the correct view id which corresponds to the current site collection.

No comments:

Post a Comment