Automatic Installation of a SPFx Web Part to a Classic Site in SharePoint On-Prem

In this article, I would like to share with you a complete solution to install a SPFx Web Part to a Classic Site inside a SharePoint On-Prem WSP solution package in 4 steps:

  • Turn on the SPFx Assets & Package files in WSP.
  • Install the SPFx Web Part into the SharePoint App Catalog inside the WSP Feature
  • Install the SPFx Web Part to a Classic Site/Web inside the WSP Feature (this article).
  • Turn on the SPFx Web Part inside the Web Template

Because there too much content for one article, I will only share the third step, my favourite one. You can read about the other steps on my blog – the link is at the bottom of the page in my author box.

In the first step, we have already created a custom gulp task for copying Assets and Package files from the SPFx project to the Module Item inside out WSP solution. In the second step, we have already programmatically copied SPFx Web Parts to the SharePoint Server 2016 App Catalog via the WSP Feature. Now we need to solve the problem of programatically installing a SPFx Web Part to a specific Site or Web or Sub-Web through a WSP Feature (so you can assume, that we will use SSOM).

First of all, we must be aware that a SPFx Web Part look pretty similiar to a SharePoint App/Add-in, from the end Site/Web point of view. It must be installed to the Web-Scope, so we will create a Web Scope Feature.

But before we do that, let’s take a look at the options for programatically installing a SPFx Web Part to SharePoint Server. The truth is, we don’t have any, because SPFx is relatively new and are still mostly unsupported On-Prem, unlike Cloud SharePoint.

So if you want to install your SPFx Web Part using the LoadAndInstallApp method, that is available for installing SharePoint Apps/Add-ins, you will receive the following error: “Value cannot be null. Parameter name: xeAppPermissionRequests.”. As I have stated above, Apps/Add-ins are very similar to SPFx Web Parts in the AppManifest.xml file structure. This means we can modify the SPFx Web Part manifest file so it looks like for Apps/Add-ins and we will be able to install the solution to SharePoint

After this has been taken care of, we can install the SPFx Web Part using the LoadAndInstallApp method. Here we will enounter a new problem – it can only be installed to the Root Web of a certain Site Collection and not to any Sub-Webs we might have. In this case, we will encounter the following error: A different version of this App is already installed with the same version number.” [ https://goo.gl/Rqb4HJ ]

We can use the ALM API but this works only for the Cloud SharePoint. My goal however is to automatically install SPFx on SharePoint On-Prem inside a Web Scope Feature, as we would like to include this feature in the Web Template for newly created SharePoint Sites/Web sites.

Lahko uporabimo ALM API, vendar deluje samo za Cloud SharePoint. Moj cilj pa je, da bi se namestil SPFx na SharePoint On-Prem avtomatsko znotraj nekega Web Scope Feature-a, saj bi rad ta feature vključil v Web Template za novo ustvarjene SharePoint Site/Web strani.

Let’s start. Inside the Microsoft.SharePoint.dll assembly I found the SPApp class with the CreateAppUsingPackageMetadata internal method. This method creates the SPApp object for our SPFx App from the App Catalog. From this, we create an App instance for a specific SPWeb with the CreateAppInstance method, which we then install with the Install method.

We would like to add this code to the FeatureActivated method inside the Web-Scope Feature Event Receiver. Everything works fine until if we activate the feature manually via Manage site features. But we will encounter problems when we activate the Feature in Web Template, because this means that our code will run in the System Account, as we must create the Site Collection in the SharePoint Central Administration. In this case, we will get the following error: “The System Account cannot perform this action.” https://goo.gl/UucuSG ]

You can impersonate another user with RunWithElevatedPrivileges but without any effect. If you run the code when creating a Web Template in the context of a user, who has Site Admin permissions, you get the above-mentioned error. But if you run the code in the context of a person with lower permissions, you receive the following error: “Only site administrators may install or uninstall Apps.”

When solving this issue, I encountered an internal disposable class, SPAppAllowRunAsSystemAccountScope, inside the SPSecurity static class (inside Microsoft.SharePoint.dll), which solved this problem.

This way, I created a new LoadAndInstallSPFxAppPackages method inside the SPFxHelper helper class, that I created in one of my previous blog posts and this solves all of the above-mentioned problems. As the method is quite large, you can view it on my GitHub channelhttps://goo.gl/dRFJRR

This method accepts the URL of the final SPWeb site, where you want to install your SPFx Web Parts.

As you can see, I used Reflection in C#, because CreateAppUsingPackageMetadata and SPAppAllowRunAsSystemAccountScope are only internal inside the Microsoft.SharePoint assembly. Therefore, we need to load this assembly. Because we wish to run this code through the Central Administration App Pool Account, I used the full path to the assembly.

After that, I ran the CreateAppUsingPackageMetadata method, SPAppAllowRunAsSystemAccountScope constructor and the Dispose method for the SPAppAllowRunAsSystemAccountScope.

The next lines of code load the SPSite and SPWeb object for our App Catalog and load all of the sppkg packets to Stream. Because sspkg packets are actually just archive files, I used the Package class in took only the AppManifest.xml file from it.

I then modified it so that it looks like a SharePoint App/Add-In. I added a StartPage and an AppPrincipal element with an Internal child element.

After that, I ran the SPAppAllowRunAsSystemAccountScope, which sets the AllowRunAsSystemAccount property to true and opened the target SPWeb, into which I wanted to install SPFx Web Parts. I tried to create a SPApp out of the previously loaded AppManifest stream. If the error 
-2146232828” shows up, this means that our App is already installed on one of the SPWebs inside the current Site Collection. In this case, I have to find one of the -> App Instance -> SPApp. And finally, create a new App Instance on the target SPWeb and run the Install method.

At the end, we need to set AllowRunAsSystemAccount back to false using the Dispose method. And lastly, we need to create a new Web Scope feature with the Feature Event Receiver.

In the Feature Activated method simply call the LoadAndInstallSPFxAppPackages method (that we described above) from the SPFxHelper static class.

public override void FeatureActivated(SPFeatureReceiverProperties properties)
{
    string cWebUrl = (properties.Feature.Parent as SPWeb).Url;
    SPFxHelper.LoadAndInstallSPFxAppPackages(cWebUrl);
}

And that’s it. Deploy the solution and activate the SPFxWebPartsFeature Site Feature inside our destination Web or Sub Web. KaBOOm, all the applications are installed without any errors.

You can read more articles from the world of SharePoint development on my blog.

Gašper Rupnik

Author: Gašper Rupnik

Software Developer and Technology Enthusiast MS, MCPS, MCSD, MCT

Leave a Reply

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