SharePoint Multiclient Anwenderstudie 2016

Die Hochschule der Medien Stuttgart führt wieder eine Online-Befragung durch und auch dieses Mal auch von mir der Aufruf mitzumachen. Es gibt wieder etwas zu gewinnen!

Auf der Seite heißt es dazu:

die Verbreitung der Portalsoftware Microsoft SharePoint ist in den letzten Jahren enorm gestiegen.

Die Frage ist: Wie zufrieden sind die Kunden? Dieser Thematik geht die Hochschule der Medien unter der Leitung von Prof. Dr. Thorsten Riemke-Gurzki und Prof. Dr. Arno Hitzges in der vorliegenden Befragung nach.

Ziel ist es, die Meinung der tatsächlichen Anwender zu erfragen, um auf Grundlage der Aussagen Rückschlüsse auf den Prozess der Nutzung von Intranet und Unternehmensportalen und der Integration von Microsoft SharePoint vornehmen zu können.

SharePoint 2013: „Mehr anzeigen“ Link auf Formularen entfernen

Und hier gleich noch ein Beitrag zum Thema Anpassung von Aufgabenformularen in SharePoint 2013. Hier ging es darum, die Verwandten Elemente auch auf dem EditForm anzuzeigen. Jetzt soll noch gezeigt werden, wie man den meiner Meinung nach völlig überflüssigen „Mehr anzeigen“ Link von den Aufgabenformularen entfernen und gleich alle Felder darstellen kann.

Der Link selbst ruft nur eine JavaScript-Funktion rlfiShowMore auf. Das machen wir uns zunutze, indem wir diese Funktion einfach selbst aufrufen, sobald die Seite geladen ist. Auf dem Formular muß dazu nur diese Zeile Script eingefügt werden:

_spBodyOnLoadFunctionNames.push(„rlfiShowMore“);

SharePoint 2013: Verwandte Elemente auf dem EditForm anzeigen

Bei SharePoint 2013 haben Workflowaufgaben standardmäßig eine Spalte Verwandte Elemente (Related Items). Leider ist diese Spalte ohne weiteres Zutun nur auf dem Formular zur Anzeige (DispForm) vorhanden und auch nur dort pflegbar.

SharePoint 2013 Workflows fügen beim Erstellen einer Aufgabe dort einen Link zum Element ein, auf dem Workflow läuft. Wenn man also einen Workflow hat, der z.B. Aufgaben erstellt, mit deren Hilfe etwas genehmigt werden soll, hat es durchaus Sinn diesen Link auch auf dem Änderungsformular (EditForm) darzustellen. Die genehmigende Person hat dann direkt auf dem Formular, mit dem sie arbeitet, auch einen Link zum Element, das genehmigt werden soll.

Das ist mal wieder ein typischer Fall für JavaScript. Das notwendige Script dazu kann man, wie fast immer, entweder in einem Script Editor Webpart oder per SharePoint Designer direkt im Code der Seite unterbringen.

SharePoint stellt zum Zugriff auf die Verwandten Elemente das Objekt SP.RelatedItemManager zur Verfügung. Es befindet sich in der Datei sp.js und kann erst verwendet werden, wenn diese geladen ist. Wir beginnen das Script also so:

ExecuteOrDelayUntilScriptLoaded(function() {
    // hier der Code
}, "sp.js");

Wir benötigen den ClientContext, den man auf die bekannte Art bekommt. Außerdem die ID der Aufgabenliste, die man aus dem _spPageContextInfo-Objekt bekommt. Und schließlich die ID der Aufgabe, die man aus der URL holen kann. Wir bedienen uns hierzu der altbekannten Methode getQueryStringParameter:

function getQueryStringParameter(paramToRetrieve) {
  if (document.URL.indexOf("?") > 0) {
    var params = document.URL.split("?")[1].split("&"),
        i,
        singleParam;
         
    for (i = 0; i < params.length; i++) {
      singleParam = params[i].split("=");
      if (singleParam[0] == paramToRetrieve)
        return singleParam[1];
    }
  }
  return "";
}

