SharePointCommunity
Die deutschsprachige SharePoint Community mit Infos zu SharePoint - speziell SharePoint 2010 und SharePoint 2007


SharePoint 2010 Client-Objektmodell – Einführung

Nachdem ich in den vergangenen Wochen mit dem Probekapitel für unser SharePoint-Buch beschäftigt war, wird es mal wieder Zeit für einen Blog-Eintrag. Als Thema habe ich mir das Client-Objektmodell ausgesucht, das ich in mehreren Artikeln vorstellen möchte.

Das Client-Objektmodell wird mit SharePoint Foundation 2010 neu eingeführt. Mit der Technologie lassen sich Lösungen implementieren, die clientseitig auf SharePoint-Daten und -Funktionen zugreifen, wie etwa Silverlight oder JavaScript-basierte Webseiten. Anwendungen, die auf Basis des Client-Objektmodells implementiert werden, benötigen auf dem Client-PC keine zusätzliche Installation. Das Client-Objektmodell wird von SharePoint Foundation 2010 durch zwei zusätzliche Assemblies (Microsoft.SharePoint.Client.dll und Microsoft.SharePoint.Client.Runtime.dll) ausgeliefert, die zusammen mit der Anwendung auf dem Zielsystem bereitgestellt werden müssen. Der Funktionsumfang ist im Vergleich zum serverseitigen Objektmodell deutlich abgespeckt, jedoch lassen sich über das Client-Objektmodell grundlegende Aufgaben realisieren, wie zum Beispiel die Erstellung von Websitesammlungen und Liste, der Zugriff und die Manipulation von Listenelemente oder die Berechtigungen von Benutzern. Die Struktur und Notation der Klassen des Client-Objektmodells sind mit der serverseitigen Variante vergleichbar, was den Einstieg für den erfahrenen SharePoint-Entwickler deutlich einfacher macht. So repräsentiert zum Beispiel die Klasse Microsoft.SharePoint.Client.Site eine Websitesammlung (SPSiteCollection) oder Microsoft.SharePoint.Client.List eine Liste (SPList). Folgende Tabelle listet die wichtigen Klassen des Client-Objektmodells auf:

Client

Server

Microsoft.SharePoint.Client.Site

Microsoft.SharePoint.SPSite

Microsoft.SharePoint.Client.Web

Microsoft.SharePoint.SPWeb

Microsoft.SharePoint.Client.List

Microsoft.SharePoint.SPList

Microsoft.SharePoint.Client.ListItem

Microsoft.SharePoint.SPListItem

Microsoft.SharePoint.Client.Field

Microsoft.SharePoint.SPField

Microsoft.SharePoint.Client.View

Microsoft.SharePoint.SPView

Microsoft.SharePoint.Client.User

Microsoft.SharePoint.SPUser

Microsoft.SharePoint.Client.RoleAssignment

Microsoft.SharePoint.SPRoleAssignment

Microsoft.SharePoint.Client.RoleDefintion

Microsoft.SharePoint.SPRoleDefinition


Den Zugriffspunkt zur SharePoint-Umgebung liefert die DataContext-Klasse. Über den Konstruktor der Klasse wird die URL der Ziel-Webseite definiert. Der Datenkontext liefert die Möglichkeit, auf Informationen der Websitesammlung, der Listen einer Webseite oder auf Benutzerinformationen zuzugreifen. Das nachfolgende einfache Beispiel demonstriert den Zugriff die Informationen eines SharePoint Webs.

   1: ClientContext clientContext = new ClientContext("http://localhost:88");
   2:  
   3: Web web = clientContext.Web;
   4: clientContext.Load(web);
   5: clientContext.ExecuteQuery();        
   6:  
   7: Console.WriteLine("{0} ({1})", web.Title, web.Description);

