Donnerstag, 12. März 2009

Mit SPQuery nach Items in DocumentLibrary suchen

Eine Anforderung, die es gestern umzusetzen galt, bestand darin, nach Items (in diesem speziellen Falle Subfoldern) in einer DocumentLibrary zu suchen und diesen Wert einem speziellen Lookup-Feld als Standardauswahl anzugeben. Die normale SPQuery-Abfrage sucht leider nur auf der obersten Ebene. Abhilfe schafft hier das ViewAttribute Scope="RecursiveAll". Dieses sucht rekursiv in der DocumentLibrary und zwar nach allem, also Dokumenten und Foldern.

Die Code-Abfrage lautet dann so:


SPFieldLookup spFieldLookup = (SPFieldLookup)spListItem.Fields[property];
SPList spLookupList = spListItem.Web.Lists[new Guid(spFieldLookup.LookupList)];

SPQuery query = String.Format("{1}", spLookupFieldName, value);
query.ViewAttributes += " Scope=\"RecursiveAll\"";
SPListItemCollection results = spLookupList.GetItems(query);


spListItem und property sind das SPListItem welches ich updaten möchte und der Name des Lookup-Feldes, welches benutzt werden soll. value ist der Foldername, nach dem gesucht werden soll.

Mehr zum dem Attribut "Scope" gibt es auf http://msdn.microsoft.com/en-us/library/ms438338.aspx.

Montag, 2. März 2009

Gruppen in Quicklaunch-Navigation eintragen

Einer der Unterschiede von programmatisch angelegten Benutzergruppen zu denen, die über die Oberfläche erzeugt wurden, ist der, dass letztere in der Quicklaunch-Navigation angezeigt werden, erstere aber nicht.

Witzigerweise stehen diese Gruppen auch nicht per Default zur Verfügung, wenn man in "All People" versucht, einen Benutzer gleich einer Gruppe hinzuzufügen.

Abhilfe schafft hier das Property "vti_associategroups" vom Rootweb, dem man semikolonsepariert die IDs der Benutzergruppen zuweisen muss:


List quickLaunchGroupIDs = new List();
...
// create a new spGroup here and add its ID to the list
quickLaunchGroupIDs.Add(spGroup.ID.ToString());

rootWeb.AllProperties["vti_associategroups"] = string.Join(";", quickLaunchGroupIDs.ToArray());

rootWeb.Update();

Mittwoch, 18. Februar 2009

Formeln für berechnete Felder (calculated fields)

Mal ein interessanter Link zwischendurch: auf dieser Website werden sehr übersichtlich und mit Beispielen versehen die Formeln angezeigt, die in berechneten Feldern verwendet werden dürfen: http://www.gothamweb.com/support/manual/wsshelp/html/EgForm.htm http://camp.gob.mx/_vti_bin/help/1033/sts/html/EgForm.htm

Viele dieser Formeln lassen z.B. Feldmanipulationen auf EventReceiver-Seite überflüssig werden.

Mittwoch, 21. Januar 2009

"Insufficient memory to continue the execution of the program" und "System.OutOfMemoryException" bei Upload in eine Dokumentbibliothek

Im Moment arbeite ich an dem Projekt zur Migration der Daten aus einem Livelink- in ein SharePoint-System. Eine der Herausforderungen ist das Migrieren einer vorhandenen Dateistruktur - bestehend aus Foldern, Dokumenten (mit mehreren Versionen) und URLs - in eine Dokumentbibliothek.

Neben der Tatsache, dass SharePoint stark begrenzte Vorgaben was die Maximallänge von Datei- und Verzeichnisnamen sowie deren Syntax betrifft - dazu vielleicht in einem anderen Post einmal mehr -, gibt es auch das Problem, dass Dateien nicht beliebig groß sein dürfen.

In der Zentraladministration unter Application Management > Web Application General Settings die Einstellung Maximum Upload Size. Standardmäßig sollten dort 50 MB eingestellt sein.

Laut Microsoft kann man nun Dateien von einer Umgebung in eine Dokumentenbibliothek laden mittels diesen Codes:


FileStream fStream = File.OpenRead(srcUrl);
byte[] contents = new byte[fStream.Length];
fStream.Read(contents, 0, (int)fStream.Length);
fStream.Close();

EnsureParentFolder(site, destUrl);
site.Files.Add(destUrl, contents);