Mit diesen Werten liefert uns SP.RelatedItemManager direkt die Verwandten Elemente zur aktuellen Aufgabe:

var ctx = SP.ClientContext.get_current(),
    itemId = getQueryStringParameter("ID"),
    relItems = SP.RelatedItemManager.getRelatedItems(ctx, _spPageContextInfo.pageListId, itemId);

Jetzt braucht es nur ein executeQueryAsync und die Verwandten Elemente können benutzt werden. Es handelt sich dabei um ein Array, das Objekte enthält. Die Objekte haben eine get_url() Methode, die die URL des Elements liefert. Sie kann direkt z.B. in einen Link eingebaut werden. Und es gibt eine get_title() Methode, die den Anzeigenamen liefert, der z.B. als Text für den Link verwendet werden kann.

Hier nur ein kleines Beispiel, wie damit per jQuery ein Link in einem vorher bereitgestellten Container mit der ID myContainer erzeugt werden kann. Dazu nochmal das gesamte Script zum Kopieren und Einfügen:

ExecuteOrDelayUntilScriptLoaded(function() {
    var ctx = SP.ClientContext.get_current(),
        itemId = getQueryStringParameter("ID"),
        relItems = SP.RelatedItemManager.getRelatedItems(ctx, _spPageContextInfo.pageListId, itemId);
    ctx.executeQueryAsync(function() {
        var html;
        if (relItems.length > 0) {
            html = "<a href=’" + relItems[0].get_url() + "‘ target=’_top‘>" + relItems[0].get_title() + "</a>";
            $("#myContainer").append(html);
        }
        }, function() {}
    );

    function getQueryStringParameter(paramToRetrieve) {
        if (document.URL.indexOf("?") > 0) {
            var params = document.URL.split("?")[1].split("&"),
                i,
                singleParam;
         
            for (i = 0; i < params.length; i++) {
                singleParam = params[i].split("=");
                if (singleParam[0] == paramToRetrieve)
                    return singleParam[1];
            }
        }
        return "";
    }
}, "sp.js");

SPWeb.EnsureUser und Claims

Jeder SharePoint-Entwickler kennt wahrscheinlich die EnsureUser-Methode der SPWeb-Klasse (Beschreibung bei MSDN). Der Methode übergibt man einen Benutzer in der Form Domäne\Login und bekommt eine gültige SPUser-Instanz und zwar unabhängig davon, ob der Benutzer in der Website bereits bekannt ist oder nicht.

Das war jedenfalls "früher" der Fall, d.h. vor der Benutzung von Claims-Authentifizierung. Wird die betreffende Webanwendung mit Claims betrieben, was bei SharePoint 2013 Standard ist, muß man etwas anders vorgehen. Dasselbe gilt für SharePoint 2010 wenn Claims benutzt wird.

Die Angabe von Domäne\Login reicht alleine nicht mehr aus und man muß zusätzlich angeben um welche Art von Benutzer es sich handelt. Mit Claims-Authentifizierung können schließlich auch andere Arten von Benutzerquellen als nur Active Directory verwendet werden. Hier die grundsätzliche Vorgehensweise:

string account = @"domain\login";
SPClaimProviderManager cpm = SPClaimProviderManager.Local;
SPClaim userClaim = cpm.ConvertIdentifierToClaim(account, SPIdentifierTypes.WindowsSamAccountName);
SPUser user = web.EnsureUser(userClaim.ToEncodedString());

Der Code benötigt folgendes using-Statement:

using Microsoft.SharePoint.Administration.Claims;

Der gezeigte SPIdentifierTypes.WindowsSamAccountName gilt für AD-Benutzer. Je nach Herkunft des gesuchten Benutzers muß hier ein anderer Typ angegeben werden.

SharePoint 2013: Distributed Cache aktuell halten

Der Distributed Cache Dienst (AppFabric) spielt in SharePoint 2013 eine sehr wichtige Rolle und entgegen früherer Aussagen von Microsoft, er würde zusammen mit SharePoint aktuell gehalten, ist man selbst für die Aktualität verantwortlich.

