SharePoint Object Model  Udostępnij na: Facebook

Autor: Jakub Gutkowski

Opublikowano: 2011-08-08

Chciałbym móc powiedzieć, że model obiektowy SharePoint przeszedł długą drogę, udostępniając nam coraz lepsze, zgrabniejsze API, abyśmy mogli tworzyć rozwiązania szybciej i sprawniej. Niestety, SharePoint przeszedł długą drogę, ale przy tym niczego się nie ucząc, i nie próbując rozwiązać problemów, które jak dręczyły, tak i dalej dręczą programistów. Powiedziałbym, że nawet utrudnił komunikację pomiędzy biznesem a programistami, wprowadzając nowe nazewnictwo w dokumentacji, zaś pozostawiając stare w kodzie – „aby był kompatybilny”.

Tak było do wersji 2007, kiedy to pod ładną przykrywką UI dostaliśmy to samo, co było  – z nowymi problemami i z nowymi funkcjami. O wersji 2010 moglibyśmy prawie powiedzieć to samo – nowe UI, stary model obiektowy – jednak nastąpiła pewna znacząca zmiana. Microsoft uświadomił sobie, że coraz więcej ludzi nie chce korzystać z tak zwanego Server Object Model, a chciałaby z poziomu Silverlight czy też aplikacji okienkowej odpytać SharePoint o elementy, czy też nawet nimi zarządzać.

To zmieniło trochę podejście, które zaowocowało powstaniem modelu obiektowego dla aplikacji klienckich – zarówno kodu zarządzanego (.NET), jak i JavaScript. Dzięki czemu możemy teraz, nie męcząc się, poprzez WebServicy i XMLele odwoływać się prawie bezpośrednio do SharePointa z miejsc, w którym wcześniej powstawały całe artykuły nt. jak tego dokonałem i dlaczego odradzam.

Przypatrzmy się temu, co jest dostępne, opisując po kolei ogólnie modele obiektowe, a następnie prezentując przykłady, które można je wykorzystać w życiu codziennym.

Server Object Model

Jeżeli pracowaliśmy wcześniej z Server OM, to raczej nie zobaczymy znaczących zmian – nowe metody, parametry, własności, jednak ogólna zasada komunikacji z SharePoint pozostaje taka sama i niezmieniona. Czasami widać małe usprawnienia, jednak ze względu na kompatybilność wstecz, wciąż mamy dostępne prawie wszystkie stare metody.

Jeżeli jesteśmy nowi i wcześniej nie bawiliśmy się SharePointem, to warto tutaj wspomnieć o kilku rzeczach.

Microsoft.SharePoint.dll

Biblioteka Microsoft.SharePoint.dll jest podstawową biblioteką, z jaką będziemy współpracować – zawiera ona zbiór podstawowych klas i metod umożliwiający nam dostęp zarówno do stron, jak i witryn. Biblioteka ta znajduje się w katalogu powszechnie zwanym VERSION HIVE/ISAPI, gdzie VERSION to numer wersji SharePointa. W przypadku SharePoint 2007 jest to 12 HIVE, zaś w przypadku SharePoint 2010 jest to 14 HIVE.

Microsoft.SharePoint.dll dla SharePoint 2007 znajduje się w katalogu:

%ProgramFiles%\Common Files\Microsoft Shared\web server extensions\12\ISAPI

Zaś dla SharePoint 2010 w katalogu:

%ProgramFiles%\Common Files\Microsoft Shared\web server extensions\14\ISAPI

Uwaga. Czasami mogę odnosić się do biblioteki Microsoft.SharePoint.dll poprzez sformułowania takie jak biblioteka SharePoint, domyślna biblioteka itp. Tak naprawdę nie ma dużo bibliotek, z którymi będziemy współpracować, a każda inna, ma znaczącą różnicę w nazwie, jak chociażby Microsoft.SharePoint.Client.dll, do której mogę się odwoływać jako do biblioteki klienckiej SharePoint. Czasami zaś będę pomijał całkowicie część Microsoft.SharePoint w nazwie biblioteki.

64 Bit

To, że SPS jest 64-bitowy, prowadzi do pewnych problemów przy pisaniu rozwiązań z wykorzystaniem Visual Studio 2010. W Visual Studio 2008 domyślnie dla projektu była ustawiona konfiguracja buildu na Any CPU, co dawało możliwość uruchomienia kodu zarówno na 32-bitowym, jaki 64-bitowym systemie. W Visual Studio 2010 domyślna konfiguracja buildu jest uzależniona od typu projektu i raz może ona być x86 (32 bit), a raz Any CPU. Warto o tym pamiętać, aby przy każdym tworzeniu nowego projektu – na przykład Console Application – upewnić się, iż nasza konfiguracja build jest ustawiona na Any CPU lub x64 (64 bit), gdyż inaczej przy jakiejkolwiek próbie odwołania się do SharePointa dostaniemy bardzo mało mówiący błąd FileNotFoundException wskazujący na błędny adres URL. Jest to oczywiście nieprawdą – w większości przypadków.

