In uno dei nostri ultimi progetti, avevamo la necessità di inserire delle web part all'interno di una pagina SharePoint 2013, all'attivazione di una feature. Una delle web part in questione era la XsltViewWebPart di cui abbiamo parlato in uno dei precedenti post.
La pagina invece era la home page di un sito di Publishing, quindi con i meccanismi di checkout e pubblicazione obbligatori prima di fare qualsiasi modifica al contenuto o al relativo layout.

Questo il nostro codice per aggiungere la web part all'interno della pagina:

SPFile homePageFile = web.GetFile("Pages/Home.aspx");
SPLimitedWebPartManager wpManager = web.GetLimitedWebPartManager(homePageFile.ServerRelativeUrl, PersonalizationScope.Shared);

if (homePageFile.CheckOutStatus == SPFile.SPCheckOutStatus.None)
    homePageFile.CheckOut();

SPList list = web.Lists["MY LIST NAME"];
XsltListViewWebPart webpart = CreateXsltViewWebPart(list);
wpManager.AddWebPart(webpart, "TopWebPartZone", 0);

homePageFile.CheckIn(string.Empty, SPCheckinType.MajorCheckIn);
homePageFile.Publish(string.Empty);

Eseguendo il codice sopra, ci ritornava il seguente errore durante l'esecuzione della chiamata al metodo AddWebPart:

"File is not checked out."

Eppure la chiamata al metodo CheckOut era presente..

Dov'era il problema?
Il problema era nel punto in cui si recuperava l'istanza della classe SPLimitedWebPartManager. Cercando infatti di recuperare tale istanza prima della chiamata al metodo CheckOut, la classe aveva in memoria una versione della pagina che non era ancora in check-out, quindi non modificabile.
Per un corretto funzionamento delle sue funzionalità, tale istanza deve essere recuperata DOPO aver fatto checkout sulla pagina.
Ecco quindi il codice funzionante.

SPFile homePageFile = web.GetFile("Pages/Home.aspx");
if (homePageFile.CheckOutStatus == SPFile.SPCheckOutStatus.None)
    homePageFile.CheckOut();

SPLimitedWebPartManager wpManager = web.GetLimitedWebPartManager(homePageFile.ServerRelativeUrl, PersonalizationScope.Shared);

SPList list = web.Lists["MY LIST NAME"];
XsltListViewWebPart webpart = CreateXsltViewWebPart(list);
wpManager.AddWebPart(webpart, "TopWebPartZone", 0);

homePageFile.CheckIn(string.Empty, SPCheckinType.MajorCheckIn);
homePageFile.Publish(string.Empty);

Spero vi possa essere d'aiuto.