Ich beziehe mich hier auf diesen Beitrag von Wictor Wilén. Er beschreibt dort sehr ausführlich die genauen Schritte und auch warum etwas wie gemacht werden sollte. Als persönliche Referenz fasse ich hier nur in aller Kürze die notwendigen Schritte zusammen. Dabei beziehe ich mich auf das derzeit aktuelle CU5, das hier heruntergeladen werden kann.

Schritt 1: Distributed Cache anhalten. Das geht in der SharePoint Management Shell so:

Stop-SPDistributedCacheServiceInstance -Graceful

Schritt2: Das Update installieren. Dazu einfach die heruntergeladene Datei durch Doppelklick starten.

Schritt 3: Eine kleine Anpassung in der Konfigurationsdatei. Dazu Notepad (oder einen anderen Editor) als Administrator starten und diese Datei öffnen:

Program Files/AppFabric 1.1 for Windows Server/DistributedCacheService.exe.config

In diese Datei fügt man irgendwo innerhalb von <configuration> … </configuration> folgendes ein:

<appSettings>
  <add key="backgroundGC" value="true" />
</appSettings>

Schritt 4: Distributed Cache wieder starten. Das geht ebenfalls in der SharePoint Management Shell:

$svc = Get-SPServiceInstance | ? { $_.TypeName -eq "Distributed Cache" -and $_.Server.Name -eq $env:computername }
$svc.Provision()

Diese Schritte müssen nacheinander auf allen Servern der SharePoint Farm ausgeführt werden, auf denen der Distributed Cache läuft.

Anwenderstudie SharePoint 2014/2015

Die Hochschule der Medien in Stuttgart führt eine Online-Befragung zur Kundenzufriedenheit durch und hat mich gebeten, mit zur Verbreitung beizutragen. Deshalb hier der Aufruf: bitte nehmt an der Befragung teil! Es gibt auch etwas zu gewinnen!

Auf der Seite heißt es dazu:

die Verbreitung der Portalsoftware Microsoft SharePoint ist in den letzten Jahren enorm gestiegen.

Die Frage ist – wie zufrieden sind die Kunden? Dieser Frage geht die Hochschule der Medien unter der Leitung von Prof. Dr. Thorsten Riemke-Gurzki und Prof. Dr. Arno Hitzges in der vorliegenden Befragung nach.

Ziel ist es, die Meinung der tatsächlichen Anwender zu erfragen, um auf Grundlage der Aussagen Rückschlüsse auf den Prozess der Nutzung von Intranet und Unternehmensportalen und der Integration von Microsoft SharePoint vornehmen zu können.

Und hier nochmal der Link zur Befragung.

Inhaltsdatenbank von SharePoint 2010 nach 2013 migrieren

Dieser Beitrag beschreibt, wie man eine Inhaltsdatenbank von SharePoint 2010 nach SharePoint 2013 migriert und welche Probleme dabei im Bezug auf die Authentifizierungsmethode auftreten können. Es geht dabei wirklich nur um die Vorgehensweise beim Migrieren einer Inhaltsdatenbank. Beim Planen und Durchführen einer kompletten Migration ist wesentlich mehr zu beachten! Hier finden sich dazu ausführliche Informationen bei TechNet.

Ich habe diesen Prozeß bereits einige Male gemacht, mußte aber immer wieder Kleinigkeiten z.B. zur genauen Syntax der PowerShell-Cmdlets nachschlagen. Es handelt sich hierbei also durchaus auch um eine Nachschlagemöglichkeit für mich selbst.

Datenbankbackup auf dem alten System

Zunächst wird die Inhaltsdatenbank vom alten zum neuen System verschoben. Es gibt dazu mehrere Möglichkeiten, aber die einfachste dürfte in den meisten Fällen Backup und Restore sein. Dazu verwendet man z.B. das SQL Management Studio. Weil es in diesem Blog in erster Linie um SharePoint und nicht um SQL Server geht, werden die einzelnen Schritte hier nur kurz erläutert.

