SharePoint überall

SharePoint-Clientprogrammierung mit JavaScript
Kommentare

Das Fundament des Siegeszugs von JavaScript sind moderne Browser und gestiegene Ansprüche an die Benutzerfreundlichkeit von Webapplikationen. Das macht vor SharePoint nicht halt. Ob als Web Part im Kontext von SharePoint oder in Apps, mit dem Client-API oder REST-Diensten lassen sich schnell, elegant und vor allem einfach kleinere bis mittelgroße Lösungen schaffen.

JavaScript – korrekt eigentlich ECMAScript – hat sich von der kleinen Skriptsprache zu „der“ Sprache des Webs entwickelt. Kaum eine Webanwendung kommt ohne aus, und die Fälle, in denen komplexe Applikationen wie ERP oder Konfiguratoren aufs Web portiert werden, häufen sich. Dahinter steckt der Wunsch nach mehr Clientunabhängigkeit, denn Clients machen in vielen Unternehmen den Löwenanteil der Administrationskosten aus. Themen wie Sicherheit, Deployment und Wartung sind in Webumgebungen deutlich einfacher. Ebenso ist die Anbindung mobiler Geräte und Tablets nicht mit drastischen Technologiewechseln verbunden. Auf diesen Bedarf haben die Browserhersteller reagiert und bieten inzwischen stabile und schnelle Script Engines und mit HTML5 eine leistungsfähige Beschreibungssprache.Zeitgleich hat auch die Werkzeugkiste zugelegt und JavaScript lässt sich gut debuggen, testen und in verschiedenen Szenarien ausführen. Die Sprache selbst ist einigermaßen gewöhnungsbedürftig, wenn man einen Hintergrund in C# oder VB.NET hat. Hier hilft nur lernen und vor allem – ernst nehmen. Wer JavaScript belächelt und als „Kindersprache“ abtut, dann und wann mal eine kleine Lösung zusammenhackt, der wird über kurz oder lang kläglich scheitern.

Konzepte von JavaScript

Jede Programmiersprache hat bestimmte Grundprinzipien, Konzepte und Stile. Die übliche Einordnung in „objektorientiert“, „imperativ“ usw. reicht zum Verständnis nicht, zumal moderne Sprachen sich hier recht freizügig gleich mehrerer Merkmale bedienen. Die strenge Einordnung ist auch gefährlich, weil sie den Entwickler in die Irre führt. Besonders kritisch ist dies bei JavaScript, weil hier gleich mehrere Prinzipien genutzt und dann in einen sehr eigenen Stil transportiert werden.

Am auffälligsten ist dabei das Thema Vererbung. Douglas Crockford beschreibt dies sehr plakativ in seinem Artikel „The World’s Most Misunderstood Programming Language“. Er erinnert daran, dass sich die Sprache drastisch entwickelt hat und viel Falsches geschrieben wurde, auch in anerkannten Fachbüchern; das vieles obsolet ist und einige Implementierungen in Browsern schlicht so schlecht und unvollständig waren, dass das voll Potenzial der Sprache nicht hervortrat. Auch die Beschreibung des Sprachstandards selbst durch das ECMA-Komitee ist verhältnismäßig dürftig, was Implementierern das Leben unnütz schwer macht. Die einfache Erreichbarkeit durch „Amateure“ (wie Crockford es nennt) trägt auch zu einer Flut schlechter Beispiele bei. Warum also JavaScript in SharePoint nutzen? So richtig gut klingt das alles nicht.

Der aktuelle Standard von ECMAScript 5 ECMA-262, bietet vieles, was eine „echte“ Programmiersprache ausmacht. Die wichtigste Schlussfolgerung von Crockford ist, dass klassische Vererbung kein Konzept der Sprache JavaScript ist. Die angebotene prototypische Vererbung und das äußerst flexible Objektmodell bieten elegante und schnelle Konstrukte für alle Alltagsaufgaben. Im Kern basiert dies auf der allen Objekten eigenen Eigenschaft prototype. Diese bietet Vererbung und gemeinsame Eigenschaften. Listing 1 zeigt eine einfache Vererbung, basierend auf diesem Pattern.


