开发者

NullReferenceException thrown in "GetAvailablePageLayouts"

I ran into this error recently when trying to get all the page layouts in a publishing site (Microsoft.SharePoint.Publishing.PublishingWeb) from a custom layouts page in a subsite. The code worked on a VM server using a site created from the Enterprise Wiki site template. But when running on the development server the code encountered various exceptions.

Attempting to get around the error, I coded the class three different ways. All three worked in the VM, but all three threw an exception when used in the development server. Example:

private PageLayout FindPageLayout(PublishingWeb pubWeb, string examplePage)
        {
            /* The error occurs in this method */
            if (pubWeb == null)
                throw new ArgumentException("The pubWeb argument cannot be null.");
            PublishingSite pubSiteCollection = new PublishingSite(pubWeb.Web.Site);
            string pageLayoutName = "EnterpriseWiki.aspx"; // for testing purposes
            PageLayout layout = null;

            /* Option 1: Get page layout from collection with name of lay开发者_运维问答out used as index
             * Result: System.NullReferenceException from GetPageLayouts()
             */

            layout = pubSiteCollection.PageLayouts["/_catalogs/masterpage/"+pageLayoutName];

            /* Option 2: Bring up an existing publishing page, then find the layout of that page using the Layout property
             * Result: Incorrect function COM exception
             */

            SPListItem listItem = pubWeb.Web.GetListItem(examplePage);
            PublishingPage item = PublishingPage.GetPublishingPage(listItem);
            layout = item.Layout;

            /* Option 3: Call "GetPageLayouts" and iterate through the results looking for a layout of a particular name
             * Result: System.NullReferenceException thrown from Microsoft.SharePoint.Publishing.PublishingSite.GetPageLayouts()
             */

            PageLayoutCollection layouts = pubSiteCollection.GetPageLayouts(true);
            for(int i = 0; i < layouts.Count; i++)
            {
                // String Comparison based on the Page Layout Name
                if (layouts[i].Name.Equals(pageLayoutName, StringComparison.InvariantCultureIgnoreCase))
                    layout = layouts[i];
            }

            return layout;
        }


Here was the solution I found after a week or so:

Make sure that when you are getting your "PublishingWeb" object by calling that PublishingWeb.GetPublishingWeb(SPWeb) method that you are passing into it an SPWeb objec that has been fully retrieved. More specifically, I would make sure to call SPSite.OpenWeb on any website, as follows:

 using (SPSite site = new SPSite(folder.ParentWeb.Url))
            {
                SPWeb web = site.OpenWeb();
                PublishingWeb pubWeb = PublishingWeb.GetPublishingWeb(web);
                /* work with PublishingWeb here ... */
                web.Close();
             }

Once I made this simple change, all the errors mentioned in the question were cleared up, no matter in what context I called "GetPageLayouts" or "GetAvailablePageLayouts". The method documentation says this, and it really means it:

Use this method in order to access PublishingWeb behavior for an instance of a SPWeb class that has already been retrieved.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