Wenn man ein Backup einer Inhaltsdatenbank erstellen möchte, sollte man verhindern, daß ein SharePoint-Prozeß während des Backups in die Datenbank schreibt. Dazu kann man entweder die Verbindung zwischen SharePoint und SQL Server kappen oder den oder die SharePoint-Server herunterfahren oder ganz einfach die Datenbank auf read-only setzen. Natürlich kann in dieser Zeit kein SharePoint-Benutzer mit den Daten dieser Datenbank arbeiten.

Um eine Datenbank read-only zu machen, klickt man im SQL Management Studio mit der rechten Maustaste darauf und dann auf Properties. Die entsprechende Einstellung findet sich hier unter Options:

Jetzt kann man durch Rechtsklick > Tasks > Back Up… ein Backup der Datenbank erstellen. Dabei ist im Grunde nichts Besonderes zu beachten. Der Dialog kann z.B. so aussehen:

Falls die Benutzer mit dem alten System weiterarbeiten sollen, z.B. weil es sich nur um eine Testmigration handelt, kann jetzt die read-only Einstellung wieder von der Datenbank entfernt werden.

Datenbank auf dem neuen System wiederherstellen

Man kopiert sich jetzt die oben erstellte Backupdatei auf den neuen SQL Server (nur lokal abgelegte Dateien können wiederhergestellt werden). Über das SQL Management Studio legt man eine neue Datenbank an. Die Einstellungen sind dabei völlig egal. Über Rechtsklick auf die neue Datenbank und dann Tasks > Restore > Database stellt man jetzt das oben erstellte Backup auf dieser Datenbank wieder her.

Man wählt dazu unter Device die Datei aus und prüft unter Destination, daß die korrekte Datenbank überschrieben wird:

Unter Files kann man prüfen, daß die zugehörigen Datenbankdateien (mdf und ldf) auch an der gewünschten Stelle landen. Wichtig ist noch, daß unter Options der Haken bei Overwrite the existing database gesetzt wird:

 

Nach dem Wiederherstellen der Datenbank nicht vergessen, die read-only Einstellung wieder zu entfernen!

Datenbank prüfen

Zum Test, ob die Datenbank auf dem neuen System verwendet werden kann, gibt es ein PowerShell-Cmdlet. Man öffnet dazu eine SharePoint Management Shell als Administrator und gibt diesen Befehl ein:

Test-SPContentDatabase –Name <NameDerDatenbank> -WebApplication http://sharepoint

Das Cmdlet Test-SPContentDatabase ist hier beschrieben.

Falls das Cmdlet Warnungen betreffs fehlender Feature ausgibt, sollten die entsprechenden Solutions (WSPs) auf dem Zielsystem bereitgestellt werden. Man kann die Datenbank zwar trotzdem einbinden, aber die enthaltenen Sites werden dann höchstwahrscheinlich nicht (korrekt) funktionieren.

Classic und Claims Authentifizierung

Sehr häufig wird man bei einer Migration von 2010 nach 2013 von Test-SPContentDatabase aber folgende Meldung erhalten:

The web application is configured with claims authentication mode however the content database you are trying to attach is intended to be used against a windows classic authentication mode.

Bei SharePoint 2010 war die Verwendung der Claims Authentifizierung optional, während sie bei SharePoint 2013 Standard ist und genau das macht uns jetzt Probleme. Im Web findet man viele Anleitungen dazu, wie man mit der Problematik umgeht. Es werden jeweils zwei Möglichkeiten beschrieben:

Möglichkeit 1: Upgrade der Datenbank auf Claims im alten System vor dem Backup. Wie man das macht, ist hier beschrieben. Dabei werden allerdings Änderungen an einem bestehenden und eventuell produktiv genutzten System gemacht. Wenn z.B. die Migration erstmal nur getestet werden soll, ist das nicht unbedingt erwünscht.

Möglichkeit 2: Erstellen einer Classic Webanwendung in SharePoint 2013 per PowerShell, anhängen der Datenbank an diese Webanwendung und danach Upgrade auf Claims. Wie man das macht, ist hier beschrieben (weiter unten auf der Seite). Auch diese Vorgehensweise ist nicht immer praktikabel, well man dabei eine neue Webanwendung im Zielsystem benötigt. Wenn bereits eine Webanwendung mit Inhalt besteht und die Datenbank dort angehängt werden soll, ist dieser Weg nicht direkt gangbar.

