Got stuck on this one for a long time, more than an hour
Microsoft.SharePoint.WebPartPages.WebPartPageUserException: The file is not checked out. You must first check out this document before making changes. at Microsoft.SharePoint.WebPartPages.SPWebPartManager.SaveChangesCore(SPLayoutProperties layoutProperties, Boolean httpGet, Boolean saveCompressed, Boolean skipRightsCheck, Guid& newTypeId, Byte[]& newAllUsersProperties, Byte[]& newPerUserProperties, String[]& newLinks) at Microsoft.SharePoint.WebPartPages.SPWebPartManager.SaveChangesCore(SPLayoutProperties layoutProperties, Boolean httpGet, Boolean saveCompressed, Boolean skipRightsCheck) at Microsoft.SharePoint.WebPartPages.SPWebPartManager.SaveChangesInternal(SPLayoutProperties layoutProperties, Boolean skipRightsCheck) at Microsoft.SharePoint.WebPartPages.SPWebPartManager.SaveChanges(Guid storageKey) at Microsoft.SharePoint.WebPartPages.SPLimitedWebPartManager.SaveChanges(WebPart webPart)
I was using the following code to update a webpart
gWeb publishingWeb = PublishingWeb.GetPublishingWeb(webSite);
SPListItem item = publishingWeb.PagesList.GetItemByFileName(pageName);
if (item != null)
{
SPLimitedWebPartManager webPartManager = item.File.GetLimitedWebPartManager(PersonalizationScope.Shared);
PublishingPage publishingPage = PublishingPage.GetPublishingPage(item);
try
{
if (item.File.CheckOutStatus == SPFile.SPCheckOutStatus.None)
{
publishingPage.CheckOut();
}
else
{
item.File.UndoCheckOut();
publishingPage.CheckOut();
}
WebPart webpart = webPartManger.WebParts[0];
// Do something with the webpart
webPartManger.SaveChanges(webpart); // Now the exception is thrown
publishingPage.Update();
publishingPage.CheckIn(updateComment);
if (publishingWeb.PagesList.EnableModeration)
{
item.File.Publish(updateComment);
item.File.Approve(updateComment);
}
}
finally
{
if (webPartManager != null)
{
webPartManager.Dispose();
}
}
}
A quick google reveals quite a lot of other people stumped with this problem. Why is it saying the file is not checked out, the lines above it make sure it’s always checked out to the user running the code. Turns out it’s quite a simple fix. Don’t instantiate the SPLimitedWebPartManager until your done making sure the page is checked out!
Working code
gWeb publishingWeb = PublishingWeb.GetPublishingWeb(webSite);
SPListItem item = publishingWeb.PagesList.GetItemByFileName(pageName);
if (item != null)
{
SPLimitedWebPartManager webPartManager = null;
PublishingPage publishingPage = PublishingPage.GetPublishingPage(item);
try
{
if (item.File.CheckOutStatus == SPFile.SPCheckOutStatus.None)
{
publishingPage.CheckOut();
}
else
{
item.File.UndoCheckOut();
publishingPage.CheckOut();
}
// Now we're certain the page is checked out, grab the web part manager.
webPartManger = item.File.GetLimitedWebPartManager(PersonalizationScope.Shared);
WebPart webpart = webPartManger.WebParts[0];
// Do something with the webpart
webPartManger.SaveChanges(webpart); // Now the exception is thrown
publishingPage.Update();
publishingPage.CheckIn(updateComment);
if (publishingWeb.PagesList.EnableModeration)
{
item.File.Publish(updateComment);
item.File.Approve(updateComment);
}
}
finally
{
if (webPartManager != null)
{
webPartManager.Dispose();
}
}
}
Notice that we assign the value of the web part manager after we make sure the page is checked out. Hopefully this saves someone a couple of missing hours i’ll never get back 🙂