Main /

Sharepoint Webpart Entwicklung

Sharepoint Webpart Entwicklung

Gesammeltes zur Entwicklung von Web Parts für Windows Sharepoint Services (WSS) und Sharepoint Portal Server 2003 (SPS)

1. Web-Part security und Deployment

Um einigermaßen schmerzfrei Web Parts entwickeln zu können sollte die erstellte dll im GAC (Global Assembly Cache) des Webservers residieren. Dann gilt sie als sicher und man hat alle Möglichkeiten die das .NET Framework bietet. Ansonsten kann man keine Dateien schreiben, keinen HTTP-Request absetzen etc. Der Nachteil ist aber, daß man nach jeder Änderung einen iisreset machen muß, damit der Webserver die neue dll benutzt - sofern sich die Versionsnummer der Assembly nicht ändert (siehe unten).

Das Web-Part muß "strongly named" sein wenn seine Assembly im GAC liegt, sonst verweigert der Sharepoint mit einer Sicherheitsmeldung die Ausführung. Dafür muß Web-Part-Assembly mit einem Schlüssel verknüpft werden. Der Schlüssel ist wiederum mit der Versionsnummer verknüpft, d.h. eine andere Versionsnummer hat einen anderen öffentlichen Schlüssel. Deshalb sollte zur Einfachheit während der Entwicklung die Versionsnummer festgenagelt werden, und sich nicht mit jedem Build ändern. Die Versionsnummer befindet sich in der AssemblyInfo.cs, wenn sie * enthält wird sie bei jedem Build hochgezählt - wir setzen sie fest: [assembly: AssemblyVersion("1.0.0.0")]

Um ein Webpart 'strongly named' und damit vertrauenswürdig zu machen sind folgende Schritte notwendig:

Es ist eine Datei mit einem Schlüsselpaar nötig. Dazu existiert ein Kommandozeilen-tool im Visual Studio .NET Installations-Verzeichnis
(\Programme\Microsoft Visual Studio .NET 2003\SDK\v1.1\Bin\).
Eine Schlüsseldatei wird erstellt mit: sn.exe -k c:\keypair.snk Man erstellt sich besten einmalig ein Keyfile und verwendet es für alle Projekte.

In der AssemblyInfo.cs muß das keypair.snk-File referenziert werden:
[assembly: AssemblyKeyFile("c:\\keypair.snk")]

bzw. wenn es im Quellcode-Verzeichnis des Webpart-Projektes liegt:
[assembly: AssemblyKeyFile("..\\..\\keypair.snk")]

Das Keyfile darf nicht auf den Ziel-Server deployt werden. Erstens wird es nicht benötigt, zweites ist es eine Sicherheitslücke, denn der Angreifer erhält damit den privaten Schlüssel.

1.1 Signieren des Web-Parts

  • Public key ermitteln mit sn -T <assemblyname.dll>
    Alternativ: Assembly per drag & drop in GAC (C:\windows\assembly) reinziehen, Public Key wird dann im Dateifenster ersichtlich.
  • .dwp-File editieren, mit mit einem Tag
    <Assembly>Assemblyname ohne .dll, Version=<Versionsnummer>,
    Culture=neutral, PublicKeyToken=<Public Key Token (mit sn ermittelt)></Assembly>

    versehen (ohne Umbruch!).

    Beispiel:
    <Assembly>Elsni.Webparts.tollesWebpart, Version=1.0.0.0, Culture=neutral, PublicKeyToken=27828b94c818161e</Assembly>
  • in Manifest.xml wie folgt eintragen:
    <SafeControl Assembly="Elsni.Webparts.tollesWebpart, Version=1.0.0.0, Culture=neutral, PublicKeyToken=27828b94c818161e" Namespace="Elsni.Webparts" TypeName="*" Safe="True" />
  • Ein CAB-Projekt in der Solution anlegen, und alle Files einbinden. Die bestehenden .dwp-files sollten bereits vom Build-Typ "Inhalt" sein, nachträglich erstellte .dwp-files sind per default nicht eingebunden. (In den Eigenschaften des dwp-files die Buildaktion auf 'Inhalt' setzen).
  • Auf SP-Server:
    C:\Programme\Gemeinsame Dateien\Microsoft Shared\web server extensions\60\BIN\stsadm.exe 
    -force -o addwppack -globalinstall -filename <''CAB-FILE''>
  • Web-Part aus Sharepoint-Seite entfernen, falls es schon vorhanden war (aus früheren nicht strongly-named deployments)
  • IIS neu starten: iisreset
  • Web-Part in SP-Site wieder einbinden.

