Liebe Leser, in diesem Bereich finden Sie Tipps und Tricks rund um die Microsoft Sharepoint Technologie.

19Jun

Um in Sharepoint anfragen auf eigene ASPX Seiten umzuleiten, besteht die Möglichkeit dies durch die Verwendung eines „IHttpModules“ zu realisieren. Das Modul greift spezifische Anfragen auf definierte Seiten ab und leitet diese auf definierte Seiten um.

Hier der Code, um eine Anfrage auf die CreateWebPage.aspx auf die MyPage.aspx umzuleiten:

pic1

Die Verwendung des IHttpModule, welches durch einen Eintrag in die „web.config“ realisiert wird, kann über ein Feature mit Hilfe des SPWebConfigModification Objektes erreicht werden. Diese Feature setzt und löscht automatisch den notwendigen Eintrag in der „web.config“.

Hier der Beispielcode um das oben gezeigte IHttpModule anzubinden:

pic2

pic3

Wichtig: Um auch die “Remove” Methode korrekt ausführen zu können, müssen die Eigenschaften des SPWebConfigModification Objektes richtig gewählt werden.

1. Die Eigenschaft “EnsureChildNote” muss angewandt werden, da mit der EnsureSection eine spätere “Remove” Methode keine Auswirkung liefert.

mod.Type = SPWebConfigModification.SPWebConfigModificationType.EnsureChildNode;

2. Der “mod.Name” muss entsprechend der “mod.Values” angepasst werden. Wird der Name des Objektes willkürlich gewählt, ist die Funktionalität der “Add” Methode gewährleistet, doch wird die Funktionalität der “Remove” Methode kein Resultat liefern.

entryvalue = @”<add name=”"IHttpModule”" type=”"namespace.class, assembly, Version=1.0.0.0, Culture=neutral, PublicKeyToken=…”" />”;

Der Angepasste “mod.Name” muss dann folgend lauten:

