Tokrat bi rad z vami delil kompletno rešitev kako namestiti SPFx Web Parte na Classic Site znotraj SharePoint On-Prem WSP solution paketa v štirih korakih:
- Vključi SPFx Assets & Package datoteke v WSP
- Namesti SPFx Web Part v SharePoint App Catalog znotraj WSP Feature-a
- Namesti SPFx Web Part na Classic Site/Web znotraj WSP Feature-a (ta članek)
- Vključi SPFx Web Part v Web Template

Ker je vsebine za en članek preveč, bom z vami delil samo tretji korak te rešitve (zgoraj odebeljen), ker je ta moj najljubši, ostale pa si lahko ogledate na mojem blogu preko QR kode na koncu članka.
V prejšnjih korakih smo že ustvarili custom gulp task za
kopiranje Assetsov and Package datotek iz SPFx projekta v Module Item znotraj
našega WSP solutiona. Prav tako smo v drugem koraku že programsko prekopirali
SPFx Web Parte v SharePoint Server 2016 App Catalog z WSP Feature.
Sedaj pa nas čaka problem, kako programsko namestiti SPFx Web Part na specifičen
končen Site ali Web ali Sub-Web preko nekega WSP Feature-a (torej, uporabili
bomo SSOM).
Najprej se je potrebno zavedati, da SPFx Web Part izgleda za končen Site/Web dokaj podobno kot SharePoint App/Add-in. Nameščen mora biti na Web-Scope, zato bomo ustvarili Web Scope Feature.
Ampak najprej si poglejmo, kakšne vse imamo opcije te dni za
programsko namestitev SPFx Web Parta na SharePoint Server? Nimamo jih, saj so
SPFx zadeve dokaj nove in so za razliko od Cloud SharePointa na On-Prem še
dokaj nepodprte.
Torej, če želite namestiti vaš SPFx Web Part preko LoadAndInstallApp metode, ki je na voljo za nameščanje SharePoint
Apps/Add-ins vas pričaka naslednja napaka: “Value
cannot be null. Parameter name: xeAppPermissionRequests.” Kot sem
napisal zgoraj, so Apps/Add-ins zelo podobni s SPFx Web Parti po strukturi AppManifest.xml fajla. Torej, lahko
modificiramo SPFx Web Part manifest datoteko, da bo izgledala tako kot je za
Apps/Add-ins in zadevo bomo lahko namestili na SharePoint.
Ko to uredimo lahko SPFx Web part namestimo na SharePoint preko LoadAndInstallApp metode. Ampak nastane nov problem – zadevo lahko namestimo samo na Root Web določenega Site Collection-a in ne tudi na katerega izmed morebitnih Sub-Web-ov. V tem primeru vas pričaka naslednja napaka: “A different version of this App is already installed with the same version number.” [ https://goo.gl/Rqb4HJ ]
Lahko uporabimo ALM API, vendar deluje samo za Cloud SharePoint. Moj cilj pa je to, da bi rad namestil SPFx na SharePoint On-Prem avtomatsko znotraj nekega Web Scope Feature-a, saj bi rad ta feature vključil v Web Template za SharePoint Site/Web strani.
Pa začnimo. Znotraj Microsoft.SharePoint.dll assembly-a sem našel SPApp razred z CreateAppUsingPackageMetadata internal metodo. Ta metoda kreira SPApp objekt za naš SPFx App iz App Catalog-a. Iz tega kreiramo App instanco za specifičen SPWeb z CreateAppInstance metodo, ki jo potem še namestimo preko Install metode.
To kodo bi radi dodali v FeatureActivated metodo znotraj Web-Scope Feature Event Receiver-ja. Vse deluje zadovoljivo dokler feature aktiviramo ročno preko Manage site features. Problem pa nastane, ko vključimo Feature v Web Template, saj to pomeni, da bo naša koda tekla preko System Account-a, saj moramo kreirati Site Collection znotraj SharePoint Central Administration. V tem primeru vas pričaka sledeča napaka: “The System Account cannot perform this action.” [ https://goo.gl/UucuSG ]
Lahko impersionirate drugega uporabnika z uporabo RunWithElevatedPrivileges ampak brez učinka. Če poženete kodo ob kreiranju Web Template-a v kontekstu osebe, ki ima Site Admin pravice, vam javi zgornjo napako. Če pa poženete kodo v kontekstu osebe z nižjimi pravicami, pa vas pričaka sledeča napaka: “Only site administrators may install or uninstall Apps.”
Ob reševanju te težave sem znotraj SPSecurity statičnega razreda (znotraj Microsoft.SharePoint.dll našel internal disposable razred SPAppAllowRunAsSystemAccountScope, kateri mi je rešil zgornji problem.
Tako sem znotraj SPFxHelper helper razreda, ki sem ga ustvaril v enem izmed mojih predhodnih blog postov, kreiral novo LoadAndInstallSPFxAppPackages metodo, ki reši vse zgornje težave. Ker je le ta malce prevelika za v Piko, si jo lahko ogledate na mojem GitHub kanalu preko naslednje povezave: https://goo.gl/dRFJRR
Ta metoda sprejme url končnega SPWeb mesta, kamor želite namestiti vaše SPFx Web Parte.
Kot lahko vidite sem uporabil Reflection v C# ker sta CreateAppUsingPackageMetadata in SPAppAllowRunAsSystemAccountScope samo internal znotraj Microsoft.SharePoint assembly-a. Torej moramo naložiti ta assembly. Ker bi radi zaganjali kodo preko Central Administration App Pool Account-a sem uporabil full path do assembly-a.
Nato sem naložil CreateAppUsingPackageMetadata metodo, SPAppAllowRunAsSystemAccountScope konstruktor in Dispose metodo za SPAppAllowRunAsSystemAccountScope.
Naslednje vrstice kode naloadajo SPSite in SPWeb objekt za
naš App Catalog ter naložijo vse sppkg pakete
v Stream. Ker so sppkg paketi
dejansko archive datoteke sem uporabil Package
razred in iz njega vzel samo AppManifest.xml
datoteko.
Nato sem jo modificiral tako, da izgleda kot SharePoint App/Add-In. Dodal sem StartPage in AppPrincipal element z Internal
child elementom.
Nato sem zagnal SPAppAllowRunAsSystemAccountScope,
ki postavi AllowRunAsSystemAccount
property na true ter odprl ciljni
SPWeb, v katerega želim namestiti SPFx Web Parte. Skušal sem kreirati SPApp
iz prej naloženega AppManifest
stream-a. Če pride do napake s kodo “-2146232828”,
potem je naš App že nameščen na enem izmed SPWeb-ov znotraj trenutnega Site
Collectiona. V tem primeru poiščem enega izmed njih – > App Instance ->
SPApp.
In končno kreiram novo App Instanco na
ciljnem SPWeb-u ter poženem Install metodo.
Na koncu moram postaviti AllowRunAsSystemAccount nazaj na false preko Dispose metode.
Ne nazadnje moramo kreirati še nov Web Scope feature z Feature Event Receiverjem.

V Feature Activated metodi nato enostavno kličem zgoraj spisano LoadAndInstallSPFxAppPackages metodo v SPFxHelper statičnem razredu.
public override void FeatureActivated(SPFeatureReceiverProperties properties)
{
string cWebUrl = (properties.Feature.Parent as SPWeb).Url;
SPFxHelper.LoadAndInstallSPFxAppPackages(cWebUrl);
}
In to je vse. Deploy-amo solution in aktiviramo SPFxWebPartsFeature Site Feature znotraj našega končnega Web-a ali Sub-Weba. KaBOOm,vse aplikacije so nameščene pravilno, brez kakršne koli napake.
Več člankov iz sveta SharePoint razvoja pa si lahko preberete na mojem blogu.