Es gibt aber eine dritte Möglichkeit, bei der die Meldung ignoriert werden und die Datenbank trotzdem an die Webanwendung angehängt werden kann.

Datenbank anhängen

Die Datenbank wird mit Hilfe von PowerShell einer SharePoint-Webanwendung angehängt:

Mount-SPContentDatabase <NameDerDatenbank> -DatabaseServer <Servername> -WebApplication http://sharepoint

Das Cmdlet Mount-SPContentDatabase ist hier beschrieben.

Nach dem Anhängen der Datenbank kann ein Farmadministrator die in der Datenbank enthaltenen Websites im Browser aufrufen. Alle anderen Benutzer erhalten aber eine Zugriff verweigert Fehlermeldung. Um das zu reparieren, muß jetzt noch die Authentifizierung angepaßt und die Benutzer migriert werden. Das geht jetzt mit

Möglichkeit 3: per PowerShell nachträglich auf Claims umstellen. Dazu führt man in der SharePoint Management Shell folgendes aus:

$wa = Get-SPWebApplication http://sharepoint
$wa.MigrateUsers($true)
$wa.ProvisionGlobally()

Und schon sind alle Websitesammlungen der Datenbank migriert und können von allen Benutzern verwendet werden.

SharePoint 2013: Liste innerhalb der Websitesammlung anzeigen

Eine Frage, die immer wieder aufkommt, ist die, wie man die Daten einer Liste oder einer Bibliothek in einer anderen Website anzeigen kann. In einem früheren Beitrag habe ich gezeigt, wie man das in SharePoint 2010 machen kann. Leider funktioniert es in SharePoint 2013 mit der Methode nicht mehr. Die Vorgehensweise ist zwar ähnlich, aber auch die Werkzeuge haben sich verändert, so daß es jetzt einen eigenen Beitrag dazu gibt, wie man eine Listenansicht in SharePoint 2013 für die gesamte Websitesammlung zur Verfügung stellt.

Ansicht vorbereiten

Man kann die Ansicht zwar auch später noch problemlos über die Webparteinstellungen bearbeiten, auch dann, wenn sie in einer anderen Website eingefügt wurde, aber es empfiehlt sich trotzdem sie bereits an der Quelle so aufzubereiten, wie sie später an den meisten Stellen verwendet wird (oder verwendet werden soll).

Man kann dazu entweder eine vorhandene Listen- oder Bibliotheksansicht verändern, auf der Liste oder Bibliothek eine neue Ansicht erzeugen (und später wieder löschen) oder auch auf einer beliebigen Seite eine Ansicht einfügen und verändern. Auch in diesem Fall kann man sie später problemlos wieder von der Seite entfernen (oder die ganze Seite löschen).

Ansicht exportieren

Die oben erstellte Ansicht muß jetzt exportiert werden. Warum Microsoft den dafür vorgesehenen Menüpunkt aus dem Webpartmenü entfernt hat, kann ich nicht sagen, aber mit SharePoint Designer geht es zum Glück immer noch. Man öffnet also die Website in SharePoint Designer und navigiert zur Seite mit der gewünschten Ansicht. Wenn sie sich als Ansicht direkt auf der Liste oder Bibliothek befindet, kann man dazu über Listen und Bibliotheken und dann über die Ansichten einer Liste oder Bibliothek gehen. Wenn sie sich auf einer beliebigen Seite befindet, muß man diese öffnen. Je nach Speicherort der Seite kann man z.B. über Site Pages oder auch über Alle Dateien dorthin gelangen.

In SharePoint Designer 2013 gibt es keine Designansicht mehr, so daß man nach dem Öffnen der Seite direkt in die Quellcodeansicht gelangt. Dort sucht man sich die gewünschte Ansicht (im Idealfall befindet sich nichts anderes auf der Seite). Man findet Listenansichten z.B. indem man nach WebPartPages:XsltListViewWebPart sucht. Jetzt setzt man einfach die Einfügemarke irgendwo innerhalb dieses Elements und im Ribbon oben erscheint unter der Überschrift WEBPARTTOOLS der Reiter FORMAT. Darin gibt es rechts zwei Optionen zum Webpart speichern:

