Recently I received a questions from a customer who was looking for a way to access content of historic revisions of a publishing pages using SharePoint client side object model (CSOM).
Using server side object model this can be achieved using code similar to the following (here we access historic versions of the Title and the PublishingPageContent field):
SPSite site = new SPSite("http://contoso:3200"); SPWeb web = site.OpenWeb(); SPList list = web.Lists["Pages"]; SPListItem item = list.Items[2]; Console.WriteLine("---------------------------"); Console.WriteLine(item["PublishingPageContent"]); foreach (SPListItemVersion version in item.Versions) { Console.WriteLine(version.VersionLabel); Console.WriteLine(version["Title"]); Console.WriteLine(version["PublishingPageContent"]); }
The equivalent CSOM code would look like this:
// this code works only with SharePoint Online and SharePoint Server 2019 using (ClientContext ctx = new ClientContext("http://contoso:3200")) { ctx.Load(ctx.Web); ctx.ExecuteQuery(); // Retrieve list by title List list = ctx.Web.Lists.GetByTitle("Pages"); ctx.Load(list, L => L.Id); // Retrieve all items from above list ListItemCollection listItems = list.GetItems(CamlQuery.CreateAllItemsQuery()); ctx.Load(listItems, IC => IC.Include(I => I.Id, I => I.DisplayName)); ctx.ExecuteQuery(); // select the ListItem we are interested in ListItem item = listItems[2]; Console.WriteLine(item.DisplayName); ctx.Load(item, li => li.Versions); ctx.ExecuteQuery(); Console.WriteLine(item.Versions.Count); foreach (ListItemVersion version in item.Versions) { Console.WriteLine(version.VersionLabel); Console.WriteLine(version["Title"]); Console.WriteLine(version["PublishingPageContent"]); } }
The problem with the CSOM code above is that the above listed CSOM API calls to retrieve historic versions of List Items is only available in SharePoint Online and SharePoint Server 2019. So this method cannot be used with previous versions of SharePoint.
After a little bit of research I identified the following method which utilizes the Lists.asmx web service which can be also be used with all OnPremise versions of SharePoint (this method cannot be used with SharePoint Online):
using (ClientContext ctx = new ClientContext("http://contoso:3200")) { ctx.Load(ctx.Web); ctx.ExecuteQuery(); // Retrieve list by title List list = ctx.Web.Lists.GetByTitle("Pages"); ctx.Load(list, L => L.Id); // Retrieve all items from above list ListItemCollection listItems = list.GetItems(CamlQuery.CreateAllItemsQuery()); ctx.Load(listItems, IC => IC.Include(I => I.Id, I => I.DisplayName)); ctx.ExecuteQuery(); // select the ListItem we are interested in ListItem item = listItems[2]; Console.WriteLine(item.DisplayName); // Use Lists.asmx web service to retrieve historic version information ListService.Lists listService = new ListService.Lists(); listService.Url = ctx.Url + "/_vti_bin/Lists.asmx"; listService.Credentials = CredentialCache.DefaultCredentials; // Retrieve all versions for selected fields from list item using web service XmlNode nodeUIVersions = listService.GetVersionCollection( list.Id.ToString(), item.Id.ToString(), "_UIVersionString"); XmlNode nodePageContent = listService.GetVersionCollection(list.Id.ToString(), item.Id.ToString(), "PublishingPageContent"); XmlNode nodeTitle = listService.GetVersionCollection(list.Id.ToString(), item.Id.ToString(), "Title"); // the number of versions for each field should be the same so we can retrieve them // using a single loop for (int i = 0; i < nodeUIVersions.ChildNodes.Count; i++) { Console.WriteLine("-------------------------------------"); Console.WriteLine("Version: " + nodeUIVersions.ChildNodes[i].Attributes["_UIVersionString"].Value); Console.WriteLine("List Item Title: " + nodeTitle.ChildNodes[i].Attributes["Title"].Value); Console.WriteLine("PublishingPageContent: " + nodePageContent.ChildNodes[i].Attributes["PublishingPageContent"].Value); } }
To use the code above you need to create a C# Visual studio project and add a web reference to the _vti_bin/Lists.asmx web service (References / Add Service Reference… / Advanced… / Add Web Reference…).
In the following Dialog you need to name the WebReference “ListService”. Alternatively you can change all references to ListService in the code above to the name you selected in this dialog.