Identify The Modern Pages And Copy Them To Another Site Collection

In this blog, I am going to perform two actions -

  1. Identify if a page is a modern page or not.
  2. Migrate or copy that modern page (including its content) to another site collection or site (destination location)

I am going to accomplish these tasks by using CSOM (Client Object Model). After identifying the modern page, I will copy the modern page into another site collection (destination location) and then, will migrate all the page contents of this modern page (including web parts and other properties of source modern page) to a destination web using CSOM.

We are using a console application to achieve the above functionality using CSOM. In the below-mentioned code logic, we will get all pages from ‘Site Pages’ page library which is present in the source web and looping each page to check if that is a modern page or not.

If the page is found to be a modern page, then we are migrating that page to the destination web ‘Site Pages’ library.

Please have a look at the below code. The code is self-explanatory because of the comments.
  1. using System;  
  2. using System.Net;  
  3. using System.Security;  
  4. using System.Text.RegularExpressions;  
  5. using Microsoft.SharePoint.Client;  
  6. namespace ConsoleApp1 {  
  7.     class Program {  
  8.         static void Main(string[] args) {  
  9.             ClientContext sourceContext = null;  
  10.             List sourceList = null;  
  11.             ListItemCollection srcItemCollection = null;  
  12.             ListItem sourceItem = null;  
  13.             string userName = string.Empty;  
  14.             string password = string.Empty;  
  15.             SecureString srcSiteSecurePassword = new SecureString();  
  16.             SharePointOnlineCredentials sourceOnlineCredentials = null;  
  17.             try {  
  18.                 using(sourceContext = new ClientContext("http://sourcesiteurl")) {  
  19.                     userName = "TestUser";  
  20.                     password = "Password";  
  21.                     if (!string.IsNullOrEmpty(password)) {  
  22.                         foreach(char c in password.ToCharArray())  
  23.                         srcSiteSecurePassword.AppendChar(c);  
  24.                     }  
  25.                     // Setting credential for the above site  
  26.                     sourceOnlineCredentials = new SharePointOnlineCredentials(userName, srcSiteSecurePassword);  
  27.                     sourceContext.Credentials = sourceOnlineCredentials;  
  28.                     sourceContext.Load(sourceContext.Web);  
  29.                     sourceContext.ExecuteQuery();  
  30.                     // Getting source list by Title  
  31.                     sourceList = sourceContext.Web.Lists.GetByTitle("Site Pages");  
  32.                     // Getting all items from source list using caml query  
  33.                     srcItemCollection = sourceList.GetItems(CamlQuery.CreateAllItemsQuery());  
  34.                     //Loading source items  
  35.                     sourceContext.Load(srcItemCollection, IC => IC.Include(I => I.Id, I => I.DisplayName));  
  36.                     sourceContext.ExecuteQuery();  
  37.                     if (srcItemCollection != null && srcItemCollection.Count > 0) {  
  38.                         for (int iCount = 0; iCount < srcItemCollection.Count; iCount++) {  
  39.                             try {  
  40.                                 sourceItem = srcItemCollection[iCount];  
  41.                                 //Checking if current page is modern page or not  
  42.                                 if (IsModernPage(sourceContext, sourceItem)) {  
  43.                                     // Migrate modern page to anothen site  
  44.                                     MigrateModernPageToAnotherWeb(sourceContext, sourceItem);  
  45.                                 }  
  46.                             } catch (Exception ex) {}  
  47.                         }  
  48.                     }  
  49.                 }  
  50.             } catch (Exception ex) {}  
  51.         }  
  52.         // Checking if the selected page is a modern page or not  
  53.         private static bool IsModernPage(ClientContext sourceContext, ListItem sourceItem) {  
  54.             bool isModernPage = false;  
  55.             try {  
  56.                 sourceContext.Load(sourceItem, srcItm => srcItm["CanvasContent1"], srcItm => srcItm["LayoutWebpartsContent"]);  
  57.                 sourceContext.ExecuteQuery();  
  58.                 // Check if modern page  
  59.                 if (!string.IsNullOrEmpty(sourceItem["CanvasContent1"].ToString()) || !string.IsNullOrEmpty(sourceItem["LayoutWebpartsContent"].ToString())) isModernPage = true;  
  60.             } catch {  
  61.                 isModernPage = false;  
  62.             }  
  63.             return isModernPage;  
  64.         }  
  65.         // Migrating the modern page from source site to destination site  
  66.         private static void MigrateModernPageToAnotherWeb(ClientContext sourceContext, ListItem sourceItem) {  
  67.             ClientContext destSiteContext = null;  
  68.             List destList = null;  
  69.             ListItem destItem = null;  
  70.             string userName = string.Empty;  
  71.             string password = string.Empty;  
  72.             SecureString destSiteSecurePassword = new SecureString();  
  73.             SharePointOnlineCredentials destOnlineCredentials = null;  
  74.             string canvasContent = string.Empty;  
  75.             string metaInfo = string.Empty;  
  76.             string layoutWebpartsContent = string.Empty;  
  77.             try {  
  78.                 using(destSiteContext = new ClientContext("http://destinationsiteurl")) {  
  79.                     userName = "TestUser";  
  80.                     password = "Password";  
  81.                     if (!string.IsNullOrEmpty(password)) {  
  82.                         foreach(char c in password.ToCharArray())  
  83.                         destSiteSecurePassword.AppendChar(c);  
  84.                     }  
  85.                     // Setting credential for the above site  
  86.                     destOnlineCredentials = new SharePointOnlineCredentials(userName, destSiteSecurePassword);  
  87.                     destSiteContext.Credentials = destOnlineCredentials;  
  88.                     destSiteContext.Load(destSiteContext.Web);  
  89.                     destSiteContext.ExecuteQuery();  
  90.                     // Getting destination list by Title  
  91.                     destList = destSiteContext.Web.Lists.GetByTitle("Site Pages");  
  92.                     // Loading destination list  
  93.                     destSiteContext.Load(destList, L => L.RootFolder.ServerRelativeUrl);  
  94.                     destSiteContext.ExecuteQuery();  
  95.                     // Creating modern page in destination site  
  96.                     destItem = destList.RootFolder.Files.AddTemplateFile(destList.RootFolder.ServerRelativeUrl.TrimEnd('/') + "/" + sourceItem.DisplayName + ".aspx", TemplateFileType.ClientSidePage).ListItemAllFields;  
  97.                     destSiteContext.Load(destItem);  
  98.                     destSiteContext.ExecuteQuery();  
  99.                     // Loading source item properties  
  100.                     sourceContext.Load(sourceItem, i => i.ContentType.Id, i => i["CanvasContent1"], i => i["MetaInfo"], i => i["LayoutWebpartsContent"]);  
  101.                     sourceContext.ExecuteQuery();  
  102.                     try {  
  103.                         destItem["ContentTypeId"] = sourceItem.ContentType.Id.ToString();  
  104.                         canvasContent = sourceItem["CanvasContent1"].ToString();  
  105.                         // Replacing source Web ID with destination Web ID  
  106.                         if (!string.IsNullOrEmpty(canvasContent) && canvasContent.Length > 0 && canvasContent.ToLower().Contains(sourceContext.Web.Id.ToString().ToLower())) canvasContent = Regex.Replace(canvasContent, sourceContext.Web.Id.ToString(), destSiteContext.Web.Id.ToString(), RegexOptions.IgnoreCase);  
  107.                     } catch (Exception ex) {}  
  108.                     try {  
  109.                         metaInfo = sourceItem["MetaInfo"].ToString();  
  110.                         // Replacing source Web ID with destination Web ID  
  111.                         if (!string.IsNullOrEmpty(metaInfo) && metaInfo.Length > 0 && metaInfo.ToLower().Contains(sourceContext.Web.Id.ToString().ToLower())) metaInfo = Regex.Replace(metaInfo, sourceContext.Web.Id.ToString(), destSiteContext.Web.Id.ToString(), RegexOptions.IgnoreCase);  
  112.                     } catch (Exception ex) {}  
  113.                     try {  
  114.                         layoutWebpartsContent = sourceItem["LayoutWebpartsContent"].ToString();  
  115.                         // Replacing source Web ID with destination Web ID  
  116.                         if (!string.IsNullOrEmpty(layoutWebpartsContent) && layoutWebpartsContent.Length > 0 && layoutWebpartsContent.ToLower().Contains(sourceContext.Web.Id.ToString().ToLower())) layoutWebpartsContent = Regex.Replace(layoutWebpartsContent, sourceContext.Web.Id.ToString(), destSiteContext.Web.Id.ToString(), RegexOptions.IgnoreCase);  
  117.                     } catch (Exception ex) {}  
  118.                     // Setting source page canvas content to destination page  
  119.                     if (!string.IsNullOrEmpty(canvasContent) && canvasContent.Length > 0) destItem["CanvasContent1"] = canvasContent;  
  120.                     // Setting source page metaInfo content to destination page  
  121.                     if (!string.IsNullOrEmpty(metaInfo) && metaInfo.Length > 0) destItem["MetaInfo"] = metaInfo;  
  122.                     // Setting source page layout webparts content to destination page  
  123.                     if (!string.IsNullOrEmpty(layoutWebpartsContent) && layoutWebpartsContent.Length > 0) destItem["LayoutWebpartsContent"] = layoutWebpartsContent;  
  124.                     // Updating the destination page  
  125.                     destItem.Update();  
  126.                     destSiteContext.ExecuteQuery();  
  127.                 }  
  128.             } catch (Exception ex) {}  
  129.         }  
  130.     }  
  131. }  
Destination Page Library Before Migration,
 
Destination Page Library Before Migration 

Destination Page Library after Migration

Destination Page Library after Migration 
After executing the above code behind, you can find the newly created modern page in the destination web 'Site Pages' library with the same page contents and "web parts" as they were in the source page.