Direktes Speichern in den Websitekatalog hat keinen Sinn, weil es damit in anderen Websites nicht funktionieren wird. Man speichert das Webpart also in eine Datei, z.B. als ListeInWebsite1.webpart und merkt sich den Ort, an dem man die Datei abgelegt hat.

Gespeicherte Ansicht editieren

In der Datei muß jetzt eine Änderung gemacht werden. Es handelt sich dabei um eine XML-Datei, die man mit einem geeigneten Editor bearbeiten kann. Zur Not geht es auch mit Windows-Notepad. Man sucht in der Datei nach WebId und stellt fest, daß diese als leere Guid hinterlegt wurde: 00000000-0000-0000-0000-000000000000

Dort muß jetzt die richtige ID der Website eingetragen werden, in der sich die Liste oder Bibliothek tatsächlich befindet. Man findet diese ID z.B. über den REST-Service, indem man im Browser an die Adresse der Website folgendes anhängt: /_api/web/id

Als Adresse steht dann sowas im Browser http://sharepoint/sites/web2/_api/web/id und die Ausgabe sieht so aus:

Der markierte Teil ist die gesuchte Guid der Website. Man überschreibt damit die leere Guid in der Datei und speichert sie. Falls der Browser die Daten nicht wie oben gezeigt darstellt: hier steht, wie man das ändert.

Ansicht importieren

Die in der Datei gespeicherte Ansicht wird jetzt in den Webpartkatalog importiert. Dazu geht man zuerst in die Rootwebsite der Websitesammlung. Dort dann über das Menü hinter dem kleinen Zahnrad rechts oben in die Websiteeinstellungen. Unter Web-Designer-Kataloge findet man den Link Webparts. Dort lädt man die Datei hoch und kann dann noch verschiedene Metadaten angeben wie z.B. eine Beschreibung. Man kann auch die Gruppe angeben, unter das Webpart später beim Einfügen in eine Seite gefunden wird. Wenn man hier nichts angibt, erscheint es unter Verschiedenes.

Das war’s auch schon. Die Ansicht ist jetzt als wiederverwendbares Webpart im Webpartkatalog gespeichert und kann innerhalb der gesamten Websitesammlung verwendet werden.

SharePoint 2013 Apps: Schnellstartleiste im App Web

Bei der Suche im Web nach einer Möglichkeit die Schnellstartleiste (Quicklaunch) auch im App Web verwenden zu können, bin ich auf viele nicht funktionierende "Lösungen" gestossen. Zumindest bei mir hatte keines der meist identischen Beispiele die erwünschte Wirkung erzielt. Offenbar haben hier viele Blogger ohne zu testen einfach nur voneinander abgeschrieben. Nach ein wenig Probieren habe ich dann aber selbst eine funktionierende Lösung gefunden.

Für das App Web wird standardmäßig die Gestaltungsvorlage (Master Page) app.master verwendet und bei der ist die Schnellstartleiste ausgeblendet. Wenn man diese verwenden möchte, muß man also eine eigene Gestaltungsvorlage verwenden. Wie das geht, habe ich hier beschrieben.

Man sucht jetzt einfach in der eigenen Gestaltungsvorlage nach PlaceHolderLeftNavBar. Standardmäßig ist dieser Platzhalter leer. Den leeren Platzhalter überschreibt man mit folgendem:

<asp:ContentPlaceHolder id="PlaceHolderLeftNavBar" runat="server">
 
<div>
    <asp:SiteMapDataSource SiteMapProvider="SPNavigationProvider"
                           ShowStartingNode="False"
                           id="QuickLaunchSiteMap"
                           StartingNodeUrl="sid:1025"
                           runat="server"/>
    <SharePoint:AspMenu id="V4QuickLaunchMenu"
                        runat="server"
                        EnableViewState="false"
                        DataSourceId="QuickLaunchSiteMap"
                        UseSimpleRendering="true"
                        Orientation="Vertical"
                        StaticDisplayLevels="3"
                        AdjustForShowStartingNode="true"
                        MaximumDynamicDisplayLevels="2"
                        SkipLinkText=""
                        CssClass="s4-ql"/>
  </div>