Das funktioniert auch wunderbar. Wird versucht, eine Datei hochzuladen, die größer ist als die eingestellte Maximum Upload Size wirft SharePoint eine Exception, die auch aussagt, dass das File Size Limit Exceeded ist.

Eine weitere Projektanforderung besagt, dass Dokumente bis 200 MB hochgeladen werden sollen. Also erhöhte ich den Wert in der ZA. Das funktionierte eine Zeit lang auch ganz gut aber irgendwann tauchten solche Fehlermeldungen auf:

Insufficient memory to continue the execution of the program.
at Microsoft.SharePoint.Library.SPRequestInternalClass.PutFile(String bstrUrl, String bstrWebRelativeUrl, Object varFile, PutFileOpt PutFileOpt, String bstrCreatedBy, String bstrModifiedBy, Int32 iCreatedByID, Int32 iModifiedByID, Object varTimeCreated, Object varTimeLastModified, Object varProperties, String bstrCheckinComment, UInt32& pdwVirusCheckStatus, String& pVirusCheckMessage)
at Microsoft.SharePoint.Library.SPRequest.PutFile(String bstrUrl, String bstrWebRelativeUrl, Object varFile, PutFileOpt PutFileOpt, String bstrCreatedBy, String bstrModifiedBy, Int32 iCreatedByID, Int32 iModifiedByID, Object varTimeCreated, Object varTimeLastModified, Object varProperties, String bstrCheckinComment, UInt32& pdwVirusCheckStatus, String& pVirusCheckMessage)
at Microsoft.SharePoint.SPFileCollection.AddInternal(String urlOfFile, Object file, PutFileOpt fileOpt, String createdBy, String modifiedBy, Int32 createdByID, Int32 modifiedByID, DateTime timeCreated, DateTime timeLastModified, Object varProperties, String checkInComment, SPVirusCheckStatus& virusCheckStatus, String& virusCheckMessage)
at Microsoft.SharePoint.SPFileCollection.Add(String urlOfFile, Byte[] file, SPUser createdBy, SPUser modifiedBy, DateTime timeCreated, DateTime timeLastModified)...


Und zwar genau in der Codezeile, in der der SPFileCollection mit der Methode .add die neue Datei hinzugefügt werden sollte.

Die Irritation war groß zumal laut der oben verlinkten MSDN-Seite und dem dort vorgegebenen Code Dateigrößen bis 2 GB möglich sein sollten.

Ein paar Zeilen tiefer in meinem Logfile fand sich auch diese Fehlermeldung:

Exception of type 'System.OutOfMemoryException' was thrown.

Und zwar in der Codezeile, in der das Bytearray deklariert wurde:

byte[] contents = new byte[fStream.Length];

Das Problem an dieser Stelle ist ausnahmsweise mal nicht SharePoint sondern das Betriebssystem, bzw. .net. Anscheinend sind Byte-Arrays jenseits der ~100 MB-Grenze zu groß für den Speicher sodass es zu den oben genannten Fehlermeldungen kommt.

Glücklicherweise, und das verschweigt die MSDN in ihrem Artikel voll und ganz, kann als zweiter Parameter in der SPFileCollection.add-Methode anstelle eines Byte-Arrays auch ein Stream benutzt werden:


FileStream fStream = File.OpenRead(fileToUpload);
spFile = spFileCollection.Add(newDocumentName, fStream, fileCreator, fileModifier, DateTime.Parse(fileCreated), DateTime.Parse(fileModified));
fStream.Close();


Durch diese Methode wird nicht nur der Speicher geschont sondern werden auch weniger Codezeilen benötigt.

Freitag, 12. Dezember 2008

Fehler beim Anlegen eines Folders in einer Dokumentenbibliothek

Einen sehr merkwürdigen Fehler habe ich bei unserem aktuellen Projekt - einer Migration von Livelink nach SharePoint - entdeckt und gelöst.

Hier werden u.a. programmatisch Folder und Dokumente in einer Dokumentenbibliothek angelegt aber ab und zu taucht diese Fehlermeldung auf:

The filename, directory name, or volume label syntax is incorrect. (Exception from HRESULT: 0x8007007B)

