SharePoint SPFx Deployment | SP2016 OnPremise

SPFx Deployment: SharePoint 2016 OnPremise automatisiert ausrollen
04/2020
Michael F. | Solution Engineer

TL;DR

In SharePoint 2016 OnPremise wird skipFeatureDeployment nicht unterstützt. Die Lösung erfolgt per CSOM-Skript, SideLoading und angepasster App.manifest für das SPFx-Package.

Globale Bereitstellung in SharePoint Online

Beim SharePoint SPFx Deployment in SP2016 OnPremise kann eine SPFx-Solution nicht wie in SharePoint Online standardmäßig allen Site Collections automatisch zur Verfügung gestellt werden. Dies wird erreicht, indem im Projekt in der Datei /config/package-solution.json im „solution“-Objekt das Property „skipFeatureDeployment“ auf true gesetzt wird. Diese Einstellung gilt auch in SP2016 OnPremise-Umgebungen, sofern das Feature entsprechend konfiguriert ist.

1{ 
2  "$schema": "https://dev.office.com/json-schemas/spfx-build/package-solution.schema.json", 
3  "solution": { 
4    "name": "helloworld-client-side-solution", 
5    "id": "517544a9-fa90-4b2e-848e-c15392b19eb0", 
6    "version": "1.0.0.0", 
7    "includeClientSideAssets": true, 
8    "skipFeatureDeployment": true 
9  }, 
10  "paths": { 
11    "zippedPackage": "solution/helloworld.sppkg" 
12  } 
13}

Beim Hochladen der Solution vom Administrator wird diese dann automatisch einmalig für alle bereitgestellt. Die Solution taucht dann nicht im App-Bereich der Site Collections auf, ist aber entsprechend verfügbar (z. B. können die Webparts direkt verwendet werden). In jeder neu angelegten Site Collection sind die Inhalte der Solution direkt verfügbar.

Bei SharePoint 2016 On-Premise erzeugt diese Vorgehensweise jedoch einen Fehler beim Bereitstellen der Solution. Dies liegt daran, dass in SharePoint 2016 On-Premise bis dato nur SPFx 1.1 unterstützt wird. Dieses Property ist im Schema zwar bereits bekannt und erzeugt keinen Kompilierungsfehler, darf aber nicht auf true gesetzt werden. Laut Microsoft wird dies erst ab Version 1.4 unterstützt.

Hier muss also ein anderer Weg beschritten werden, um die Solution zu verteilen.

Laut Microsoft könnte dies z. B. durch die Ausführung eines separaten Skriptes nach dem Anlegen einer neuen Site Collection realisiert werden. Das Grundprinzip beruht dabei auf dem bereits bekannten Hochladen von SharePoint AddIns. Dazu muss das entsprechende SPFx-Package aus dem App-Katalog geladen und dann auf der neuen Site Collection installiert werden.

Beispiel eines CSOM-Skriptes:

1// AppCatalog 
2ClientContext appContext = new ClientContext(appCatalogUrl); 
3appContext.Credentials = credentials; 
4
5Web web = appContext.Web; 
6ListCollection lists = web.Lists; 
7appContext.Load(web); 
8appContext.Load(lists); 
9appContext.ExecuteQuery(); 
10
11// Deutsch oder Englisch 
12List cataloglist = lists.FirstOrDefault(c =>  
13    c.Title == "Apps for SharePoint" || c.Title == "Apps für SharePoint"); 
14appContext.Load(cataloglist); 
15
16string productID = "517544a9-fa90-4b2e-848e-c15392b19eb0"; 
17CamlQuery query = new CamlQuery(); 
18query.ViewXml = "<View><Query><Where><Eq> 
19        <FieldRef Name='AppProductID'/><Value Type='Text'>" + productID + "</Value> 
20    </Eq></Where></Query></View>"; 
21
22ListItemCollection listItems = cataloglist.GetItems(query); 
23appContext.Load(listItems, c => c.Include(item => item, item => item["AppProductID"])); 
24appContext.ExecuteQuery(); 
25
26ListItem item = listItems.First(); 
27appContext.Load(item); 
28appContext.ExecuteQuery(); 
29
30File file = item.File; 
31appContext.Load(file); 
32appContext.ExecuteQuery(); 
33
34ClientResult<System.IO.Stream> data = file.OpenBinaryStream(); 
35appContext.ExecuteQuery(); 
36
37// SiteCollection 
38ClientContext siteContext = new ClientContext(SiteCollectionUrl); 
39Web web1 = siteContext.Web; 
40siteContext.Load(web1); 
41siteContext.ExecuteQuery(); 
42
43AppInstance appInstance = web1.LoadAndInstallApp(data.Value); 
44siteContext.Load(appInstance); 
45siteContext.ExecuteQuery();