entryname = “add[@name='IHttpModule'][@type='namespace.class, assembly, Version=1.0.0.0, Culture=neutral, PublicKeyToken=...]“;

Hier nun noch der Inhalt der “feature.xml”. Zu beachten ist, dass der Scope auf der WebApplication liegen muss.

pic4

Links zum Thema:

http://blogs.technet.com/tatianasv/rss_tag_SharePoint+development.xml

http://msdn.microsoft.com/en-us/library/microsoft.sharepoint.administration.spwebconfigmodification.aspx

http://blog.tedpattison.net/Lists/Posts/Post.aspx?ID=4

MFG Gordon

Technorati Tags: ,

21Dez

In verschiedenen Anwendungsfällen kann es vorkommen, dass eine Liste mit den dazugehörigen Einträgen dem Nutzer der Site verborgen bleiben soll. Trotzdem muss der Nutzer einen Workflow mit Instantiation-Form starten können und ein entsprechendes Listenelement anlegen können. Für diesen Beitrag wird von einem vorhandenen Infopath-Formular ausgegangen, welches als Instantiation-Form verwendet wird.

Hier die Schritt-für-Schritt-Anleitung:

1. ASPX-Seite oder Webpart zum Anlegen des List-Items
Zum Anlegen des List-Items, für den der Workflow gestartet werden soll, kann ein einfaches ASPX-Formular oder ein Webpart zum Einsatz kommen. Dem Formular muss als Parameter die Listen-ID mitgegeben werden.

2. Anlegen der Eingabefelder für das Listenelement
Das ASPX-Formular sollte nun alle Datenfelder abfragen und ein neues Listenelement mit entsprechenden Werten anlegen. Dies muss unbedingt mit erhöhten Privilegien geschehen:

SPSecurity.RunWithElevatedPrivileges(delegate()

{

    using (SPSite site = new SPSite(web.Site.ID))

    {

    // implementation details omitted

    }

});

Zu beachten ist, dass keine Kontext-Objekte (SPContext) verwendet werden dürfen, da diese mit den Rechten des aktuellen Nutzers laufen.

3. Weiterleitung zum Instatiation-Form
Nachdem das Item angelegt wurde (Update nicht vergessen), kann der Workflow gestartet werden. Voraussetzung ist, dass dieser bereits mit der Liste verknüpft ist und neue Instanzen gestartet werden dürfen. Der Aufruf des Instantiation-Form erfolgt mittels Response.Redirect. Folgende Url muss übergeben werden:

"_layouts/IniWrkflIP.aspx?List=<listID>&ID=<itemID>&TemplateID=<WFAID>&Source=<webUrl>"

Folgende Parameter müssen ersetzt werden:
<listID> - ID der Liste (siehe 1.)
<itemID> - ID des soeben erzeugten Items (siehe 2.)
<WFAID> - ID der WorkflowAssoziation (diese hängt an der Liste)
<webUrl> - Url an die weitergeleitet wird, nachdem der Workflow gestartet wurde

Den Rest erledigen Infopath und die aufgerufene ASPX-Datei.


19Dez

Mit den Visual-Studio-Erweiterungen für Sharepoint wird der Entwickler schon sehr gut beim Deployment auf seinem Entwicklungssystem unterstützt. Ein Nachteil ist jedoch, dass der Deployment-Prozess recht lang dauert. Der Grund ist, dass der Workflow in eine Solution verpackt und deployed wird.

Um das Deployment während der Entwicklung zu beschleunigen, kann direkt nach dem Build eine Batch-Datei ausgeführt werden, die diese Aufgabe übernimmt. Post-build events werden direkt in den Projekteigenschaften unter “Build Events” konfiguriert. Um eine Batch-Datei aufzurufen ist folgender Befehl notwendig:

call “$(ProjectDir)\PostBuildEvent.bat”

Um die Batch-Datei möglichst generisch zu gestalten stehen diverse Makros zur Verfügung, die als Parameter übergeben werden können.

Folgende Aktionen sind per Batch auszuführen:

  1. Assembly zum GAC hinzufügen mittels GACUtil
  2. Kopieren von Dateien in den 12-Ordner von Sharepoint
  3. Kopieren von Dateien direkt in die Sharepoint-Datenbank. Dies kann mittels UNC-Pfad geschehen. Bsp: \\server\website1\documents
  4. Deaktivieren des Features
  5. Deinstallieren des Features
  6. Installieren des Features
  7. Aktivieren des Features
  8. IISRESET

Sollte es nur ein Webpart sein, können die Punkte 4-7 ausgelassen werden. Alternativ kann die DLL auch ins BIN-Verzeichnis von Sharepoint kopiert werden, anstatt sie im GAC zu deployen. Die Verzeichnisse können mittels Umgebungsvariablen und der oben bereits erwähnten Makros systemunabhängig ermittelt werden. Mit dem eigenen Deployment lässt sich während der Entwicklung viel Zeit sparen…


20Nov

Dieser Blogeintrag stellt eine Deployment-Variante für Sharepoint-Enwicklungen, wie z.B. WebParts oder Workflows, vor. Im Mittelpunkt stehen zwei Open-Source-Tools zur Erstellung und zum Deployment von Sharepoint Solutions.

Zuerst werde ich jedoch kurz beispielhaft die manuelle Vorgehensweise vorstellen: Ausgangspunkt ist ein Sharepoint-Workflow, der mit Visual Studio entwickelt wurde. Auf dem Entwicklersystem geschieht das Deployment mittels des Visual Studio-Plugins vollautomatisch. Soll der Workflow nun auf einem fremden System deployed werden, sind eine Reihe von Schritten notwendig:

  1. Compilieren des Projekts
  2. Kopieren/Installieren der Assembly auf das Zielsystem
  3. Kopieren der Feature-Dateien auf das Zielsystem
  4. Ggf. Deaktivieren/Deinstallieren des vorhandenen Features
  5. Installieren/Aktivieren des Features auf dem Zielsystem
  6. IISRESET

Die einzelnen Schritte lassen sich durchaus scripten, aber eine einfache und elegante Deployment-Möglichkeit wird dadurch nicht geschaffen. Abhilfe schaffen hier zwei Open-Source-Tools: WSPBuilder und SharepointInstaller.

Der WSPBuilder erstellt aus einer vorgegebenen Struktur eine WSP-Datei. Im Wesentlichen müssen nur die notwendigen Dateien in eine Sharepoint-ähnliche Ordnerstruktur (12/…) kopiert und das Programm gestartet werden. Es können alle Dateien automatisch deployed werden, die unter dem 12-Pfad liegen müssen. Assemblies müssen in ein spezielles Verzeichnis namens GAC kopiert werden, damit Sie automatisch in den Assembly Cache deployed werden. Der WSPBuilder ist sehr gut per Kommandozeile konfigurierbar. Sinnvoll ist es, den Namen der Solution (WSPName) sowie den Ausgabepfad selbst festzulegen (OutputPath). Letzteres ist insbesondere für die Nutzung des SharepointInstallers hilfreich. Die Kommandozeilenoptionen können mit Hilfe des Parameters /? abgerufen werden.

image

Die nun vorhandene WSP-Datei kann mit dem Sharepoint-eigenen Tool STSADM deployed werden. Einfacher ist es aber, den SharepointInstaller zu verwenden. Dieser bietet eine Standard-Installationsoberfläche und prüft zudem ob bestimmte Voraussetzungen für die Installation von Sharepoint-Solutions vorhanden sind. Für die Installation sind drei Dateien notwendig: setup.exe, setup.exe.config und die zuvor erstellte Solution. Alle Parameter für das Setup können in der config-Datei eingestellt werden. Besonders wichtig ist die Solution-ID, welche der WSPBuilder im gleichen Verzeichnis wie die Solution ablegt. Genauere Informationen zur Konfiguration enthält die Readme-Datei.

Das vorhandene Setup-Paket kann nun ausgliefert und installiert werden. Es werden alle Features aktiviert. Beim Ausliefern eines Updates oder eines Patches kann ebenfalls der SharepointInstaller verwendet werden. Während der Installation muss hier Repair ausgewählt werden.


16Okt

Wer mit Visual Studio.Net Sharepoint Projekte (Webparts, Workflows etc.) entwickelt, weiß wie oft man während der Entwicklung ein IISRESET machen muss und auch, dass dies immer eine Weilchen Zeit in Anspruch nimmt. Besonders interessant wird es natürlich, wenn das IISRESET auf einem System ausgeführt wird, auf dem auch noch andere Nutzer arbeiten, denen dann förmlich der IIS “unter den Füßen weggezogen” wird…

Eine deutlich maßvollere Alternative ist es, stattdessen nur den Application Pool der Sharepoint Webanwendung neu zu starten:

cscript c:\windows\system32\iisapp.vbs /a “%SharePointAppPool%” /r

Dies ist nicht nur sauberer, sondern geht auch deutlich schneller… :-)