1.2 Web-Part-Deployment mit Batch-Datei

(Die Zeilen sind sehr lang und aus anzeigetechnischen Gründen umgebrochen)

"C:\Program Files\Microsoft Visual Studio .NET 2003\SDK\v1.1\Bin\gacutil.exe"
/u ''Assembly.Name'

"C:\Program Files\Microsoft Visual Studio .NET 2003\SDK\v1.1\Bin\gacutil.exe"
/i "''<Pfad zum Projekt>''\bin\''<DllName.dll>''"

copy "''<Pfad zum Projekt>''\bin\*.dwp"  "C:\Inetpub\wwwroot\wpcontent"

iisreset

1.3 Finales Deployen von strongly-named Web-Parts

Das finale Deployen zum Kunden ist glücklicherweise relativ einfach aus der Entwicklungsumgebung heraus:

  • Die <SafeControls> Sektion des Manifest.xml files muß den gleichen Eintrag enthalten, wie die gleichnamige Sektion der web.config - Wichtig ist hier natürlich wieder mal der Public Key.
  • Die <DwpFiles> Sektion muss alle zu deployenden Web-Parts in der Form <DwpFile FileName="SiteMap.dwp"/> enthalten
  • Bei allen dwp-Files muss die Build-Property auf "Inhalt" gesetzt werden, sonst werden sie nicht mit in die CAB-Datei gepackt.

Die fertige CAB-Datei kann dann einfach mit stsadm in den Kundenserver eingebunden werden, die Sicherheitsmechanismen werden automatisch konfiguriert. Voraussetzung ist, daß der ausführende User dbo-Rechte auf der config-Datenbank das SQL-Servers hat.

1.4 Troubleshooting

  • beim deployen mit stsadm tritt der Fehler System.Exception oder Object Reference not set to instance of an object auf:
    Man sollte genau die Manifest.xml und assemblyinfo.cs durchsehen. Es könnte ein vereinsamtes Gänsefüßchen (Anführungsstrich, Tüttel, Hochkomma etc.) und damit eine nicht abgeschlossene Zeihenkette dafür verantwortlich sein. Es kann sich auch um einen anderen Schreibfehler in einer der Konfigurationsdateien handeln. Kandidaten dafür sind auch die dwp Files, im <Assembly> Tag z.b. dürfen keine Fehler sein!
  • Beim deployen mit stsadm tritt der Fehler "Die Webpartpaket-datei kann in der Konfigurationsdatenbank nicht gefunden werden" auf
    Das kann zwei Ursachen haben:
    • Der aktuelle User hat keine dbo-Rechte auf die Sharepoint Config-Datenbank im SQL-Server
    • Es befindet sich Grütze in der CAB-Datei. Bitte die Referenzen des CAB-Projektes nochmal genau nachprüfen.
  • Beim deployen mit stsadm tritt der Fehler "Ungültige Daten auf Stammebene. Zeile 1, Position 1."(o.ä.) auf
    • Eine der XML-Dateien (.dwp oder Manifest.xml) validiert nicht. Müllzeichen?
  • Ein neues Web-Part einer Web Part Library ist nach dem deployen im Virtuellen-Server-Katalog von Sharepoint nicht vorhanden
    Das kann wieder zwei Gründe haben:
    • Die Buildaktion des Web-Part dwp-Files muß in den Eigenschaften auf Typ "Inhalt" gesetzt werden, damit es ins CAB-File gepackt wird (natürlich muß man das CAB-Projekt anweisen alle Inhaltsdateien mit einzupacken). Standardmäßig ist sie auf "keine" gesetzt.
    • Das neue Web-Part ist nicht in der Manifest.xml eingetragen

1.5 Wichtige Verzeichnisse

  • Die Webpart-Assembly-DLLs? werden normalerweise im bin-Verzeichis des des Webservers, also standardmäßig in C:\inetpub\wwwroot\bin installiert, es sei denn man installiert mit der option -globalinstall dann liegt die dll im Global Assembly Cache (GAC), also in C:\windows\assembly. Im letzteren Fall muß die Assembly signiert sein.
  • Die Webpart-DWP-Dateien liegen im Verzeichnis C:\inetpub\wwwroot\wpcatalog
  • Zusätzliche Webpart-Ressourcen liegen im Verzeichnis C:\inetpub\wwwroot\wpresources

