Communardo Software GmbH, Kleiststraße 10 a, D-01129 Dresden
+49 (0) 351/850 33-0

Sharepoint 2007: Ordner in Listen und Bibliotheken entmystifiziert

Die letzten Tage habe ich damit verbracht, mich mit den Besonderheiten(oder besser absurden Angewohnheiten) von Sharepoint 2007  zu befassen. Speziell mit dem programmatischen Anlegen von Ordnern und Unterordnern in Sharepoint Dokumenten – Bibliotheken beziehungsweise Listen.

Hier meine gesammelten Erfahrungen über das Anlegen von Ordnern in

  • Bild- und Dokumentenbibliotheken (Picture- and Documentlibrary)
  • Webseiten Bibliotheken (Pages Library)
  • Wiederverwendbare Inhalte (Reusable Content)

Bild- und Dokumentenbibliotheken (Picture- and Documentlibrary)

Angefangen hat das ganze mit dem Versuch, Unterordner in einer Bild- und Dokumentenbibliothek anzulegen. Hier stellte sich Sharepoint gutmütig. Innerhalb dieser Bibliotheken kann über das Menü (Neu /New) ein Ordner angelegt werden, in welchen später auch Inhalte gespeichert werden können.
Soll das Anlegen der Ordner programmatisch (zum Beispiel über ein Feature) erfolgen,  kann folgender Programmcode verwendet werden.

String folderList = "Bilder";
SPList spList = webContext.Lists[folderList];
String folderUrl = spList.RootFolder.ServerRelativeUrl.ToString();
SPFolderCollection foldersColl = web.GetFolder(folderUrl).SubFolders;
SPFolder newFolder = folders.Add("Unterordner");
spList.Update();

Bis hierher könnte man meinen, Sharepoint bietet dem Entwickler mit seiner API alle Möglichkeiten, Listen zu modifizieren und so zum Beispiel Ordner anzulegen.

Webseiten Bibliotheken (Pages Library)

Ich wurde jedoch eines Besseren belehrt, als ich versuchte, innerhalb der Webseiten Bibliothek (Pages Library) einen Unterordner anzulegen. Anders als in einer Bildbibliothek bietet hier das Menü nicht die Möglichkeit, einen Ordner hinzuzufügen.

Pagesfolder

Da das Menü fehlte, dachte ich mir, versuche ich es doch einfach per Programmcode. Hierzu kann der obige Code verwendet werden, indem einfach der String für die Liste auf Pages geändert wird.

String folderList = "Pages";

Pagestest

Das Ergebnis sieht wie oben angezeigt aus. Der Unterordner erscheint unterhalb der Webseiten Bibiliothek. Eigentlich das gewünschte Ergebnis … aber dieses Ergbnis hat einen Haken. Unterhalb dieses Ordners können keine Pages angelegt werden und der Unterordner hat auch keinen Menüpunkt innerhalb der GUI für das Anlegen einer Page.

Nach intensiver Recherche fand ich einen Knowledge Article von Microsoft zu diesem Thema.

http://support.microsoft.com/kb/948614/en-us
Daraus geht klar hervor, dass dieses Verhalten von Microsoft nicht unterstützt wird. Schade eigentlich.

Wiederverwendbare Inhalte (Reusable Content)

Der letzte Schritt sollte das Anlegen eines Unterordners unterhalb der Wiederverwendbaren Inhalte Bibliothek (Reusable Content) darstellen.  Da das Menü die Möglichkeit bietet, bequem einen Unterordner in dieser Liste zu erstellen, dachte ich, der Programmcode von oben sollte sehr gut dafür funktionieren … weit gefehlt. Wieder wurde ich eines Besseren belehrt. Der Code bewirkte in dieser Liste rein gar nix.

Nach einer Phase des Debuggens wurde mir klar, wie Sharepoint hier arbeitet. Anstatt einen SPFolder anzulegen, muss hier ein ein neues SPListItem angelegt werden. Der Trick an der Sache ist, diesem SPListItem den gleichen SPContentType zuzuweisen wie Sharepoint ihn verwendet, um einen Ordner anzulegen.

Wir benötigen den ContentType für Folder. Wird dieser ContentType einen SPListItem zugewiesen, erscheint dieses danach auch in der Wiederverwendbaren Inhalte Liste als Ordner und besitzt alle nötigen Menüpunkte. Der passende SPContentType kann wie folgt ermittelt werden:


SPContentTypeId contentId = new SPContentTypeId("0x0120");
SPContentTypeId listCTID = reuseList.ContentTypes.BestMatch(contentId);
SPContentType cType = reuseList.ContentTypes[listCTID];
List contentTypes = new List();
contentTypes.Add(cType);

Das Ganze habe ich anschließend in eine generische Methode verpackt, welche wie folgt aussieht:

CodeSnippet
Diese Methode legt nun ein SPListItem an, welches den Content Type Folder besitzt und auch entsprechend in der Liste angezeigt wird. Da der Ordner im Verzeichnisbaum jedoch nicht derselbe ist wie in der Liste angezeigt, muss  dieser noch umbenannt werden.  Anschließend kann dieser Ordner genauso verwendet werden, als ob er über das grafische Menü angelegt worden wäre. War doch ganz einfach… – oder?
Zum besseren Kopieren hier das Ganze nochmal als Text:

internal static void SubFolder2ReusableList(SPList reuseList, string reusableFolder)
 {
 reuseList.ContentTypesEnabled = true;
 //get the content type for the folder
 SPContentTypeId contentId = new SPContentTypeId("0x0120");
 SPContentTypeId listCTID = reuseList.ContentTypes.BestMatch(contentId);
 SPContentType cType = reuseList.ContentTypes[listCTID];
 List<SPContentType> contentTypes = new List<SPContentType>();
 contentTypes.Add(cType);

 SPListItem newListItem = reuseList.Items.Add();

 newListItem[SPBuiltInFieldId.ContentTypeId] = cType.Id;
 newListItem[SPBuiltInFieldId.Title] = reusableFolder + "_tmp";
 newListItem.Update();
 reuseList.Update();

 //get the parent folder of the SPListItem which is resident in the left tree
 //its not the same folder as listed in die detail list on the right
 using (SPWeb webContext = reuseList.ParentWeb)
 {
 SPFolder reuseFolder = webContext.GetFolder(newListItem.Url);
 try
 {
 //try to rename the folder on the left
 reuseFolder.MoveTo(reuseList.RootFolder.ServerRelativeUrl + "/" + reusableFolder);
 }
 catch (SPException)
 {
 //if the folder already exist delete it
 SPFolder toDeleteFolder = webContext.GetFolder(reuseList.RootFolder.ServerRelativeUrl + "/" + reusableFolder);
 toDeleteFolder.Delete();
 reuseFolder.MoveTo(reuseList.RootFolder.ServerRelativeUrl + "/" + reusableFolder);

 }
 //rename the _tmp SPListitem to his final name
 newListItem[SPBuiltInFieldId.Title] = reusableFolder;
 newListItem.Update();
 }
 }

1 Kommentar

Sharepoint 2007: Ordner in Listen und Bibliotheken entmystifiziert @Communardo #Techblog http://bit.ly/jQ1MV
This comment was originally posted on Twitter

Kommentar hinterlassen


Pin It on Pinterest