How To Create Web Part Page In SharePoint 2013/2016/2019 Programmatically Using CSOM

Basically, CSOM does not expose any inbuilt functions which can help us in creating web part page templates in SharePoint 2013/2016/2019. By using CSOM functions, we can create wiki pages, modern pages and also publishing pages,  but we cannot create web part pages.
 
In this blog post, I am going to use “Web Browser Control” to achieve this task.
 
By using “Web Browser Control”, we can create a webpart page in the destination page library. As we all know, we can create the web part pages by navigating to this URL - “<Site Url>+ /_layouts/15/spcf.aspx” page and there, we are selecting the webpart page name, page layout type, destination library, and then clicking the ‘Create’ button internally to create the page in the destination library location.
 
So in this blog post, I am going to share all code details for how you can invoke the “/_layouts/15/spcf.aspx” page and then how you can set parameters and then submit the page by using “Web Browser Control”.
 
In this example, I am using a WPF application so my design page will have the extension as .xaml.
 
Point 1
 
We have to add a web browser control in the design page, and please make it hidden by default as we are going to use it internally, so the end user cannot see this control.
 
Please refer to the below mentioned code for adding “WebBrowserControl” in design or “.xaml” page.
  1. // adding WebBrowser control in design page  
  2. <WebBrowser x:Name="WebBrowserControlCreatePage" Grid.Row="0" Grid.Column="0" Height="10" Width="10" Visibility="Hidden"/>;  
  3. Design Page  
  4. <Window x:Class="WpfApp1.MainWindow"  
  5.    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"  
  6.    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"  
  7.    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"  
  8.    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"  
  9.    xmlns:local="clr-namespace:WpfApp1"  
  10.    mc:Ignorable="d"  
  11.    Title="MainWindow" Height="450" Width="800">  
  12. <Grid>  
  13.    <Label x:Name="lblStatus" HorizontalAlignment="Center" VerticalAlignment="Center"></Label>  
  14.    <WebBrowser x:Name="WebBrowserControlCreatePage" Grid.Row="0" Grid.Column="0" Height="10" Width="10" Visibility="Hidden"/>  
  15. </Grid>  
  16. </Window>  
Point  2
 