Der Name des anzulegenden Folders war "1_ERF ", beinhaltete also keine Zeichen, die SharePoint kategorisch ablehnt (wie z.B. & # % * usw.). Über die Oberfläche war der Folder ebenfalls problemlos anlegbar.
Daraufhin versuchte ich noch einmal den Folder programmatisch anzulegen. Diesmal ohne das Leerzeichen am Ende und siehe da, plötzlich funktionierte es problemlos.

Fazit: Beim programmatischen Anlegen von Foldern in einer Dokumentenbibliothek am besten immer ein .TrimEnd() oder .Trim() an den Folder-Namen hängen.

Montag, 1. Dezember 2008

Michael Greth auf dem 3. Treffen der regionalen SharePoint User Gruppe

Vgl: Consultants Digest

Ich freue mich, an dieser Stelle verkünden zu können, dass Michael Greth, einer der SharePoint Evangelisten in Deutschland und Microsoft MVP, am 15.01.2008 zum dritten Treffen der regionalen SharePoint User Gruppe Nürnberg kommen wird, um dort über das Podcasting Kit zu sprechen.

Der Termin wird am 15.01.2008 wieder bei der Spirit Link Technology in Erlangen stattfinden.

Anmeldung und weitere Informationen zu dem Termin und der User Gruppe finden Sie unter:

Xing Termin: https://www.xing.com/app/events?op=detail;id=281380;from=home

User Gruppe: https://www.xing.com/net/spusergroupnbg/

Spirit Link Technology: www.spiritlink-technology.de

Ich würde mich freuen auch den einen oder anderen Blog Leser dort zu diesem sicher spannenden Termin begrüßen zu dürfen.

Montag, 24. November 2008

2. Treffen der regionalen SharePoint User Gruppe

Vgl: Consultants Digest

An dieser Stelle möchte ich einen kurzen Rückblick auf das letzte Treffen der regionalen User Gruppe geben.

Am 20.11.2008 haben sich ca. 20 Fachanwender und Softwarespezialisten bei der Spirit Link Technology eingefunden, um in gemütlicher Runde über SharePoint und andere Themen zu plaudern.

Thematisch stand der Abend im Zeichen von Livelink Migration nach SharePoint und Business Intelligence mit SQL Server Reporting Service im SharePoint Kontext.

Nach einer kurzen Einleitung hat Andras Molnar über ein laufendes Projekt der Spirit Link Technology gesprochen, in dem es um die Migration von 160.000 Dokumenten eines bestehenden Knowledge Sharing Systems auf Livelink Basis in eine SharePoint Umgebung geht.

Schwerpunkte des Vortrages waren:

  • Generelles Migrationsvorgehen
  • Evaluation von Migrationstools
  • Problemkreise der Migration
    • Livelink Aliase
    • Pfadlängen
    • Dokumentengrößen
    • Versionierungen
  • Detailierte Problemlösung
  • Migrationsdauer und User Interaction

Im Anschluss an den Vortrag von Andras Molnar hat Sebastian Gerling zum Thema Business Intelligence Ansätze im Microsoft SharePoint Umfeld angesprochen. Nach einer kurzen theoretischen Einleitung wurde anhand von Screencasts und Live Demos das Vorgehen der Erstellung eines funktionsfähigen in SharePoint implementierten Berichtes von dem Aufbau der SQL Server Tabellen über die Erstellung des Berichtes in SQL Server Reporting Services bis hin zur Implementierung in ein SharePoint Berichtszentrum gezeigt.

Schwerpunkte des Vortrags waren:

  • SQL Server Integration Services (SSIS)
  • SQL Server Analysis Services (SSAS)
  • SQL Server Reporting Services (SSRS)
    • Berichtserstellung in Visual Studio
    • Modifizierung von Berichtselementen
    • Bedingte Formatierungen und der Umgang mit Ausdrücken
  • Voraussetzung für die Implementierung von SRSS Reports in SharePoint
  • Vorgehen beim Implementieren
    • Data Connection
    • Single Item Security

Diesen Vortrag und die Screencasts werden Sie in Kürze auch hier auf dem Blog zu finden sein.

Im Anschluss an die Vorträge wurden offene Fragen diskutiert und in gemütlicher Runde bei Bier und Brötchen der Abend ausklingen gelassen.

Weiter Informationen rund um die User Gruppe und die Teilnehmer finden Sie unter:

https://www.xing.com/net/spusergroupnbg/