Jeżeli nie chcemy o tym pamiętać, to możemy wykorzystać rozszerzenie CKS Dev dla SharePoint (http://bit.ly/gXFJQM), które instaluje nam szablon projektu Console Application ustawiający wszystkie niezbędne parametry.

.NET 3.5 SP1

SharePoint 2010 został skompilowany pod .NET 3.5 SP1, co ogólnie prowadzi do tego, że w SharePoint 2010 nie da się programować w .NET Framework 4.0 – przez co także nie mamy dostępu zarówno do nowych funkcji języka, bibliotek (nowe aktywności Workflow Foundation), jak i całego CLR.

Warto też wspomnieć, że od .NET 3.5 SP1 istnieje .NET Framework w postaci Client Profile, który ogólnie jest wersją okrojoną pełnej wersji framework. Visual Studio 2010 przy domyślnych ustawieniach utworzy nam projekt Console Application w Client Profile dla .NET 4.0. – można to zmienić przy tworzeniu projektu i ustawić .NET 3.5, w tym momencie Client Profile nie zostanie wybrany, zaś nasz projekt będzie kompilował się pod .NET 3.5.

Problem z Client Profile jest dość istotny, gdyż SharePoint wykorzystuje biblioteki niezawarte w pakiecie Client Profile, przez co – mimo poprawnego dodania referencji do biblioteki SharePoint – nasz kod może nam się nie kompilować.

Nazewnictwo

Większość obiektów SharePoint zawiera przedrostek SP (np.  SPSite, SPEventReceiver), można więc dość łatwo odróżnić klasy pochodzące z biblioteki SharePoint od klas pochodzących z innych bibliotek.

Jeżeli jeszcze nie współpracowaliśmy z biblioteką SharePoint, to przy nazewnictwie warto jeszcze wspomnieć, że Microsoft w wersji SharePoint 2007 wprowadził nowe słownictwo do dokumentacji, pozostawiając stare wciąż w API. Była szansa, że to ulegnie zmianie w SharePoint 2010, jednak tak się nie stało. Problem polega na tym, iż to, co nazywane jest w dokumentacji Site Collection, w kodzie jest SPSite, zaś to, co się nazywa Site, w kodzie prezentowane jest przez SPWeb. Aby było zabawniej, Site Collection w kodzie możemy stworzyć poprzez klasę SPSiteCollection, zaś aby móc stworzyć Site Collection, potrzebujemy SPWebApplciation. Przyznaję, że sam nieco się w tym gubię, dlatego używam starego nazewnictwa, które do mnie lepiej przemawia:

  • Site Collectiton  – nazywam stroną, site lub SPSite i tak też będę się do tego odwoływał w artykułach;
  • Site – nazywam witryną, web lub SPWeb i tak też będę się do tego odwoływał w artykułach.

Jeżeli w dalszej części artykułu zaczniecie się gubić z nazewnictwem, polecam wrócić do tego punktu.

LINQ

Odkąd SharePoint istnieje, zawsze był problem z modelem obiektowym. Aby dostać się do listy, należy podać jej nazwę, czasami trzeba zrobić encode  na ciągu stringów, by nazwa odpowiadała tej, którą SharePoint trzyma u siebie w bazie danych (np. spacjato _x0020_). Na temat „jak mapować i jakie rozwiązanie jest najlepsze” powstawało zarówno wiele teorii, jak i praktyk (na przykład tutaj: http://bit.ly/bqT9fm możecie znaleźć listę różnych typów mapowania modelu obiektowego SharePoint na statycznie typowany model obiektowy), jednak to, jak ktoś mapował, zależało zarówno od niego, jak i specyfiki projektu.

Microsoft wraz z SharePoint 2010 wypuścił bibliotekę umożliwiającą nam nie tylko mapowanie informacji z witryny na obiekt, ale także tworzenie zapytań LINQ oraz ogólnie całej pracy z modelem obiektowym – wstawianie elementów do list itp.

LINQ jest możliwe dzięki bibliotece Microsoft.SharePoint.Linq.dll oraz aplikacji command line spmetal znajdującej się w katalogu 14 HIVE/BIN. Aplikacja spmetal służy do wygenerowania klas, w zależności od list dostępnych na witrynie. Tak wygenerowany plik dodajemy do projektu i możemy zacząć korzystać zarówno z LINQ Provider, jak i ogólnie ze statycznie typowanego modelu – zamiast odwoływać się do wartości na liście poprzez listItem["Title"] możemy po prostu napisać listItem.Title – to naprawdę znacznie ułatwia pracę i umożliwia wykrycie problemów w trakcie kompilacji, a nie w trakcie uruchomienia aplikacji.

Jako że temat LINQ jest dość obszerny, nie będziemy się nim dalej zajmować w tym artykule. Jeżeli ciekawi was, jak można dodać LINQ do projektu, zachęcam do przeczytania tego krótkiego wpisu: http://bit.ly/fmcsEb, zaś więcej informacji o LINQ w SharePoint można znaleźć tutaj: http://bit.ly/dWDs9G.

Praca tylko po stronie serwera

Server object model wziął swoją nazwę stąd, że nie działa on na innym komputerze, niż komputer z zainstalowanym SharePoint. Jest to spowodowane bezpośrednim odwołaniem zarówno do rejestru, jak i do obiektów COM poprzez bibliotekę SharePoint. Jeżeli więc wpisy w rejestrze czy obiekty COM nie istnieją, biblioteka zwraca błąd, nie mówiący jednak, że „brak instancji SharePointa”, a przeważnie kompletnie niezwiązany z problemem, np. FileNotFoundException z opisem, że strona o podanym adresie URL nie istnieje.

Ciekawostka do weryfikacji. Jeżeli mamy dwie instancje SharePoint na dwóch różnych komputerach, to serwerowy model obiektowy nie pozwoli nam odwołać się do instancji SharePoint na innym komputerze głównie z tego powodu, że rejestr na komputerze, z którego próbujemy się podłączyć, zawiera ścieżki zarówno do plików, jak i do baz danych, które są wykorzystywane przez SharePoint. Bawiąc się pewnie rejestrem, moglibyśmy odwołać się do SharePoint na innym komputerze, jednak są to tylko i wyłącznie czyste spekulacje (jeśli jednak koniecznie będziecie chcieli to sprawdzić, chętnie usłyszę/przeczytam o tym).