Der Sichtbereich der Variablen (Scope) ist ein weiteres Thema, das man sehr früh lernen muss. „var oder nicht var“ ist die Frage. Und die korrekte Antwort ist: immer var. Das Schlüsselwort deklariert nicht eine Variable, sondern legt den Sichtbereich fest. Davon gibt es nur zwei: Funktion und global. Funktion ist alles innerhalb von function, global alles andere. Da sich global schwer einschätzen lässt, sollten Variablen immer in einer Funktion deklariert werden. Das führt zu typischen Pattern, wie dem Modul-Pattern (Listing 2). Das Prinzip erledigt gleich mehrere Aufgaben:

  • Es gibt private Variablen
  • Es gibt eine Art Schnittstelle, also private und öffentliche Methoden
  • Das Konstrukt kann auf mehrere Dateien aufgeteilt werden (ähnlich wie partial in C#)
var MODULE = (function (my) {
  // Privater Startwert
  var counterInitialValue = 0;
  // Private Zählvariable
  var cnt;
  // Konstruktor, öffentlich über return
  var counterConstructor = function () {
    cnt = counterInitialValue;
  };
  // vererbare Methode
  counterConstructor.prototype.increment = function () {
    cnt++;
  };
  // vererbare Methode
  counterConstructor.prototype.show = function () {
    alert(cnt);
  };
  // Öffentliche Schnittstelle
  return {
    Counter: counterConstructor
  };
// Mehr Funktionen können auf Dateien aufgeteilt sein
})(MODULE || {});
// Eine Instanz
var c = new MODULE.Counter();
c.increment();
c.increment();
c.show();
// Eine weitere Instanz
var c2 = new MODULE.Counter();
c2.increment();
// Diese Zuweisung bewirkt nichts - cnt ist privat
c2.cnt = 99;
c2.show();

Das Modul selbst ist eine Art statische oder Singleton-Klasse, es kann aber als Objekt-Factory dienen und interne Objekte anbieten. Das wird durch new auf dem Rückgabewert gemacht. Mit diesen wenigen Sprachmerkmalen – verschachtelte Funktionen, Funktions-Scope, Prototypen und ein paar knackigen Abkürzungen (wie {}, für new Object()), steht eine spannende und leistungsfähige Programmierwelt bereit. Zeit also, sich um die Nutzung in der SharePoint-Welt zu kümmern.

Dokumentations-Anti-Pattern

Der Einstieg in JavaScript-API von SharePoint sollte leicht gelingen, denn es gibt natürlich eine Referenz. Leider ist diese derart schlecht und unvollständig, dass man sogar mit gediegenen JavaScript-Kenntnissen keine ernsthafte Applikation zustande bringt. Die meisten Objekte sind überhaupt nicht beschrieben, Beispiele sind selten und Erklärungen, warum etwas existiert, hat man nicht für nötig befunden. Zudem bettet sich das API in eine Reihe anderer Programmiermodelle für SharePoint ein, die alle um die Gunst der Entwickler buhlen:

  • .NET-Framework-Clientbibliotheken
  • JavaScript
  • REST/ODATA
  • Windows Phone
  • Silverlight

Eine kurze Anleitung zur Wahl des richtigen API zeigt, dass JavaScript hier ziemlich viel abdeckt und deshalb einen näheren Blick unbedingt verdient. Konkret programmieren kann man damit:

  • Web Parts
  • ASP.NET-Webanwendungen
  • Apps für SharePoint
  • Apps für Office
  • HTML/JavaScript auf allen Betriebssystemen

Silverlight und native Smartphone-Apps eher nicht, für die Windows-Welt (Windows Phone, Silverlight) gibt es eigene Clientbibliotheken für SharePoint, und für alle anderen eignet sich REST/ODATA am besten. Allerdings kommt man hier schon ins Grübeln. Denn REST/ODATA ist mit Bibliotheken wie jQuery leicht zu programmieren, was wiederum zu JavaScript führt. Es handelt sich hier letztlich um Web Services, die nahezu alle Objekte einer SharePoint-Umgebung zugänglich machen. Warum also noch eine Clientbibliothek?

Aufmacherbild: Businessman presenting the word javascript against hologram on black background with squares von Shutterstock / Urheberrecht: wavebreakmedia

[ header = Seite 2: Alles so neu hier ]

SharePoint und JavaScript: Alles so neu hier

JavaScript ist relativ neu, und entsprechend heftig werden die Umgebungen weiterentwickelt. Das führt dazu, dass eigentlich kaum eine Bibliothek wirklich vollständig, ausgereift und umfassend dokumentiert ist. Die Eleganz, den Umfang und die Vollständigkeit von .NET kann man nicht erwarten. Man greift eher in einen übervollen Baukasten mit unterdurchschnittlichen Werkzeugen. Das ist ganz klar kein Fehler der Programmiersprache, sondern ein Mangel an Bibliotheken. Um daher einer ersten Anwendung näher zu kommen, sind einige Schritte notwendig.

Zuerst wird auf eine der bekanntesten Bibliotheken in der JavaScript-Welt zurückgegriffen – jQuery. Dies ist eine kleine und kompakte Bibliothek, die dazu dient, den Zugriff auf das Objektmodell der Seite (DOM, Document Object Model) zu erleichtern. Es lassen sich damit sehr schnell Elemente aus- oder einblenden, Daten hinzufügen oder auf Ereignisse reagieren. Bekannt geworden ist jQuery durch die vielen Effekte und Animationen, mit denen man aber sehr sparsam umgehen sollte. jQuery erleichtert auch den Abruf von Daten von Webdiensten und bildet damit eine Schnittstelle zum SharePoint. Die Erleichterung liegt nicht so sehr an weniger Code, sondern an der Abstraktionsschicht, die kleinere Unpässlichkeiten und Inkompatibilitäten der verschiedenen Browser ausgleicht.

Des Weiteren liefert SharePoint selbst Bibliotheken mit, die typische Interaktionen innerhalb einer SharePoint-Seite abwickeln. Läuft die Skriptapplikation entfernt, also nicht im Kontext von SharePoint, spielen diese kaum eine Rolle. Innerhalb von SharePoint, und damit als Ersatz für das klassische SharePoint-API, sind diese Bibliotheken ungemein wertvoll.

Her damit

Jedes Programmierprojekt beginnt mit der Einbindung der benötigten Bibliotheken. Das ist bei JavaScript nicht anders. Allerdings muss man bei der Einbindung die Situation auf dem Client beachten. Öffentliche Bibliotheken werden meist über CDN (Content Delivery Networks) verteilt, der Client lädt die Bibliothek also von einem öffentlichen Server, wobei das CDN immer dafür sorgt, dass der Server benutzt wird, der am dichtesten zum Client steht. Das setzt natürlich eine Internetverbindung voraus, was bei Intranet-Anwendungen nicht unbedingt gegeben ist. Alternativ packt man die Skripte ins Projekt und verteilt sie per Package-Modul oder Feature. Listing 3 zeigt die CDN-Version, Listing 4 ein Modul, das die Bibliotheken verteilt.


// Elements.xml

http://schemas.microsoft.com/sharepoint/">
  

// Von der Elements.xml referenziertes Benutzersteuerelement
// Standard-Direktiven wurden hier nicht abgedruckt

Die Skriptdatei selbst soll im Kontext von SharePoint laufen. Diese muss also auch verteilt werden. Wie das erfolgt, hängt von der Nutzung ab. Eine allgemeine Skriptbibliothek, die auf einer Seite mehrfach benutzt wird, soll natürlich nur einmal verteilt werden. Dazu bieten sich Delegate Controls an. Über diese Technik wird ein Benutzersteuerelement so verteilt, dass es an einer bestimmten Stelle der Seite im Master platziert wird. Im Benutzersteuerelement wird ein Script Tag benutzt, um die Skriptdateien in der richtigen Reihenfolge global zu laden.

Wird ein Web Part entwickelt, das nur einmal existiert und nur private Skripte nutzt, kann man den Code auch mit dem Web Part verteilen. Sollen die Skripte häufig oder von Anwenderseite aus ersetzt werden, bietet sich eine zentrale Ressourcenbibliothek an, aus der die Skripte geladen werden. In jedem Fall bietet es sich an, die benötigten Skripte nur bei Bedarf zu laden, beispielsweise mit dem Code aus Listing 5.

var hostweburl;

// Laden der Seite abwarten
$(function () {

    // URL ermitteln (nutzt das Plug-In "purl")
    hostweburl = $.url().param("SPHostUrl");

    // Die js-Dateien von SharePoint liegen hier:
    // web_url/_layouts/15/resource_file
    var scriptbase = hostweburl + "/_layouts/15/";

    // Asynchrones nachladen
    $.getScript(scriptbase + "SP.Runtime.js",
      function () {
        $.getScript(scriptbase + "SP.js", execOperation);
      }
    );
});

// Unser Programmcode fängt hier an:
function execOperation() {
  // z.B. Funktionen aus Listing 6:
  retrieveListItems(hostweburl);
}

[ header = Seite 3: Typische Aufgaben ]

Typische Aufgaben

Die meisten Applikationen werden mit SharePoint-Listen arbeiten. Deshalb soll hier als Beispiel der Zugriff auf eine Liste gezeigt werden. Listing 6 zeigt, wie es geht. Der Abruf erfolgt – unabhängig vom konkreten Beispiel – immer asynchron. Das API ähnelt dem von .NET. Der Einsatz von CAML erleichtert im einen oder anderen Fall die Migration. Die Vorgehensweise ist sehr einfach. Zuerst wird ein Kontext beschafft (SP.ClientContext). Dann werden die nötigen Operationen angemeldet. Sind alle eingesammelt, werden diese mit einem asynchronen Abruf abgesendet. Die Antwort enthält alle Teilelemente und wird dann zerlegt. Nun kann die Applikation darauf zugreifen. Der Vorteil dieser Architektur liegt in der Einsparung von aufeinanderfolgenden Abrufen. Es werden weniger Anforderungen abgesendet und damit Bandbreite und Zeit gespart. Hierbei gibt es keinen Clientkontext und damit keine Zusammenfassungen. Jeder Abruf erfolgt separat – asynchron bleibt es trotzdem. Generell sind asynchrone Abrufe ein absolutes Muss, denn JavaScript hat nur einen Thread und ein blockierender (synchroner) Abruf würde die Oberfläche des Browsers einfrieren lassen.

function retrieveListItems(siteUrl) {
  var clientContext = new SP.ClientContext(siteUrl);
  var oList = clientContext.get_web().get_lists().getByTitle('Ablage');
  // Ganz klassisch: CAML
  var camlQuery = new SP.CamlQuery();
  camlQuery.set_viewXml(
    '' + 
    '1' + 
    '10'
  );
  this.collListItem = oList.getItems(camlQuery);
  // asynchroner Abruf
  clientContext.load(collListItem);
  clientContext.executeQueryAsync(
    Function.createDelegate(this, this.onQuerySucceeded), 
    Function.createDelegate(this, this.onQueryFailed)
  ); 
}

function onQuerySucceeded(sender, args) {
  var listItemInfo = '';
  var listItemEnumerator = collListItem.getEnumerator();
  // Unsere Liste ‘Ablage’ enthält Title und Name    
  while (listItemEnumerator.moveNext()) {
    var oListItem = listItemEnumerator.get_current();
    listItemInfo += 'nID: ' + oListItem.get_id() + 
      'nTitel: ' + oListItem.get_item('Title') + 
      'nName: ' + oListItem.get_item('Name');
  }

  alert(listItemInfo.toString());
}
// Fehler ?
function onQueryFailed(sender, args) {
  alert('Request failed. ' + args.get_message() + 
    'n' + args.get_stackTrace());
}

Wird stattdessen mit REST/ODATA gearbeitet, sieht es etwas anders aus. REST (Representational State Transfer) hat in den letzten Jahren eine enorme Entwicklung erfahren. Als Architekturstil basiert es auf bereits etablierten Technologien und kann mit wenig Aufwand implementiert werden. Entsprechend groß ist inzwischen die Verbreitung. Gegenüber traditionellen Webdiensten mit SOAP ist es einfacher zu benutzen, braucht weniger Bandbreite und liefert bessere Performance.

ODATA kann man sich am besten als Datenzugriffs-API vorstellen – unabhängig von Betriebssystem, Clienttechnologie oder physischer Datenquelle. Es bietet ein normiertes Schema zum Ausführen von CRUD-Operationen (Create, Read, Update, Delete) auf einer Datenquelle über HTTP. Die Nutzung von HTTP ist zwingend, es werden die entsprechenden Methoden benutzt, um der Datenquelle die gewünschte Operation anzuzeigen. Gelesen wird dabei mit GET, eingefügt mit POST, geändert mit PUT (oder MERGE) und gelöscht mit DELETE. Bei PUT müssen alle Eigenschaften angegeben werden, bei MERGE nur die geänderten, und die Serverlogik sorgt dafür, dass alle nicht angegebenen Eigenschaften ihren alten Zustand behalten.

Der ODATA-Provider kann darüber hinaus diverse Filter-, Sortier- und Auswahlfunktionen umsetzen. Damit geht ein Teil der Logik auf den Client über, was der Skriptumgebung einige interessante Möglichkeiten verschafft. Auf der SharePoint-Seite läuft ein Webdienst, der das unterstützt. Der Einstiegspunkt über den Alias _api ist eine Abkürzung zum Dienst /vti_bin/client.svc: http://sharepoint/site/_api/

>REST ist ein selbstbeschreibendes Verfahren. Jeder Abruf enthält Informationen darüber, wie es in der Objekthierarchie weitergeht. Der Aufrufer entscheidet mittels MIME-Typ, welches Format gewünscht ist; zur Auswahl steht XML im AtomPub-Format und JSON (JavaScript Object Notation). Beim Abruf im Browser wird kein JSON verlangt und deshalb bekommt man XML zu sehen. In Listing 7 ist ein Skript zu sehen, das explizit JSON verlangt (MIME-Typ application/json).

var executor = new SP.RequestExecutor(appweburl);
// Asnychron REST-Daten abrufen
executor.executeAsync(
  {
   url:
      appweburl +
      "/_api/SP.AppContextSite(@target)/web/lists?@target='" +
      hostweburl + "'",
    method: "GET",
    headers: { "Accept": "application/json; odata=verbose" },
    success: successHandler,
    error: errorHandler
});

Mit dem Parameter type wird festgelegt, welche HTTP-Operation benutzt werden soll, also eine der Anweisungen GET, POST, MERGE usw. Alle möglichen Elemente finden Sie im Kasten „Elemente der REST-Abfrage“.

Elemente der REST-Abfrage Die folgenden Optionen helfen bei der Konfiguration der REST-Abfrage: • url: Endpunkt gemäß ODATA-Spezifikation • method: GET, POST, MERGE, PUT, DELETE • type: Alternative zu method X-HTTP-Method: Manche Firewalls blocken alle Methoden außer GET und POST. In solchen Fällen wird POST benutzt und der eigentlich gewünschte Wert in X-HTTP-Method verpackt. • body: Die Daten der Anfrage • data: Alternative zu body accept: Das Abfrageformat, entweder application/json;odata=verbose oder application/atom+xml content-type: Das erwartete Antwortformat, entweder application/json;odata=verbose oder application/atom+xml content-length: Die Größe der Abfrage bei POST (optional) • X-RequestDigest: Bei Abfragen per POST und außerhalb des Kontexts ein Wert, der vorher mit _spi/contextinfo beschafft wurde, um die Echtheit festzustellen • IF-MATCH: Stellt Änderungen an einem Objekt fest, steuert also den serverseitigen Cache. Mit IF-MATCH:“*“ wird die Abfrage immer erzwungen.

JSON-Objekte beim Schreiben zu erzeugen, erfordert noch einen kleinen Trick, weil die Übertragung mittels HTTP serialisiert erfolgt. Hierzu müssen alle Inhalte als Zeichenkette vorliegen. Nutzen Sie JSON.stringify(object) zur Umwandlung eines JavaScript-Objekts in die Zeichenkettenform. Listing 8 zeigt ein Beispiel, bei dem ein Eintrag in einer SharePoint-Liste erzeugt wird.

function addListItem(hostweburl) {
  // Optionen
  var options = {
    // Wir suchen eine Liste "Ablage"
    url: hostweburl + "/_api/web/lists/GetByTitle('Ablage') ",
    // Und fügen Daten ein
    method: "POST",
    // Das sind die Daten
    body: {
      // Das ist der Datentyp der Daten, siehe unten
      '__metadata': { 'type': 'SP.Data.AblageItem' },
      // Das sind die Felder und Werte
      'Title': 'Neuer Titel',
      'Name': 'Neuer Name'
    },
    // JSON soll benutzt werden
    headers: {
      "accept": "application/json;odata=verbose",
      "content-type": "application/json;odata=verbose"
    }
  };
  // jQuery’s AJAX Funktion
  $.ajax(options)
  // Asynchroner Callback bei Erfolg
  .done(function (data) {
      alert("Erfolg!");
  })
  // Asynchroner Callback bei Fehler
  .fail(function (data) {
      alert("Fehler!");
  });
}
// Der Datentyp kann so ermittelt werden:
// _api/web/lists//listItemEntityTypeFullName
// Der Wert im Beispiel war: SP.Data.AblageItem

Sicher ist sicher

Alle Beispiele zeigen JavaScript im Kontext der aktuellen Seite. Das heißt, der Benutzer hat sich mit seinen Anmeldeinformationen am SharePoint angemeldet und führt in diesem Kontext die Skripte im Browser aus. Der Browser fügt bei jeder Anforderung an den Server den Sicherheits-Token mit – egal ob es eine reguläre HTML-Seite ist oder ein per AJAX versendetes PUT. Damit unterliegen alle Anforderungen den Sicherheitseinstellungen für den angemeldeten Benutzer. JavaScript kann deshalb bedenkenlos benutzt werden, denn es hebelt keine Sicherheitseinstellungen auf dem Server aus.Wenn das Skript allerdings nicht im Kontext von SharePoint läuft, fehlt der Sicherheits-Token. SharePoint wird ohne weitere Maßnahmen solche Anfragen global zurückweisen. Zutreffend ist dieses Szenario in Cloud-basierten Anwendungen und Apps für SharePoint. In beiden Fällen muss der Zugangs-Token – eine Art Schlüssel – mittels OAUTH beschafft werden. Das setzt in der Regel eine Anmeldung bei einem Token-Dienst voraus, der als gemeinsame vertrauenswürdige Instanz zwischen der SharePoint-Website und der App läuft. SharePoint selbst bietet eine solche Instanz mit dem Secure Token Service. Ein Einstieg in das Thema ist hier und hier zu finden.

Zeig’s mir

SharePoint nutzt selbst intensiv JavaScript zur Steuerung der Benutzeroberfläche. Es ist naheliegend, hier keine eigene Lösung für Dialoge, Benachrichtigungen und Fortschrittsanzeigen zu entwickeln, sondern die vorhandenen Möglichkeiten zu nutzen. Das hat den Vorteil, dass die so erzeugten Ausgaben bestens in das Look-and-Feel der SharePoint-Anwendung passen und dem gewählten Stil (Theme) folgen. Die bereits erwähnten Standardbibliotheken sp.runtime.js und sp.js enthalten alles, was dafür benötigt wird.Recht häufig werden Benachrichtigungen (Notifications) eingesetzt. Da viele Prozesse auf den Server zurückgreifen, ohne die Seite neu zu laden (so genannte AJAX-Aufrufe), muss der Benutzer informiert werden, dass da noch etwas passiert. Unter Umständen ist es sogar sinnvoll, bei sehr schnell ablaufenden Vorgängen noch eine Meldung nachzuschieben, um dem Benutzer Rückmeldung zu geben. Nicht immer sind Änderungen an den Inhalten der Seite offensichtlich, und jede Reaktion der Anwendung gibt dem Anwender ein besseres Gefühl.

Der Aufruf der Benachrichtigung erfolgt mit der statischen Methode Notify der Klasse UI:

SP.UI.Notify.addNotification('In Arbeit...', false);

Der erste Parameter erzeugt den anzuzeigenden Text, der zweite entscheidet, ob die Meldung nach ein paar Sekunden automatisch verschwindet (false), oder bleibt, bis sie explizit entfernt wurde (true). Neben der kleinen Benachrichtigungsmeldung gibt es noch die Statusanzeige, die einen größeren Teil des Bildschirms einnimmt. Hierfür ist die Methode Status verantwortlich:


Beide Varianten gab es schon unter SharePoint 2010. Ebenso nicht neu ist die Möglichkeit, einen eigenen Dialog (Pop-up) anzuzeigen. Die Datei sp.dialog.js enthält den nötigen Code. Das Skript muss dynamisch nach dem Laden der Seite und der Basisskripte geladen werden. Listing 9 zeigt, wie das geht.


Fazit

JavaScript als Programmierumgebung ist den Kinderschuhen entwachsen, und es gelingt durchaus, ernstzunehmende Anwendungen zu schreiben. Die Integration in SharePoint 2013 ist umfassend und erfüllt fast alle Ansprüche. Wer bereits einen Hintergrund in HTML5, CSS und JavaScript hat, wird sich mit der Programmierung von SharePoint-Anwendungen deutlich leichter tun als mit dem auf .NET und COM aufbauenden API. Deutlich einfacher werden auch das Deployment, die Wartung und die Verwaltung.

Das klassische API kommt weiter für administrative Lösungen, komplexere Aufgaben, den Zugriff auf externe Datenquellen und die Integration mit anderen Produkten in Frage. Dieses API verliert also keineswegs an Bedeutung, sondern wird für Alltagsaufgaben durch eine einfacher anzuwendende Alternative ergänzt.

Unsere Redaktion empfiehlt:

Relevante Beiträge

Meinungen zu diesem Beitrag

X
- Gib Deinen Standort ein -
- or -