Was passiert im Hintergrund?
Bei der Ausführung von clientseitigem Code wird im Hintergrund ein WCF-Service aufgerufen, der die Anfrage dann serverseitig verarbeitet und die Ergebnisse via JSON ausliefert. Abfragen gegen die SharePoint-Umgebung werden zunächst intern in CAML umgewandelt und als XML-String an den Service übermittelt. Die JSON-Rückgabe wird dann im Client-Objektmodell ausgewertet und an die Objekte der Applikation zurückgegeben.

Bei clientseitigen Aufrufen ist es besonders wichtig zu beachten, wann die Funktionsaufrufe an den Server übermittelt werden. Sollte der Service mit jedem Funktionsaufruf angesprochen werden, könnte die Performance der Anwendung sehr schnell in den Keller gehen. Daher empfiehlt es sich, die Funktionsaufrufe in einem Server Round Trip zu bündeln. Außerdem sollte zwingend auf die effiziente Abfrage von Daten geachtet werden. Sollte das Client-Programm beispielsweise Daten über nicht unterstützte LINQ-Anfragen aus einer SharePoint-Umgebung aufrufen (in diesem Fall werden die Daten clientseitig gefiltert), kann das übertragene JSON-Paket unter Umständen sehr groß werden.


Eine erste Client-Anwendung erzeugen
Zur Erstellung von clientbasierten SharePoint-Anwendungen benötigt es folgende Zutaten: SharePoint Foundation 2010, Visual Studio 2010 und die Assemblies des Client-Objektmodells. Die Assemblies Microsoft.SharePoint.Client.dll und Microsoft.SharePoint.Client.Runtime.dll werden durch die Installation von SharePoint Foundation 2010 in folgendem Verzeichnis bereitgestellt %ProgramFiles%\Common Files\Microsoft Shared\web server extensions\14\ISAPI. Sie müssen vor der Erstellung auf den Client-PC kopiert werden. Danach kann das Visual Studio-Projekt erzeugt werden. In meinem Beispiel werde ich eine einfache Konsolenanwendung implementieren. Wichtig: Das Projekt muss auf Basis des .NET Framework 3.5 generiert werden.

image

Danach müssen die zuvor auf den Client kopierten Assemblies im Projekt referenziert werden.

image

Jetzt kann die Anwendung implementiert werden.

   1: using System;
   2: using System.Collections.Generic;
   3: using System.Linq;
   4: using System.Text;
   5: using Microsoft.SharePoint.Client;
   6:  
   7: namespace ClientObjectSample01
   8: {
   9:    class Program
  10:    {
  11:       static void Main(string[] args)
  12:       {
  13:          ClientContext clientContext = new ClientContext("http://localhost:88");
  14:  
  15:          Web web = clientContext.Web;
  16:          ListCollection allLists = web.Lists;
  17:          clientContext.Load(web);
  18:          clientContext.Load(allLists);
  19:         
  20:          clientContext.ExecuteQuery();
  21:  
  22:          Console.WriteLine("{0} ({1})", web.Title, web.Description);
  23:  
  24:          foreach (List list in allLists)
  25:          {
  26:             Console.WriteLine("{0} ({1})", list.Title, list.BaseType);
  27:          }
  28:       }
  29:    }
  30: }