2. Property-Attribute

[Browsable(true),
Property erscheint in der Property-Liste
Category("Miscellaneous"),
Unter welcher Kategorie erscheint die Property
DefaultValue(defaultText),
Default-Wert
WebPartStorage(Storage.Personal),
Unter eigenem Kontext speichern?
FriendlyName("Text"),
Name der Property
Description("Text Property")]
Beschreibung (Prosa)

Das dwp-File sollte eine Konfigurationsdatei für das Web-Part sein. Properties können direkt über xml-Tags gesetzt werden. Man sollte universelle Web-Parts anstreben die über das dwp-File angepasst werden.

Verzeichnisse: C:\Inetpub\wwwroot\bin

3. Lebenszyklus eines Web Parts

  1. Instanziierung, Ausführung des Konstruktors
  2. init methode
  3. Load event
  4. postback event
  5. CreateChildControls()
  6. ICellConsumer.CellReady()
  7. evtl. OnClick- oder Command-Events der Controls
  8. RenderWebPart()
  9. unload event
  10. disposed methode

Der Lebenszyklus, d.h. Reihenfolge der Event-Methodenaufrufe ist zwar grundsätzlich sinnvoll, bringt jedoch Probleme mit sich:

Alle Web-Controlls müssen in CreateChildChildControls() instanziiert und der Control-Collection hinzugefügt werden, sonst feuern sie keine Events und behalten ihre Daten beim Postback nicht.

Click-Events werden erst NACH CreateChildControls() ausgeführt. Um also auf einen Klick zu reagieren um z.B. ein Menü auszuklappen etc. müssen alle Controls instanziiert werden bevor man weiß welcher Menüpunkt ausgeklappt werden soll. Ein klassisches Henne-Ei-Problem.

4. Dynamisches Erstellen von Controls

Manchmal möchte man in einer Schleife Controls erzeugen, deren Anzahl von Listeneinträgen etc. abhängen. Das ist ein bißchen knifflig, es treten Henne-Ei probleme auf, insbesondere wenn das Web-Part ein Cell-Consumer (ein verbundenes Web Part, das einen Wert von einem anderen Web Part erhält) ist. Folgende Probleme treten auf:

  • in der CreateChildControls() Methode müssen die Controls erzeugt und per Controls.Add() hinzugefügt werden, damit die Werte persistieren und Events gefeuert werden. Zu diesem Zeitpunkt ist ein eventueller Cell-Consumer Wert noch nicht vorhanden, außerdem sind die Events noch nicht durchgelaufen.
  • In der RenderWebPart()-Methode ist der Cell-Consumer Wert vorhanden und alle Event-Methoden wurden ausgeführt. Wenn die Controls jedoch hier erst instanziiert oder hinzugefügt werden, vergessen sie ihren Inhalt beim Postback, und zugewiesene Events werden nicht gefeuert.
  • Controls, die auf visible=false gesetzt sind, vergessen ihren Inhalt beim postback! (anders als in herkömmlichen ASP-Seiten!). Abhilfe: Controls auf unsichtbare DIV-Tags setzen. Ist nicht sehr sauber, funktioniert aber. Siehe diesen News-Thread

...tbc...

5. Persistent-halten von Daten in einem Webpart

In einem Webpart besteht in der Standardkonfiguration keine Session in der Daten abgelegt werden könnten. Man kann es allerdings im Page.Cache Objekt tun:

Schreiben:

 Page.Cache.Insert(string key, object value);

Lesen:

 Page.Cache.Get(string key);

6. Die standard-CSS-Styles sehen komisch aus...

Damit man die Sharepoint standard CSS-Klassen (siehe CSS-Guide) in einem Webpart vernünftig benutzen kann muß die Eigenschaft UseDefaultStyles im Konstruktor des Webparts auf false gesetzt werden

this.UseDefaultStyles = false;

Siehe auch

Links

Frische Änderungen | Menü editieren
zuletzt geändert am 09.08.2007 21:31 Uhr von Elsni
Edit Page | Page History