</asp:ContentPlaceHolder>

Das reicht bereits, um die Schnellstartleiste anzuzeigen. Allerdings gibt es jetzt noch ein Problem: der Inhaltsbereich rutscht jetzt auf manchen Seiten unter die Schnellstartleiste, anstatt rechts daneben angezeigt zu werden. Um das zu beheben, muß man dem <div>, das in der Gestaltungsvorlage direkt darunter notiert ist, einen Abstand per Inline-Style zuweisen:

<div id="contentBox" aria-live="polite" aria-relevant="all" style="margin-left: 250px;">

SharePoint 2013 Apps: Eigene Gestaltungsvorlage verwenden

Wenn eine App für SharePoint ein in SharePoint gehostetes App Web benutzt, kann man für dieses eine eigene Gestaltungsvorlage (Master Page) benutzen. Ohne weiteres Zutun verwendet SharePoint für App Webs die Standard-Gestaltungsvorlage app.master.

Dieser Beitrag zeigt die Vorgehensweise anhand einer SharePoint-hosted App, aber es funktioniert genauso bei cloud-basierten Apps, die ein App Web benutzen, z.B. um dort eigene Listen für die Datenhaltung anzulegen.

Gestaltungsvorlage hinzufügen

Wir müssen zunächst die zu verwendende Gestaltungsvorlage in das Visual Studio Projekt aufnehmen. Dazu legen wir im Projekt, das die App repräsentiert, ein neues Element vom Typ Module an (z.B. durch Rechtsklick auf das Projekt – Add New Item Module). Wichtig ist, daß das wirklich im App-Projekt geschieht (das ist das, welches die AppManifest.xml enthält) und nicht in dem Projekt, das die Remote-Komponenten von cloud-basierten Apps enthält. Bei einer SharePoint-hosted App gibt es in Visual Studio ohnehin nur dieses eine Projekt.

Beim Hinzufügen eines Modules legt Visual Studio automatisch eine Sample.txt Datei an. Sie kann einfach gelöscht werden.

Als Ausgangsbasis für die eigene Gestaltungsvorlage empfiehlt es sich die standardmäßig verwendete app.master zu benutzen. Man findet sie auf einem SharePoint 2013 Server unter 15\TEMPLATE\GLOBAL. Zum Hinzufügen der Datei in Visual Studio gibt es jetzt zwei Möglichkeiten. Man fügt entweder eine neue Textdatei ein, nennt sie z.B. myapp.master und fügt dann per Kopieren und Einfügen den Inhalt hinzu. Oder man kopiert gleich die ganze Datei in den Ordner des Modules, benennt sie um und nimmt sie über Add Existing Item ins Projekt auf. Visual Studio nimmt die Datei jetzt automatisch in die Elements.xml des Modules auf:

<Module Name="CustomMaster">
  <File Path="CustomMaster\myapp.master" Url="CustomMaster/myapp.master" ReplaceContent="TRUE" />
</Module>

Hier müssen jetzt diverse Änderungen gemacht werden, damit die Datei in den Katalog für Gestaltungsvorlagen (Master Page Catalog) aufgenommen wird. Dazu fügt man beim Module-Element ein Attribut List="116" und ein Attribut Url="_catalogs/masterpage" hinzu. Beim File-Element wird der Ordnername aus dem Url-Attribut entfernt, das ReplaceContent-Attribut wird komplett entfernt und ein Attribut Type="GhostableInLibrary" wird hinzugefügt. Das Module sieht dann so aus:

<Module Name="CustomMaster" List="116" Url="_catalogs/masterpage">
 
<File Path="CustomMaster\myapp.master" Url="myapp.master" Type="GhostableInLibrary" />
</Module>

Damit haben wir jetzt schonmal erreicht, daß die Datei im Gestaltungsvorlagenkatalog bereitgestellt wird.