In der Konsolenanwendung muss der Namensraum Microsoft.SharePoint.Client referenziert werden. Hiermit werden die Klassen des Client-Objektmodells zur Verfügung gestellt. Der Zugriff auf die Zielumgebung erfolgt über die ClientContext-Klasse. Mit dem Aufruf der Methode ExecuteQuery() wird das Paket zum Server gesendet. Die Load()-Methode legt fest, welche Daten zum Client übermittelt werden sollen. Beachtet werden sollte, dass erst mit der Ausführung von ExecuteQuery() der serverseitige Aufruf instruiert wird. Die Load()-Methode teilt dem Client-Objektmodell mit, welche Objekte bei dem Aufruf geladen werden sollen. Zugegeben, dieses Beispiel ist nicht unbedingt optimal, da für das Web und die Listen sämtliche Eigenschaften geladen werden, obwohl sie in der weiteren Verarbeitung nicht benötigt werden. Leicht umgewandelt könnte das Bespiel auch so aussehen:

   1: using System;
   2: using System.Collections.Generic;
   3: using System.Linq;
   4: using System.Text;
   5: using Microsoft.SharePoint.Client;
   6:  
   7: namespace ClientObjectSample01
   8: {
   9:    class Program
  10:    {
  11:       static void Main(string[] args)
  12:       {
  13:          ClientContext clientContext = new ClientContext("http://localhost:88");
  14:  
  15:          Web web = clientContext.Web;
  16:          ListCollection allLists = web.Lists;
  17:  
  18:          clientContext.Load(web,
  19:             w => w.Title,
  20:             w => w.Description);
  21:  
  22:          clientContext.Load(allLists,
  23:             lists => lists.Include(
  24:               list => list.Title,
  25:               list => list.BaseType));         
  26:          clientContext.ExecuteQuery();
  27:  
  28:          Console.WriteLine("{0} ({1})", web.Title, web.Description);
  29:          foreach (List list in allLists)
  30:          {
  31:             Console.WriteLine("{0} ({1})", list.Title, list.BaseType);
  32:          }
  33:       }
  34:    }
  35: }

Mittels eines Lambda-Ausdrucks werden in diesem Aufruf die von dem JSON-Packet zurückzuliefernden Eigenschaften eingegrenzt und der Load()-Methode als Parameter übergeben. Durch dieses Verfahren ist der clientseitige Zugriff deutlich performanter als im vorherigen Beispiel, da nur die verwendeten Eigenschaften im Paket übermittelt werden. Sollte der Code auf eine andere als hier definierte Eigenschaft zugreifen, wird eine Ausnahme vom Typ SharePoint.Client.PropertyOrFieldNotInitializedException geworfen.

Hinweis: Auf optimierte Abfragen und Lambda-Ausdrücke im Client-Objektmodell werde ich in einem weiteren Artikel näher eingehen.

Der deutlichste Unterschied im Vergleich zum serverseitigen Objektmodell ist der Zugriffszeitpunkt auf die SharePoint-Plattform bzw. auf die Datenbank. Wo im SharePoint-Objektmodell die Daten direkt in die Objekte geladen und weiterverarbeitet werden können, werden im clientseitigen Objektmodell die Daten erst mit der Ausführung von ExecuteQuery() den internen Objekten zur Verfügung gestellt. Dieses Verfahren ermöglicht es dem Entwickler mehrere Objektaufrufe in einer Serveranfrage zu verpacken und damit die Round Trip zum Server deutlich zu minimieren.

Im nächsten Teil dieser Artikelserie werde ich eine Reihe von Anwendungsbeispiel vorstellen. Dazu gehören zum Beispiel CAML-Abfragen, die Manipulation von Daten oder die Berechtigung von Benutzern. Im dritten Teil werde ich auf die Optimierung von Client-Anwendungen eingehen.


Bereitgestellt 1 Feb 2010 7:47 von Fabian Moritz

Kommentare

Tobias geschrieben re: SharePoint 2010 Client-Objektmodell – Einführung
on 1 Feb 2010 15:38

Guter Beitrag. Danke!

Alexander Brütt geschrieben re: SharePoint 2010 Client-Objektmodell – Einführung
on 2 Feb 2010 12:41

Tolle Einführung, ich freu mich auf den 2. Teil.

Kann man im Rahmen der Client API mit Linq2SharePoint arbeiten?

Grüße,

Alex

Fabian Moritz geschrieben re: SharePoint 2010 Client-Objektmodell – Einführung
on 12 Feb 2010 8:07

Hallo Alex,

ja, das funktioniert erstaunlicher Weise auch. Der zweite Teil kommt am Wochenende...

Fabian

Kommentieren

(erforderlich)
(optional)
(erforderlich)  
Erinnern Sie sich an mich?