Unable to get the PageLayout for a PublishingWeb using CSOM. Error “The object is not associated with an object identity”
-
08-02-2021 - |
Question
I am working on a console application which uses CSOM to integrate with SharePoint online. and i want to create a publishing page, so i wrote this code, to get the PageLayout and create a new Publishing page, based on the values of other page:-
File tempWikiPage = context.Site.RootWeb.GetFileByServerRelativeUrl(scurl4 + tempItemTitle + ".aspx");
context.Load(tempWikiPage,items => items.ListItemAllFields);
context.ExecuteQuery();
List publishingLayouts = context.Site.RootWeb.Lists.GetByTitle("Master Page Gallery");
CamlQuery camlQuery4 = new CamlQuery();
camlQuery4.ViewXml = "<View><Query><Where><Eq><FieldRef Name='Title'/>" +
"<Value Type='String'>Basic Page</Value></Eq></Where></Query><RowLimit>1</RowLimit></View>";
ListItemCollection allItems = publishingLayouts.GetItems(camlQuery4);
context.Load(allItems,
items => items.Include(
item => item["Title"]
));
context.ExecuteQuery();
ListItem layout = allItems.FirstOrDefault();
PublishingPageInformation publishingPageInfo = new PublishingPageInformation();
publishingPageInfo.PageLayoutListItem = layout;
PublishingPage pPage = pWeb.AddPublishingPage(publishingPageInfo);
ListItem newpage = pPage.ListItem;
newpage["Title"] = newPageName;
newpage["PublishingPageContent"] = r;
newpage["Standard"] = tempWikiPage.ListItemAllFields["Standard"];
now i am facing these 2 issues:-
the
layout
will be null.once the code reaches
newpage["Standard"] = tempWikiPage.ListItemAllFields["Standard"];
i got this exception:-
The object is not associated with an object identity or the object identity is invalid.
Microsoft.SharePoint.Client.ClientRequestException was caught
HResult=-2146233088 Message=The object is not associated with an object identity or the object identity is invalid.
Source=Microsoft.SharePoint.Client.Runtime StackTrace: at Microsoft.SharePoint.Client.DataConvert.WriteValueToXmlElement(XmlWriter writer, Object objValue, SerializationContext serializationContext) at Microsoft.SharePoint.Client.ClientActionInvokeMethod.WriteToXmlPrivate(XmlWriter writer, SerializationContext serializationContext) at Microsoft.SharePoint.Client.ClientActionInvokeMethod..ctor(ClientObject obj, String methodName, Object[] parameters) at Microsoft.SharePoint.Client.ListItem.SetFieldValue(String fieldName, Object value) at Microsoft.SharePoint.Client.ListItem.set_Item(String fieldName, Object value)
Solution
I suggest you check if the exists page ServerRelativeUrl is right, and make sure the "Standard" field exists in the Pages library.
The following code for your reference.
string siteUrl = "https://tenant.sharepoint.com/sites/team";
string userName = "test@tenant.onmicrosoft.com";
string password = "xxx";
string newPageName = "new1227.aspx";
var securePassword = new SecureString();
foreach (char c in password.ToCharArray()) securePassword.AppendChar(c);
var credential = new SharePointOnlineCredentials(userName, securePassword);
using (ClientContext context = new ClientContext(siteUrl))
{
context.Credentials = credential;
Web webSite = context.Web;
context.Load(webSite);
PublishingWeb web = PublishingWeb.GetPublishingWeb(context, webSite);
context.Load(web);
if (web != null)
{
// Get Pages Library
List pages = context.Site.RootWeb.Lists.GetByTitle("Pages");
ListItemCollection existingPages = pages.GetItems(CamlQuery.CreateAllItemsQuery());
context.Load(existingPages, items => items.Include(item => item.DisplayName).Where(obj => obj.DisplayName == newPageName));
context.ExecuteQuery();
// Check if page already exists
if (existingPages != null && existingPages.Count > 0)
{
// Page already exists
}
else
{
// Get Publishing Page Layouts
List publishingLayouts = context.Site.RootWeb.Lists.GetByTitle("Master Page Gallery");
CamlQuery camlQuery = new CamlQuery();
camlQuery.ViewXml = "<View><Query><Where><Eq><FieldRef Name='Title'/>" +
"<Value Type='Text'>Basic Page</Value></Eq></Where></Query><RowLimit>1</RowLimit></View>";
ListItemCollection allItems = publishingLayouts.GetItems(camlQuery);
context.Load(allItems);
context.ExecuteQuery();
Microsoft.SharePoint.Client.ListItem layout = allItems.FirstOrDefault();
Microsoft.SharePoint.Client.File tempWikiPage = context.Site.RootWeb.GetFileByServerRelativeUrl("/sites/team/Pages/EWikiPage.aspx");
context.Load(tempWikiPage, items => items.ListItemAllFields);
context.ExecuteQuery();
TaxonomyFieldValueCollection taxFieldValueColl = tempWikiPage.ListItemAllFields["Standard"] as TaxonomyFieldValueCollection;
// Loop through all the taxonomy field values
string termValueString = string.Empty;
foreach (TaxonomyFieldValue tv in taxFieldValueColl)
{
// Display the taxonomy field value
termValueString += tv.WssId + ";#" + tv.Label + "|" + tv.TermGuid + ";#";
}
termValueString = termValueString.TrimEnd(";#".ToCharArray());
// Create a publishing page
PublishingPageInformation publishingPageInfo = new PublishingPageInformation();
publishingPageInfo.Name = newPageName;
publishingPageInfo.PageLayoutListItem = layout;
PublishingPage pPage = web.AddPublishingPage(publishingPageInfo);
Microsoft.SharePoint.Client.ListItem newpage = pPage.ListItem;
newpage["Title"] = newPageName;
newpage["PublishingPageContent"] = "Test";
newpage["Standard"] = termValueString;
newpage.Update();
newpage.File.CheckIn(string.Empty, CheckinType.MajorCheckIn);
newpage.File.Publish(string.Empty);
newpage.File.Approve(string.Empty);
context.Load(newpage);
context.ExecuteQuery();
}
}
}
OTHER TIPS
There is an error in your CAML query. Try using Text
instead of String
.
So this:
camlQuery4.ViewXml = "<View><Query><Where><Eq><FieldRef Name='Title'/>" +
"<Value Type='String'>Basic Page</Value></Eq></Where></Query><RowLimit>1</RowLimit></View>";
Should become:
camlQuery4.ViewXml = "<View><Query><Where><Eq><FieldRef Name='Title'/>" +
"<Value Type='Text'>Basic Page</Value></Eq></Where></Query><RowLimit>1</RowLimit></View>";
I'm not sure for the second error, but try checking if tempWikiPage.ListItemAllFields["Standard"]
exists before setting it to the newPage["Standard"]
.