Export Web Parts using CSOM

Export Web Parts using CSOM

When using remote provisioning solutions, you might need to export Web Parts. Did you know that you can do it using CSOM?

Remote provisioning is the future

With the release of SharePoint 2007 the Solution framework has been introduced to allow us deploy SharePoint customizations in a structured and repeatable manner. We've been using Solution packages as the de facto standard, until a few years ago Microsoft realized that provisioning SharePoint artifacts in a declarative manner is error-prone and leaves traces behind, that can have serious implications when upgrading SharePoint environments.

An alternative approach, based on the use of remote SharePoint APIs, has been suggested for provisioning SharePoint customizations and so the idea of remote provisioning was born.

SharePoint 2013 offered us a rich set of remote APIs, that we could use either through the Client-Side Object Model (CSOM) or REST, that were a perfect match for the remote provisioning techniques. But their success didn't happen overnight.

In the last few years the Office Dev PnP team did an excellent job of advocating the remote provisioning model and at the same time gathering feedback from the field to unblock developers in provisioning their solutions. Eventually, Office Dev PnP joined effort with the community building a provisioning engine that organizations can use to deploy their customizations using the recommended remote provisioning techniques.

Sometimes provisioning means also exporting

Provisioning SharePoint customizations is all but trivial. A typical SharePoint solution has its initial release followed by a number of updates. The initial deployment is relatively easy and often done to an empty environment. It's the updates however that require careful planning and consideration. SharePoint's strength is in its support of customizations: both through solutions and through configuration. As a result, what you are about to update is very likely to differ from what you initially released.

Being able to see what exactly is in the environment you are about to update, is an essential part of the SharePoint customization update process. And although the SharePoint remote API is quite impressive, there are still some things that only until recently, could be done using workarounds.

Remotely exporting Web Parts in the past

For a long time, if you wanted to export Web Parts in SharePoint using remote APIs, you had to use the /_vti_bin/exportwp.aspx page. By passing the URL of the Web Part Page and the ID of the Web Part you could get the Web Part's XML, assuming it was allowed to be exported. While the exportwp.aspx page did its job, it has one serious limitation: it doesn't support OAuth.

With continuous growth of Azure and investments such as Microsoft Graph, OAuth plays a key role for securing solutions on the Microsoft Cloud. These solutions are registered as applications with the Azure Active Directory (AAD) and use OAuth to communicate with services secured by AAD, including SharePoint Online remote APIs. Unfortunately SharePoint services located under _vti_bin do not support OAuth and since there is no way to exchange an AAD access token for a cookie, developers must fall back to using user credentials to authenticate their applications.

Exporting Web Parts using CSOM

In the March 2016 SharePoint Online CSOM update, Microsoft added support for exporting Web Parts using CSOM. This update eliminates the need to use undocumented APIs for exporting Web Parts. Instead we can use consistent approach based on CSOM throughout the whole solution.

Exporting Web Parts using CSOM is very easy and comes down to calling the LimitedWebPartManager.ExportWebPart method passing the ID of the Web Part to export as its parameter:

using (ClientContext ctx = new ClientContext("https://contoso.sharepoint.com")) {
  SecureString password = new SecureString();
  // setting password omitted for brevity
  ctx.Credentials = new SharePointOnlineCredentials("admin@contoso.onmicrosoft.com", password);
  File file = ctx.Web.GetFileByServerRelativeUrl("/pages/default.aspx");
  LimitedWebPartManager wpMgr = file.GetLimitedWebPartManager(PersonalizationScope.Shared);
  Guid webPartId = new Guid("468a7c31-053b-41b3-9e7e-d658a3ecb7fc");
  ClientResult<string> webPartXml = wpMgr.ExportWebPart(webPartId);

  // Web Part XML: webPartXml.Value

As you can see, the code sample is straight-forward and you don't even need to load any of the underlying objects such as Web Part, File or Web. All you need, in order to export a particular Web Part, is its ID. It's also worth noting that the code above will only work if the Web Part has exporting enabled.

It's great to see how community effort pays off and how Microsoft uses the feedback from the field to add capabilities to support real-life SharePoint customization scenarios. If there are other APIs missing or you have some other piece of feedback, that you would want to pass to Microsoft, I would strongly encourage you to do it on SharePoint UserVoice.