Führt man dieses Skript aus, kommt es zu einer weiteren Fehlermeldung:

SideLoading ist nicht aktiviert!

Damit dies erfolgreich ist, muss das Feature „SideLoading“ ebenfalls kurzfristig aktiviert werden, bevor LoadAndInstallApp() aufgerufen wird.

1FeatureCollection myFeatures = siteContext.Site.Features; 
2context.Load(myFeatures); 
3context.ExecuteQuery(); 
4Guid myFeatureId = new Guid("AE3A1339-61F5-4f8f-81A7-ABD2DA956A7D"); 
5
6// aktivieren 
7myFeatures.Add(myFeatureId, true, FeatureDefinitionScope.None); 
8context.ExecuteQuery(); 
9
10// ... LoadAndInstallApp() ausführen ... 
11
12// deaktivieren 
13myFeatures.Remove(myFeatureId, true); 
14context.ExecuteQuery();

Führt man dieses erweiterte Skript aus, kommt es zu einer weiteren Fehlermeldung:

Value cannot be null. Parameter name: xeAppPermissionRequest

Dies liegt daran, dass in der App.manifest des SPFx-Packages (helloworld.sppkg) einige Properties fehlen. Für ein automatisches Deployment sind diese auch nicht notwendig, da wir hier aber so tun, als handele es sich um ein SharePoint Add-in, müssen diese Werte ergänzt werden.

1<?xml version="1.0" encoding="utf-8"?> 
2<App xmlns="http://schemas.microsoft.com/sharepoint/2012/app/manifest" 
3   Name="helloworld-client-side-solution" 
4   ProductID="517544a9-fa90-4b2e-848e-c15392b19eb0" Version="1.0.0.0" 
5   SharePointMinVersion="16.0.0.0" IsClientSideSolution="true"> 
6  <Properties> 
7    <Title>helloworld-client-side-solution</Title> 
8    <StartPage>/</StartPage> 
9  </Properties> 
10  <AppPrincipal> 
11    <Internal></Internal> 
12  </AppPrincipal> 
13</App>

Dazu muss das erstellte Package in ein ZIP umbenannt werden. Dann kann dieser Ordner geöffnet werden und im Root-Verzeichnis liegt die App.manifest-Datei. In dieser Datei müssen die entsprechenden Properties ergänzt werden. Danach kann der ZIP-Ordner geschlossen und das Package wieder mit dem Original-Dateinamen versehen werden.

Damit funktioniert die Bereitstellung für die Site Collection.

Foto von Michael
Michael F. | Solution Engineer

Mehr zum Thema

Pfeil nach rechts (Verlinkung)
.NET-Ökosystem erklärt: Plattform, SDK, Core, C#, NuGet, Azure und DevOps kompakt und verständlich im Überblick für Entwicklerinnen und Entwickler.
07/2026

.NET: Framework, Plattform, Core? Was steckt eigentlich hinter dem Microsoft-Ökosystem?

Blauer Pfeil nach rechts (Verlinkung)
Microsoft Graph über Power Automate mit Anwendungs-Berechtigungen: Benutzerunabhängige Automatisierung von Office 365 über Azure App Registrierung.
01/2026

Microsoft Graph mit Power Automate & Berechtigungen

Blauer Pfeil nach rechts (Verlinkung)
Business-Central-Webservice in der Praxis: Authentifizierung mit C# sicher umsetzen – Windows Auth, Basic Auth und OAuth2 im Vergleich.
12/2025

Business-Central-Webservice: Authentifizierung in C#

Blauer Pfeil nach rechts (Verlinkung)
Microservices vs. modularer Monolith: Vergleich moderner .NET-Architekturen mit Praxisbeispielen und Entscheidungshilfe für skalierbare Software.
11/2025

Microservices vs. Modularer Monolith Architektur

Blauer Pfeil nach rechts (Verlinkung)