12Okt

Für alle Vista-Nutzer, die sich auch schon darüber geärgert haben, dass sie bei jedem Öffnen, Speichern, Einchecken usw. eines Office-Dokumentes aus einer Sharepoint Dokumentenbibliothek (2003 oder 2007) 3 mal nach ihrem Passwort gefragt werden, findet sich in der MS Knowledge Base die tröstliche Erklärung, das dieses Verhalten „by design“ ist: http://support.microsoft.com/kb/932118/en

Immerhin gibt es aber einen Workaround dafür: Seite im Internet Explorer als vertrauenswürdige Seite eintragen!

******** UPDATE 19.10.07 ************

Der oben angegebener Workaround scheint (zumindest bei mir) leider nur sporadisch zum Ziel zu führen. Dafür findet sich im offiziellen Microsoft Sharepoint Blog (http://blogs.msdn.com/sharepoint/archive/2007/10/16/known-issue-office-
2007-on-windows-vista-prompts-for-user-credentials-when-opening-documents-in-a-sharepoint-2007-site.aspx
) ein wirklich funktionierender (wenn auch etwas chaotisch anmutender) Workaround:

-> IE7 -> Extras -> Internetoptionen -> Verbindungen -> LAN Einstellungen:

Checkboxen für “Proxyserver verwenden” und “Proxyserver für lokale Adressen umgehen” aktivieren und “fake proxy” (ohne Anführungsstriche) als Proxy eintragen. Unter -> Erweitert “*” als Ausnahme hinzufügen:

IE7ProxySettings

IE7ProxySettingsErweitert

Klingt sehr gewagt - funktioniert aber! Wer sowieso einen (echten) Proxy verwendet, muss nur “Proxyserver für lokale Adressen umgehen” bzw. “Automatische Suche der Einstellungen” aktivieren.

 ******** UPDATE 09.11.07 ************

Man merke auf: Microsoft hat sich selbst korrigiert! Es gibt einen neuen Eintrag im offiziellen Microsoft Sharepoint Blog, wonach der (bei mir inzwischen doch bewährte) Workaround mit dem Fake Proxy nun um Himmels willen nicht mehr angewendet werden soll: http://blogs.msdn.com/sharepoint/archive/2007/10/19/known-issue-office-2007-on-windows-vista-prompts-for-user-credentials-when-opening-documents-in-a-sharepoint-2007-site.aspx

Dafür gibt’s einen neuen Workaround, der in Gestalt eines Hotfix und einiger Registry-Einträge daherkommt:

Der Hotfix (KnowledgeBase Artikel 907306) behebt verschiedene Probleme, die auftreten können, wenn Webordner verwendet werden, um eine Verbindung auf einem Server mittels Web Distributed Authoring und Versioning (WebDAV) herzustellen.

Die Registry-Einträge dienen dazu, die Office-Anwendungen im Windows XP SP 2 Kompatibilitätsmodus laufen zu lassen. Beispielhaft hier die Einträge dür Word, Excel und Powerpoint:

[HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\AppCompatFlags\Layers]
“C:\\Program Files\\Microsoft Office\\Office12\\WINWORD.EXE”=”WINXPSP2″
“C:\\Program Files\\Microsoft Office\\Office12\\EXCEL.EXE”=”WINXPSP2″
“C:\\Program Files\\Microsoft Office\\Office12\\POWERPNT.EXE”=”WINXPSP2″

Einfach in eine Datei mit der Endung “reg” kopieren und diese ausführen. Bei mir hat der Workaround erst funktioniert, als ich HKEY_LOCAL_MACHINE durch HKEY_CURRENT_USER ersetzt habe - dann aber prima :-)

PS: nicht vergessen, den Fake Proxy wieder aus den IE Einstellungen rauszunehmen…

Technorati Tags: , ,

14Sep

In einem Blogeintrag vom 20. Juli 2007 habe ich bereits über diese Fehlermeldung berichtet und einen Lösungsweg aufgezeigt. In einem aktuellen Projekt trat der Fehler jedoch erneut auf, diesmal mit einer anderen Ursache.

Entwickelt wurde ein automatisch ablaufendener Workflow für den MOSS 2007, der manuell sofort oder mit festgelegter Startzeit gestartet werden werden konnte. Um den verzögerten Start zu realisieren wurde eine DelayActivity eingesetzt.

Eine erste prototypische Implementierung zeigte einen interessanten Effekt: Der Workflow funktionierte ohne Probleme, wenn er sofort gestartet wurde. Kam jedoch die DelayActivity für einen verzögerten Start zum Einsatz, wurde der Workflow-Status sofort auf “Beendet” gesetzt. Die Aktionen, die laut Workflow ausgeführt werden sollten, blieben unbeachtet. Eine Fehlermeldung fand sich nur nach intensiver Suche im Sharepoint-Log:

DehydrateInstance: System.Runtime.Serialization.SerializationException: End of Stream encountered before parsing was completed.

Trotzdem in diesem Workflow keine InfoPath-Dokumente verwendet wurden, gab die Exception den entscheidenen Hinweis: Es gibt ein Problem mit der Serialisierung. Anders als im vorangegangen Blogeintrag lag das Problem nicht bei der Serialisierung der Daten, die von einem Formular übergeben werden, sondern bei der Serialisierung des Workflows selbst. Eine Bereinigung bzw. Konvertierung der Attribute der Workflowklasse brachte letztlich den Erfolg. Hierzu sei anzumerken, dass besonders die Sharepoint-Klassen SP* in den meisten Fällen nicht serialisierbar sind.