In the code behind, we have to use the “WebBrowser” control by its “x:Name” as mentioned in the desing page. (E.g x:Name=”WebBrowserControlCreatePage” )
  1. using System;  
  2. using System.Text;  
  3. using System.Windows;  
  4. using System.Threading;  
  5. using System.Reflection;  
  6. using System.Windows.Controls;  
  7. using mshtml;  
  8. namespace WpfApp1 {  
  9.     /// <summary>  
  10.     /// Interaction logic for MainWindow.xaml  
  11.     /// </summary>  
  12.     public partial class MainWindow: Window {  
  13.         bool _isPageLoadedSuccessfully = false;  
  14.         string _webPartPageName = string.Empty;  
  15.         public MainWindow() {  
  16.             InitializeComponent();  
  17.             //Please enter the site url where you want to create the web part page  
  18.             string siteUrl = "http://siteurl";  
  19.             //Please enter a valid user name for authentication  
  20.             string userName = "Testuser";  
  21.             //Please enter valid password for the above user  
  22.             string password = "password";  
  23.             string headers = string.Empty;  
  24.             //const string HTTP = "http://";  
  25.             if (userName.Contains("\\")) userName = userName.Split('\\')[1];  
  26.             // please enter page name you want to create  
  27.             this._webPartPageName = "CreateNewWebPartPage";  
  28.             //By navigation to the below url we can create the page programmatically  
  29.             Application.Current.Dispatcher.Invoke((Action) delegate {  
  30.                 headers = "Authorization: Basic " + Convert.ToBase64String(Encoding.ASCII.GetBytes(userName + ":" + password)) + Environment.NewLine;  
  31.                 if (siteUrl.StartsWith("http://")) this.WebBrowserControlCreatePage.Navigate(String.Format("http://{0}:{1}@" + siteUrl.TrimEnd('/').Replace("http://""") + "/_layouts/15/spcf.aspx", userName, password), nullnull, headers);#  
  32.                 region Navigate to the above refered location  
  33.                 HideScriptErrorPopUp(this.WebBrowserControlCreatePage);  
  34.                 this.WebBrowserControlCreatePage.LoadCompleted += WebBrowserControlCreatePage_LoadCompleted;#  
  35.                 endregion  
  36.             });  
  37.             this.lblStatus.Content = "Please wait...Creating page";  
  38.         }#region HideScriptErrorPopUp  
  39.         private void HideScriptErrorPopUp(WebBrowser webbrowser) {  
  40.             try {  
  41.                 System.Reflection.FieldInfo fldInfo = typeof(WebBrowser).GetField("_axIWebBrowser2", BindingFlags.Instance | BindingFlags.NonPublic);  
  42.                 if (fldInfo == nullreturn;  
  43.                 object obj = fldInfo.GetValue(webbrowser);  
  44.                 if (obj == nullreturn;  
  45.                 obj.GetType().InvokeMember("Silent", BindingFlags.SetProperty, null, obj, new object[] {  
  46.                     true  
  47.                 });  
  48.             } catch {}  
  49.         }#endregion  
  50.         // This event will execute after webbrowser control loaded the refered location successfully  
  51.         # region WebBrowserControlCreatePage_LoadCompleted  
  52.         private void WebBrowserControlCreatePage_LoadCompleted(object sender, System.Windows.Navigation.NavigationEventArgs e) {  
  53.             HTMLDocument htmlDocument = null;  
  54.             try {  
  55.                 if (!this._isPageLoadedSuccessfully) {  
  56.                     htmlDocument = (HTMLDocument) WebBrowserControlCreatePage.Document;  
  57.                     CreateWebPartPage(htmlDocument);  
  58.                 }  
  59.             } catch {}  
  60.         }  
  61.         // This funtuion will create the webpart programmatically using webbrowser  
  62.         private void CreateWebPartPage(HTMLDocument htmlDocument) {  
  63.             IHTMLElementCollection iHtmlElementColl = null;  
  64.             try {  
  65.                 if (!this._isPageLoadedSuccessfully) {  
  66.                     iHtmlElementColl = htmlDocument.getElementsByTagName("input");  
  67.                     foreach(IHTMLElement iHtmlElement in iHtmlElementColl) {  
  68.                         try {  
  69.                             if (iHtmlElement.getAttribute("id") != null & amp; & amp; iHtmlElement.getAttribute("id").ToString().Contains("onetidListTitle")) iHtmlElement.setAttribute("value"this._webPartPageName, 1);  
  70.                         } catch {}  
  71.                     }  
  72.                     iHtmlElementColl = htmlDocument.getElementsByTagName("select");  
  73.                     foreach(IHTMLElement iHtmlElement in iHtmlElementColl) {  
  74.                         try {  
  75.                             if (iHtmlElement.getAttribute("id") != null & amp; & amp; iHtmlElement.getAttribute("id").ToString().Contains("onetidWebPartPageTemplate")) {  
  76.                                 var dropdown = ((IHTMLElement) htmlDocument.all.item("WebPartPageTemplate"));  
  77.                                 var dropdownItems = (IHTMLElementCollection) dropdown.children;  
  78.                                 foreach(IHTMLElement option in dropdownItems) {  
  79.                                     // Header, Footer, 3 Columns  
  80.                                     option.setAttribute("selected""selected");  
  81.                                     break;  
  82.                                 }  
  83.                             }  
  84.                             if (iHtmlElement.getAttribute("id") != null & amp; & amp; iHtmlElement.getAttribute("id").ToString().Contains("onetidDocLibIDSelect")) {  
  85.                                 var dropdown = ((IHTMLElement) htmlDocument.all.item("List"));  
  86.                                 var dropdownItems = (IHTMLElementCollection) dropdown.children;  
  87.                                 foreach(IHTMLElement option in dropdownItems) {  
  88.                                     var value = option.getAttribute("value").ToString();  
  89.                                     // Please select required library  
  90.                                     if (option.innerHTML.ToLower() == "site pages") {  
  91.                                         option.setAttribute("selected""selected");  
  92.                                         break;  
  93.                                     }  
  94.                                 }  
  95.                             }  
  96.                         } catch {}  
  97.                     }  
  98.                     iHtmlElementColl = htmlDocument.getElementsByTagName("input");  
  99.                     foreach(IHTMLElement iHtmlElement in iHtmlElementColl) {  
  100.                         try {  
  101.                             if (iHtmlElement.getAttribute("value") == "Create") {  
  102.                                 //Internally clicking the OK button to create page  
  103.                                 iHtmlElement.click();  
  104.                                 this._isPageLoadedSuccessfully = true;  
  105.                                 Thread.Sleep(5000);  
  106.                                 this.lblStatus.Content = "Page Created Successfully";  
  107.                                 break;  
  108.                             }  
  109.                         } catch {}  
  110.                     }  
  111.                 }  
  112.             } catch {}  
  113.         }  
  114.     }  
  115. }  
After the label is changed to “Page Created Successfully”, you can manually check the “Site Pages” library and there, you can find the newly-created webpart page as shown in the below screenshot.
 
How to Create Web Part Page in SharePoint 2013/2016/2019 Programmatically using CSOM?