How to create SharePoint Enterprise Wiki pages with CSOM

The following code sample shows how to create a SharePoint Enterprise Wiki Page with CSOM on your On Premise or SharePoint Online environment.

Just copy the two methods into your own class implementation where you provide a ClientContext member. Further more you need to make sure to reference the PnP Core Framework. You can get it here on NuGet for SharePoint Online. If you work On Premise, just choose the equivalent NuGet package.

The Office 365 Developer Patterns and Practices is a great initiative by Microsoft employees in conjunction with the Open Source community to provide tools and best practices to work with Office 365, especially with SharePoint Online and On Premise.

To create a ClientContext that works against any of your SharePoint Online sites you could use this code:

var credentials = CredentialManager.GetSharePointOnlineCredential("https://your-domain.sharepoint.com/sites/wiki");
var clientContext = return new ClientContext(SharePointUrl)
{
            Credentials = credentials
};

Hereby the credentials will be taken from the Microsoft Credentials Manager (available since Windows 7). So make sure to add a generic credential with your desired site URL.

The template of your targeted site must be a “Enterprise Wiki” otherwise you won’t be able to create a standard Enterprise Wiki Page because of the missing page template (EnterpriseWiki.aspx).

This is the code you are going to use:

public string CreateWikiPage(string pageName, string title, string htmlContent)
{
	if (string.IsNullOrWhiteSpace(pageName))
		throw new ArgumentException("Value must not be null or empty.", "pageName");
	if (string.IsNullOrWhiteSpace(title))
		throw new ArgumentException("Value must not be null or empty.", "title");

	if (!pageName.ToLowerInvariant().EndsWith(".aspx"))
	{
		pageName = pageName + ".aspx";
	}

	var page = GetOrCreateEnterpriseWikiPage(pageName);

	var pagesLibrary = page.ListItem.ParentList;
	ClientContext.Load(pagesLibrary, pl => pl.EnableMinorVersions);
	ClientContext.Load(pagesLibrary, pl => pl.EnableModeration);
	ClientContext.ExecuteQueryRetry();

	var pageItem = page.ListItem;
	pageItem["Title"] = title;
	pageItem["PublishingPageContent"] = htmlContent;

	pageItem.Update();

	ClientContext.Load(pageItem, p => p.File.CheckOutType);
	ClientContext.Load(pageItem, p => p.File.ServerRelativeUrl);
	ClientContext.ExecuteQueryRetry();
	if (pageItem.File.CheckOutType != CheckOutType.None)
	{
		pageItem.File.CheckIn(PublishingComment, CheckinType.MajorCheckIn);
	}

	if (pagesLibrary.EnableMinorVersions)
	{
		pageItem.File.Publish(PublishingComment);
	}

	if (pagesLibrary.EnableModeration)
	{
		pageItem.File.Approve(PublishingComment);
	}
	ClientContext.ExecuteQueryRetry();

	return pageItem.File.ServerRelativeUrl;
}

private PublishingPage GetOrCreateEnterpriseWikiPage(string pageFileName)
{
	var web = ClientContext.Web;
	ClientContext.Load(web, w => w.ServerRelativeUrl);

	var pagesLibrary = web.GetPagesLibrary();
	var pagesLibraryUrl = pagesLibrary.GetWebRelativeUrl();

	var serverRelativePageUrl = UrlUtility.Combine(web.ServerRelativeUrl, pagesLibraryUrl, pageFileName);
	ListItem pageListItem = null;
	try
	{
		var file = ClientContext.Web.GetFileByServerRelativeUrl(serverRelativePageUrl);
		file.EnsureProperty(f => f.Exists);

		if (file.Exists)
		{
			pageListItem = file.ListItemAllFields;
			pageListItem.EnsureProperty(i => i.Id);
		}
	}
	catch (ServerException)
	{
		pageListItem = null;
	}

	if (pageListItem != null)
	{
		return PublishingPage.GetPublishingPage(ClientContext, pageListItem);
	}

	var site = ClientContext.Site;
	site.EnsureProperty(s => s.ServerRelativeUrl);

	var pageFromPageLayout = ClientContext.Site.RootWeb.GetFileByServerRelativeUrl(
		$"{UrlUtility.EnsureTrailingSlash(site.ServerRelativeUrl)}_catalogs/masterpage/EnterpriseWiki.aspx");
	var pageLayoutItem = pageFromPageLayout.ListItemAllFields;

	var publishingWeb = PublishingWeb.GetPublishingWeb(ClientContext, web);
	return publishingWeb.AddPublishingPage(new PublishingPageInformation
	{
		Name = pageFileName,
		PageLayoutListItem = pageLayoutItem
	});
}

The workflow of the sample code is quite straightforward. The outside caller uses the CreateWikiPage method were you define the page name, title and HTML content. Then we make sure that the page name has the proper ASPX file extension and execute the GetOrCreateEnterpriseWikiPage method which makes sure that the desired page is being created or just returned in case it’s already existing.

Hereby we are using extension methods (like web.GetPagesLibrary()) from the PnP Core framework which makes our life with CSOM a bit more comfortable.

After that the client context will be executed to retrieve the Enterprise Wiki Page (which is a plain Publishing Page with a special content type and page layout). After that the desired fields will be populated and, depending on the Pages list settings, the page will be checked in, published and/or approved.

Finally the server relative URL of the Wiki Page is being returned.

I hope this code sample is useful for you. If you have any further questions then don’t hesitate to leave a comment.

Leave a Reply

Your email address will not be published. Required fields are marked *

17 − one =