Abschließend bleibt noch die Frage, warum der Fehler nur beim verzögerten Start des Workflows auftritt. Dies lässt sich mit der Grundfunktionalität der Windows Workflow Foundation erklären. Die in Sharepoint integrierte Workflow Runtime verwaltet alle Workflowinstanzen. Wird eine solche Instanz mittels einer DelayActivity angehalten, wird diese aus Speicher- und Performancegründen persistent ausgelagert. Für diese Auslagerung muss die Instanz natürlich serialisiert werden. Ohne die DelayActivity wird die Instanz im Speicher gehalten, bis der Workflow beendet wurde. Der Fehler tritt also nicht auf.

Technorati Tags: , ,

25Jul

Beim Umhängen eines MOSS 2007 Servers in eine andere Domäne funktionieren natürlich die Servicekonten nicht mehr, die man bei der Konfiguration des SharePoint Servers angegeben hat. Bevor man jetzt manuell überall die Credentials ändert (IIS, SQL Server), und auch nach einiger Zeit immer wieder über nichtssagende Fehlermeldungen des MOSS stolpert (ich sag nur: An unexpected error has occured), hier ein praktischer Befehl des stsadm.

Stsadm.exe –o updatefarmcredentials –userlogin –password

Danach auf jeden Fall iisreset /noforce aufrufen.


24Jul

In Visual Studio 2005 gibt es leider einen kleinen Bug in den “Extensions for WF”. Das Debuggen von Workflows, also nicht des Quellcodes, funktioniert oft nur schlecht oder garnicht. Häufig stürzt das Visual Studio sogar ab, wenn man versucht den Debugger an einen Prozess zu hängen, der Workflows verwendet. Einen solchen Prozess erkennt man recht leicht, indem man einen Blick auf den Typ wirft. Steht dort u.a. “Workflow” (siehe Abbildung) sollte man sich besser nicht an den Prozess hängen.

Blog_WF_Debug

Verhindern lässt sich dieser Effekt indem man das Visual Studio bereits an den Prozess hängt, bevor die Assembly des Workflows geladen wurde, wobei ggf. vorher ein iisreset durchgeführt werden muss. Sobald die Assembly geladen wurde, lässt sich der Quelltext wie gewohnt debuggen.


20Jul

Ein gängige Methode in der Workflowentwicklung für Sharepoint 2007 ist es, Infopath-Formulare zu verwenden. Um die Daten dieser Formulare komfortabel zu deserialisieren, werden in der Regel die von Infopath zur Verfügung gestellten XSD-Schemas mittels des XSD-Tools in Klassen umgewandelt. Bei der Weiterverwendung der generierten Klasse kann folgendender Fehler ggf. auch nur sporadisch auftreten:

DehydrateInstance: System.Runtime.Serialization.SerializationException: End of Stream encountered before parsing was completed.
at System.Runtime.Serialization.Formatters.Binary.__BinaryParser.Run()
at System.Runtime.Serialization.Formatters.Binary.ObjectReader.Deserialize(HeaderHandler handler, __BinaryParser serParser, Boolean fCheck, Boolean isCrossAppDomain, IMethodCallMessage methodCallMessage)
at System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Deserialize(Stream serializationStream, HeaderHandler handler, Boolean fCheck, Boolean isCrossAppDomain, IMethodCallMessage methodCallMessage)
at System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Deserialize(Stream serializationStream)
at System.Workflow.ComponentModel.Activity.Load(Stream stream, Activity outerActivity, IFormatter formatter)
(…)

Das Problem liegt hierbei nicht an den eigentlichen Daten, sondern an einem zusätzlichen Datenfeld, welches von Infopath erzeugt wird:

private System.Xml.XmlAttribute[] anyAttrField;

Da dieses mit keinem Attribut dekoriert ist, kommt es zu Problemen bei der (De-)Serialisierung. Abhilfe schafft das NonSerialized()-Attribut:

[NonSerialized()]
private System.Xml.XmlAttribute[] anyAttrField;