Gestaltungsvorlage verwenden

In einzelnen Seiten

Wenn es hier nur um eigene Seiten, wie z.B. die von Visual Studio automatisch angelegte Default.aspx geht, kann man die zu verwendende Gestaltungsvorlage einfach in der jeweiligen Datei angeben. Standardmäßig steht dort (in der @Page-Direktive)

MasterPageFile="~masterurl/default.master"

Das ersetzt man durch

MasterPageFile="~site/_catalogs/masterpage/myapp.master"

Und schon verwendet die Seite unsere eigene Gestaltungsvorlage.

In allen Seiten

Schwieriger wird das Ganze wenn alle Seiten automatisch die neue Gestaltungsvorlage übernehmen sollen. Wenn man z.B. im App Web eigene Listen hat, sollen die zur Liste gehörenden Ansichts- und Formularseiten ebenfalls die neue Gestaltungsvorlage verwenden. Um das zu erreichen, erstellt man auch noch eine eigene Websitevorlage (Site Template) für das App Web.

Ähnlich wie bei der Gestaltungsvorlage selbst, erstellt man im Projekt ein neues Module, fügt die standardmäßig verwendete ONET.XML ein und modifiziert sie. Die Standardvorlage findet man ebenfalls auf jedem SharePoint 2013 Server im Ordner 15\TEMPLATE\SiteTemplates\App\Xml. Die Datei ONET.XML fügt man im Module ein. Wichtig: sie darf nicht umbenannt werden!

In der Datei müssen jetzt noch Änderungen gemacht werden. Beim Element Project/Configurations/Configuration muß das Name-Attribut geändert und der Pfad im MasterUrl-Attribut angepaßt werden:

MasterUrl="_catalogs/masterpage/myapp.master"

Hier noch ein Screenshot zur Verdeutlichung der Anpassungen:

Die neue Vorlage muß jetzt noch also solche bekannt gemacht werden. Dies geschieht durch ein WebTemplate-Element, das in die Elements-xml des Modules eingefügt wird, das die ONET.XML enthält. Dazu fügt man innerhalb von Elements, aber außerhalb von Module folgendes ein:

<WebTemplate BaseTemplateID="1" BaseConfigurationID="0" BaseTemplateName="APP" Name="CustomTemplate" ProductVersion="15" DisplayCategory="Custom" Description="Web template for Custom Apps."></WebTemplate>

Es sollte also so aussehen:

Wichtig ist dabei, daß das Name-Attribut beim WebTemplate-Element exakt dem Name-Attribut des Module-Elements entspricht!

Als letzten Schritt müssen wir jetzt noch der App mitteilen, daß wir das App Web aus unserer Vorlage erstellen wollen. Das geht über die AppManifest.xml, die durch einen Rechtsklick in der Codeansicht geöffnet wird (nicht mit dem Manifest-Designer). In die Datei fügt man jetzt innerhalb von Properties folgendes ein:

<WebTemplate Id="{6393fe60-d014-4ed1-9153-518538c562a3}#CustomTemplate"></WebTemplate>

Es sollte so aussehen:

Der Inhalt des Id-Attributs setzt sich so zusammen:

  • Öffnende geschweifte Klammer

  • Feature-ID (s.Erklärung unten)

  • Schließende geschweifte Klammer

  • Raute/Hash-Zeichen #

  • Der Name des WebTemplates bzw. des Modules (s.o.)

Als Feature-ID muß die Id des Features angegeben werden, das die Vorlage enthält. Man bekommt sie, indem man das Feature in Visual Studio per Doppelklick öffnet und dann oberhalb des Designers auf Manifest umschaltet:

Test

Um das Ganze zu testen, machen wir jetzt eine Änderung in unserer Gestaltungsvorlage und schauen dann, ob diese Änderung in der bereitgestellten App auch sichtbar ist. Man kann dazu eine beliebige Änderung vornehmen. Ich habe einfach oberhalb des Inhaltsbereichs einen festen Text eingefügt:

In Visual Studio F5 gedrückt und siehe da, es funktioniert: