MSDN Magazin > Home > Ausgaben > 2007 > November >  Office Space: Ereignisse in SharePoint 200...
Office Space
Ereignisse in SharePoint 2007
Ted Pattison

Codedownload verfügbar unter: OfficeSpace2007_11.exe (167 KB)
Browse the Code Online
Windows® SharePoint® Services (WSS) 3.0 bietet Entwicklern zahlreiche wesentliche Verbesserungen zum Erstellen benutzerdefinierter Geschäftslösungen, die auf SharePoint-Websites basieren. Eine der wichtigsten Verbesserungen für Entwickler hängt mit einer neuen Infrastruktur zum Verarbeiten serverseitiger Ereignisse zusammen. Wenn ein Benutzer beispielsweise eine Aktion durchführt, durch die der Inhalt einer SharePoint-Website verändert wird (indem er etwa ein neues Dokument hochlädt oder ein Element aus einer Liste löscht), bietet sich für einen Entwickler die Möglichkeit, auf diese Benutzeraktion mit einem Ereignishandler zu reagieren, der eine in C# oder Visual Basic® geschriebene serverseitige Logik ausführt.
Obwohl WSS 2.0 ebenfalls eine Infrastruktur für eine serverseitige Ereignisverarbeitung bereitgestellt hat, weist WSS 3.0 in dieser Hinsicht beträchtliche Verbesserungen auf. Abbildung 1 zeigt einen Vergleich der Unterschiede bei der Unterstützung der Ereignisverarbeitung in WSS 2.0 und WSS 3.0. Es ist entscheidend, dass die neue Infrastruktur von WSS 3.0 zur Verarbeitung von Ereignissen mehr als nur eine Verfeinerung dessen ist, was bereits in der vorherigen Version vorhanden war. Die neue Infrastruktur von WSS 3.0 zur Verarbeitung von Ereignissen ersetzt die Infrastruktur von WSS 2.0 zur Ereignisverarbeitung voll und ganz. Eine der größten Änderungen besteht darin, dass die Ereignisverarbeitung nicht auf Dokumentbibliotheksebene, sondern auf Listenebene implementiert ist. Ereignisse, die von Listendefinitionen und Listenelementen ausgelöst werden, funktionieren daher bei allen Arten von Listen einschließlich Dokumentbibliotheken.

Ereignistyp Infrastruktur von WSS 2.0 Infrastruktur von WSS 3.0
Ereignisse für Dokumentbibliotheken Unterstützt Unterstützt
Mehrere an ein einzelnes Ereignis gebundene Ereignishandler Nicht unterstützt Unterstützt
Ereignisse für Listen Nicht unterstützt Unterstützt
Ereignisse für Listendefinitionen Nicht unterstützt Unterstützt
Ereignisse für Websites Nicht unterstützt Unterstützt
Synchrone Ereignishandler mit Abbruch vor dem Ereignis Nicht unterstützt Unterstützt
Asynchrone Ereignishandler nach dem Ereignis Unterstützt Unterstützt
Ereignishandlerklassen Müssen die IListEventSink-Schnittstelle implementieren Müssen von Empfängerbasisklassen im WSS-Objektmodell erben
Die ältere Infrastruktur von WSS 2.0 folgt einem völlig anderen Programmiermodell und erfordert eine andere Vorgehensweise zum Programmieren von Ereignishandlern für Ereignisse. WSS 3.0 unterstützt sowohl die neue 3.0-Version der Infrastruktur zur Ereignisverarbeitung als auch die ältere Infrastruktur von WSS 2.0. Sie sollten sich jedoch bewusst sein, dass die von WSS 3.0 bereitgestellte Unterstützung der älteren Ereignishandler von Version 2.0 nur integriert wurde, um Abwärtskompatibilität zu bieten, wenn Code, der für WSS 2.0-Lösungen geschrieben wurde, in eine WSS 3.0-Umgebung integriert wird. Wenn Sie mit dem Entwickeln von Lösungen für WSS 3.0 und Microsoft® Office SharePoint Server (MOSS) 2007 beginnen, sollten Sie die neue Infrastruktur von WSS 3.0 zur Ereignisverarbeitung nutzen, die auf neuen Konzepten und dem Programmiermodell basiert, das im Artikel der „Office Space“-Ausgabe dieses Monats vorgestellt wird.

Ereignisempfängerklassen
Die Ereignisverarbeitung in WSS 3.0 beruht auf Ereignisempfängerklassen. Dies bedeutet im Einzelnen, dass eine neue Ereignisempfängerklasse durch Erben von einer der verschiedenen Ereignisempfängerbasisklassen erstellt wird, die innerhalb des WSS-Objektmodells als öffentliche Klassen bereitgestellt werden. Zu diesem Zweck müssen Sie ein neues Klassenbibliotheksprojekt erstellen, das auf die WSS-Kernassembly namens „Microsoft.SharePoint.dll“ verweist.
In Abbildung 2 sehen Sie die Liste der WSS-Empfängerbasisklassen, die durch das WSS-Objektmodell zur Verfügung gestellt werden. Wenn Sie eine Klassendefinition erstellen, die von einer dieser WSS-Empfängerbasisklassen erbt, fügen Sie Ereignishandler hinzu, indem Sie ausgewählte Methoden überschreiben.

Klasse Beschreibung
SPListEventReceiver Stellt Ereignisverarbeitung bereit, wenn Benutzer in einer Listendefinition Spalten hinzufügen, ändern und entfernen.
SPItemEventReceiver Stellt Ereignisverarbeitung bereit, wenn Benutzer Elemente innerhalb einer Liste oder Dokumente innerhalb einer Dokumentbibliothek ändern.
SPWebEventReceiver Stellt Ereignisverarbeitung bereit, wenn Benutzer eine Websitesammlung oder eine Website verschieben oder löschen.
SPEmailEventReceiver Stellt Ereignisverarbeitung bereit, wenn Benutzer E-Mail an eine E-Mail-kompatible Liste senden.
Wenn Sie eine benutzerdefinierte Empfängerklasse mit einem oder mehreren Ereignishandlern implementiert haben, müssen Sie sie anschließend in einer Assembly mit einem starken Namen kompilieren und sie im globalen Assemblycache (GAC) installieren. Danach können Sie Ihre Ereignishandler an Ereignisse binden, die durch ein Hostobjekt wie eine Website, eine Liste oder eine Dokumentbibliothek zur Verfügung gestellt werden. Wie Sie in diesem Artikel noch sehen werden, stehen Ihnen beim Binden von Ereignishandlern zwei Möglichkeiten zur Wahl. Sie können Ereignishandler mithilfe eines Features mit deklarativer XML-Syntax oder programmgesteuert mithilfe des WSS-Objektmodells binden. Wenn Sie eine Ereignishandlermethode an ein bestimmtes Ereignis gebunden haben, kümmert sich WSS um die Ausführung Ihres Handlers als Reaktion auf die Benutzeraktionen, die das Ereignis auslösen.

Vorereignisse und Nachereignisse
WSS 3.0-Ereignisse können in zwei Hauptkategorien unterteilt werden: Vorereignisse und Nachereignisse Vorereignisse werden als Reaktion auf eine Aktion eines Benutzers ausgelöst, bevor WSS Daten in die Inhaltsdatenbank zurückschreibt. Ein wesentlicher Punkt hierbei besteht darin, dass Vorereignisse im Lebenszyklus der Anforderungsverarbeitung früh genug stattfinden, um einen Abbruch der Benutzeraktion zu ermöglichen. Aus diesem Grund bieten Vorereignisse eine ideale Möglichkeit für Sicherheitsüberprüfungen und benutzerdefinierte Prüfungen.
WSS unterstützt auch Nachereignisse, deren Ereignishandler ausgeführt werden, nachdem WSS 3.0 Daten in die Inhaltsdatenbank zurückgeschrieben hat, um die Aktion des Benutzers zu übermitteln. Nachereignisse unterstützen keinen Abbruch der Benutzeraktion. Stattdessen werden Nachereignisse dazu verwendet, eine benutzerdefinierte Verarbeitungslogik zu starten, die immer dann ausgeführt werden soll, wenn Inhalt geändert wurde.
Der Ereignishandler für ein Vorereignis wird auf dem gleichen Thread ausgeführt, der die Aktion des Benutzers (z. B. das Hinzufügen eines Elements) verarbeitet. Deshalb sind Vorereignisse eher blockierender Natur und werden im Allgemeinen als synchrone Ereignisse bezeichnet. WSS führt die Ereignishandler für Nachereignisse auf einem separaten Thread aus, damit ihre Verarbeitung die Reaktion nicht blockiert, die zum Benutzer zurückgeschickt wird. Aus diesem Grund werden Nachereignisse im Allgemeinen als asynchrone Ereignisse bezeichnet. Beachten Sie auch, dass Vorereignisse auf überschreibbaren Methoden beruhen, deren Namen auf „ing“ enden (z. B. „FieldDeleting“), während die Namen der Methoden eines Nachereignisses auf „ed“ enden (z. B. „FieldDeleted“).
Nachfolgend sehen Sie ein Beispiel für die Erstellung einer neuen benutzerdefinierten Empfängerklasse, in der ein Ereignishandler für ein Vorereignis und für ein Nachereignis definiert wird. Abbildung 3 zeigt eine benutzerdefinierte Empfängerklasse, die von der SPListEventReceiver-Klasse erbt und die FieldDeleting- und FieldDeleted-Methoden überschreibt. Es ist zu beachten, dass WSS beim Aufrufen eines dieser Ereignishandler einen einzigen Parameter der als „SPListEventProperties“ bezeichneten Eigenschaften übergibt.
Imports Microsoft.SharePoint

Public Class MyListEvents
    Inherits SPListEventReceiver

    Public Overrides Sub FieldDeleting ( _
        ByVal properties As SPListEventProperties)
    '*** your custom event handling code goes here
    End Sub

    Public Overrides Sub FieldDeleted ( _
        ByVal properties As SPListEventProperties)
    '*** your custom event handling code goes here
    End Sub

End Class

Da die FieldDeleting-Methode ein Vorereignis verarbeitet, unterstützt sie den Abbruch der Benutzeraktion. Stellen Sie sich ein Szenario vor, in dem Sie alle Benutzer einschließlich des Administrators der Websitesammlung daran hindern möchten, Spalten aus einer bestimmten Listendefinition zu löschen. Erreicht wird dies durch Zuweisen des Werts „True“ zur Cancel-Eigenschaft des SPListEventProperties-Parameters. Beim Abbrechen der Benutzeraktion müssen Sie auch eine benutzerdefinierte Fehlermeldung zuweisen, indem Sie der ErrorMessage-Eigenschaft einen Zeichenfolgenwert zuweisen. Diese Fehlermeldung wird dem Benutzer direkt angezeigt:
Public Overrides Sub FieldDeleting( _
    ByVal properties As SPListEventProperties)
    '*** cancel user action
    properties.ErrorMessage = "Deleting not supported!"
    properties.Cancel = True
End Sub
Wenn ein Ereignishandler für ein Vorereignis der Cancel-Eigenschaft den Wert „True“ zuweist, reagiert WSS darauf, indem es die Anforderung stoppt und die Benutzeraktion abbricht. Statt die Spalte zu löschen, wie dies der Benutzer angefordert hat, zeigt WSS dem Benutzer die benutzerdefinierte Fehlermeldung an. Der ausschlaggebende Punkt hierbei ist, dass Vorereignisse eine Verteidigungsschicht gegen unerwünschte Änderungen bieten.
Nachdem Sie nun die Grundlagen des Abbruchs einer Benutzeraktion im Ereignishandler für ein Vorereignis kennengelernt haben, soll nun ein weiterer Ereignishandler für ein Vorereignis erstellt werden, der eine bedingte Logik enthält. Stellen Sie sich vor, Sie müssen eine Sicherheitsüberprüfung durchführen, um sicherzustellen, dass Benutzer bestimmte Kriterien erfüllen, bevor ihnen ermöglicht wird, Elemente aus einer Liste oder Dokumente aus einer Dokumentbibliothek zu löschen. Nehmen Sie als Beispiel den ItemDeleting-Ereignishandler in der Empfängerklassendefinition in Abbildung 4. Beachten Sie, dass die bedingte Logik die Benutzeraktion abbricht, wenn ermittelt wird, dass der Benutzer nicht über Websiteadministratorberechtigungen verfügt.
Public Class MyItemEvents
    Inherits SPItemEventReceiver

    Public Overrides Sub ItemDeleting( _
        ByVal properties As SPItemEventProperties)

        If (Not properties.OpenWeb().CurrentUser.IsSiteAdmin()) Then
            Dim ErrorMessage As String
            ErrorMessage = "Only site administrator can delete items"
            properties.ErrorMessage = ErrorMessage
            properties.Cancel = True
        End If

    End Sub

End Class

Wie Sie sehen können, wird durch diese Ereignishandlerlogik die Bedingung aufgestellt, dass der aktuelle Benutzer bestimmte Berechtigungen besitzen muss, bevor ein Löschvorgang zugelassen wird. Wenn Sie dieses Beispiel noch einen Schritt weiter führen, können Sie einen Ereignishandler schreiben, um in Abhängigkeit von einer Benutzermitgliedschaft in einer Active Directory®-Gruppe zu bestimmen, ob Benutzer Elemente löschen können. Da WSS auf der ASP.NET-Laufzeit aufgebaut ist, kann dies mit einem einfachen ASP.NET-Programmierverfahren erzielt werden, indem die IsInRole-Methode abgefragt wird, die durch die User-Eigenschaft des HttpContext-Objekts bereitgestellt wird:
If (Not HttpContext.Current.User.IsInRole( _
    "MyDomain\ContentManagers")) Then
    Dim ErrorMessage As String
    ErrorMessage = _
    "Only members of ContentManagers can delete items"
    properties.ErrorMessage = ErrorMessage
    properties.Cancel = True
End If

Überprüfen von Vorereignissen
Im Folgenden sollen die Möglichkeiten untersucht werden, in einem Ereignishandler für ein Vorereignis eine Prüfungslogik zu schreiben. Dies ermöglicht das Schreiben von Ereignishandlern, durch die Benutzer sich beim Hinzufügen oder Ändern von Elementen innerhalb einer Liste nach anwendungsspezifischen Einschränkungen richten müssen. Sie können beispielsweise überprüfen, dass das Lieferdatum für eine Rechnung kein Samstag oder Sonntag ist oder dass eine Telefonnummer oder eine E-Mail-Adresse einem Muster entspricht, das durch einen regulären Ausdruck definiert wird.
Einer der leistungsfähigsten Aspekte des Schreibens von Prüfungslogik für Vorereignisse besteht darin, dass die Prüfung sich über mehrere Spalten erstrecken kann. Im Beispielcode für diesen Monat wird eine Kaufinteressentenliste namens „Sales Leads“ verwendet, die eine Spalte für eine Telefonnummer im Büro und eine Spalte für eine E-Mail-Adresse enthält. Der verwendete Ereignishandler führt an jedem Element der Kaufinteressentenliste „Sales Leads“ eine Prüfung durch, dass entweder für die Telefonnummer im Büro oder für die E-Mail-Adresse eine Angabe vorhanden ist. Der Grundgedanke dabei ist, dass Kaufinteressenten ohne jeden Wert sind, wenn niemand Kontaktinformationen für sie eingegeben hat.
Es gibt für einen Benutzer zwei Möglichkeiten, ein Listenelement zu ändern. Ein Benutzer kann ein neues Element hinzufügen oder ein vorhandenes Element aktualisieren. Beim Schreiben von Prüfungslogik für Vorereignisse muss in der Regel hinter den Ereignishandlern, die an die ItemAdding- und ItemUpdating-Ereignisse gebunden sind, redundanter Code hinzugefügt werden. Daher ist es am besten, die Prüfungslogik in einer separaten Methode unterzubringen, die von zwei verschiedenen Ereignishandlern aufgerufen werden kann. Die in Abbildung 5 gezeigte SalesLeadIsValid-Methode akzeptiert zwei Zeichenfolgenparameter namens „Phone“ und „E-mail“ und gibt „True“ zurück, falls einer dieser Parameter nicht leer ist.
Private Function SalesLeadIsValid(
    ByVal Phone As String, ByVal Email As String) _
    As Boolean

    '*** make sure we have either phone or e-mail
    If (String.IsNullOrEmpty(Phone) And _
        String.IsNullOrEmpty(Email)) Then
        Return False
    Else
        Return True
    End If

End Function

Mit der in der SalesLeadIsValid-Methode enthaltenen Prüfungslogik können Sie diese Methode von Ereignishandlern aus aufrufen, die an das ItemAdding- oder das ItemUpdating-Ereignis gebunden sind. Beachten Sie, dass Sie innerhalb eines Ereignishandlers für ein ItemAdding-Ereignis oder ein ItemUpdating-Ereignis die Spaltenwerte abrufen müssen, an denen Sie Prüfungen durchführen möchten. Der SPItemEventProperties-Parameter stellt zwei Sammlungen namens „BeforeProperties“ und „AfterProperties“ bereit. Dadurch können Sie den Wert einer Spalte wahlweise in seinem Zustand vor oder nach der Änderung durch den Benutzer laden.
Abbildung 6 zeigt ein Beispiel für die Implementierung eines ItemAdding-Ereignishandlers, der sowohl für „Phone“ als auch für „E-mail“ die After-Werte (die Werte nach der Änderung) abruft und sie der SalesLeadIsValid-Methode übergibt, um zu bestimmen, ob die Aktion des Benutzers zugelassen werden soll.
Public Overrides Sub ItemAdding( _
    ByVal properties As SPItemEventProperties)

    Dim Phone As String, Email As String
    Phone = _
        CType(properties.AfterProperties("WorkPhone"), _
        String)
    Email = _
        CType(properties.AfterProperties("EMail"), _
        String)

    If (Not SalesLeadIsValid(Phone, Email)) Then
        Dim ErrorMessage As String
        ErrorMessage = _
            "Sales lead must have valid phone or email"
        properties.ErrorMessage = ErrorMessage
        properties.Cancel = True
    End If
End Sub

Achten Sie genau darauf, wie der Ereignishandler die beiden Spaltenwerte aus der AfterProperties-Sammlung abruft. „AfterProperties“ ist eine Sammlung mit einer parametrisierten Standardeigenschaft (einem Indexer), die den Namen einer Spalte akzeptiert. Beachten Sie, dass der an „AfterProperties“ übergebene Parameter ein Zeichenfolgenwert ist, bei dem zwischen Groß- und Kleinschreibung unterschieden wird. Weiterhin ist erwähnenswert, dass dieser Parameter nicht den Anzeigenamen, sondern den physischen Namen der Spalte repräsentiert.

Nachereignishandler
Ein Nachereignis unterscheidet sich von einem Vorereignis dadurch, dass es ausgelöst wird, nachdem eine Aktion abgeschlossen wurde, und dem Entwickler keine Möglichkeit bietet, die Aktion abzubrechen. Nachereignisse geben dem Entwickler die Möglichkeit, eine benutzerdefinierte Verarbeitung einzurichten, die ausgeführt werden soll, wenn der Benutzer eine Aktion, durch die innerhalb einer SharePoint-Website Inhalt geändert wurde, erfolgreich abgeschlossen hat. Sobald beispielsweise ein Benutzer einer Liste ein neues Element hinzugefügt hat, kann ein Nachereignis verwendet werden, um eine der Spalten neu zu formatieren, damit die Datenintegrität gewahrt bleibt, oder per E-Mail eine Benachrichtigung an einen bestimmten Benutzer oder eine Verteilerliste zu senden.
Im Folgenden wird ein Beispiel für das Schreiben eines Ereignishandlers für die Kaufinteressentenliste „Sales Leads“ beleuchtet, der an das ItemAdded-Ereignis gebunden wird. In diesem Beispiel wird die Bedingung gestellt, dass alle Namen von Kaufinteressenten in Großbuchstaben formatiert sein müssen. Ein Ereignishandler erfasst den Spaltenwert mit dem Namen des Kaufinteressenten und formatiert ihn in Großbuchstaben um.
Seien Sie vorsichtig, wenn Sie einen Ereignishandler für ein Nachereignis schreiben und das Element ändern, auf dem das Ereignis basiert. Dies ist deshalb etwas problematisch, weil durch das Ändern des Elements das Ereignis erneut ausgelöst wird. Wenn das Ereignis erneut ausgelöst wird, will es das Element ändern und startet dadurch eine rekursive Schleife. Um dies zu vermeiden, müssen Sie die Ereignisauslösung während der Änderung des aktuellen Elements deaktivieren. Dies erreichen Sie durch einen Aufruf der DisableEventFiring-Methode, die von der zugrunde liegenden Basisklasse bereitgestellt wird. Wenn Sie das Element geändert haben, müssen Sie „EnableEventFiring“ aufrufen. Hier sehen Sie, wie alles zusammenpasst:
Public Overrides Sub ItemUpdated( _
    ByVal properties As SPItemEventProperties)

    Me.DisableEventFiring()
    Dim SalesLead As String = _
        CType(properties.ListItem("Title"), String)
    '*** reformat item column values as required
    properties.ListItem("Title") = SalesLead.ToUpper()
    properties.ListItem.Update()
    Me.EnableEventFiring()
End Sub
In diesem Artikel wurden mehrere verschiedene Beispiele für das Schreiben von Ereignishandlern für Vor- und Nachereignisse aufgeführt. Jetzt wissen Sie, warum und wie Ereignishandler geschrieben werden müssen. Nun muss nur noch erklärt werden, wie Ereignishandler an Ereignisse auf einem Hostobjekt innerhalb einer SharePoint-Website gebunden werden.

Binden von Handlern an Ereignisse
Weiter oben wurde bereits erwähnt, dass Empfängerklassen in eine Assembly-DLL mit einem starken Namen kompiliert und im GAC installiert werden müssen. Die Möglichkeiten zum Binden von Ereignishandlern bestehen darin, entweder in einem Feature deklaratives XML zu verwenden oder über das WSS-Objektmodell eine programmgesteuerte Bindung durchzuführen. Allerdings ist es für beide Verfahren erforderlich, dass Sie den vollständigen vierteiligen Namen der Assembly sowie den Namespace-kompatiblen Namen der Empfängerklasse kennen, in der die zu bindenden Ereignishandler enthalten sind.
Zunächst folgt eine Beschreibung, wie Ereignishandler mithilfe von deklarativem XML in einem Feature gebunden werden. Dies wird durch Hinzufügen eines Receivers-Elements mit einem oder mehreren inneren Receiver-Elementen erzielt. Im Beispielcode zu diesem Artikel ist ein Feature mit einem Receivers-Element enthalten, das zwei verschiedene Ereignishandler an den WSS-Listentyp „Contacts“ bindet (siehe Abbildung 7). Die Contacts-Liste hat die Listentypkennung 105. Jede Liste, die innerhalb einer Website, bei der dieses Feature aktiviert ist, aus der Contacts-Liste erstellt wird, besitzt daher automatisch ebenfalls diese Ereignishandlerbindungen.
<Elements xmlns="http://schemas.microsoft.com/sharepoint/">

  <!-- Receivers element used only in feature where Scope=Web -->
  <Receivers ListTemplateId="105" >

    <Receiver>
      <Name>Field_Deleting_Event</Name>
      <Type>FieldDeleting</Type>
      <Assembly>OfficeSpaceEventDemo, [4-part assembly name]</Assembly>
      <Class>OfficeSpaceEventDemo.MyListEvents</Class>
      <SequenceNumber>1000</SequenceNumber>
      <Data>My Custom Data</Data>
    </Receiver>

    <Receiver>
      <Name>Field_Deleted_Event</Name>
      <Type>FieldDeleted</Type>
      <Assembly>OfficeSpaceEventDemo, [4-part assembly name]</Assembly>
      <Class>OfficeSpaceEventDemo.MyListEvents</Class>
      <SequenceNumber>1000</SequenceNumber>
      <Data>My Custom Data</Data>
    </Receiver>

  </Receivers>
</Elements>

Beachten Sie, dass Sie innerhalb des Receivers-Elements für jeden zu bindenden Ereignishandler ein separates Receiver-Element bereitstellen müssen. Es gibt kein unterstütztes Verfahren, um mehrere Ereignishandler gleichzeitig an ein einzelnes Receiver-Element zu binden.
Zwei Bindungsinformationen müssen in einem Receiver-Element unbedingt enthalten sein. Es handelt sich dabei um das Assembly- und das Class-Element, die jeweils den vollständigen vierteiligen Namen der Assembly und den Namespace-kompatiblen Namen der Empfängerklasse enthalten müssen. Das Name-Element innerhalb eines Receiver-Elements kann dazu verwendet werden, dem Ereignishandler für Verfolgungszwecke einen Anzeigenamen zuzuweisen, aber erforderlich ist dies nicht.
Das SequenceNumber-Element innerhalb eines Receiver-Elements ist nützlich, wenn mehrere Ereignishandler an ein einziges Ereignis gebunden werden. Der Ereignishandler mit der niedrigeren Sequenzzahl wird stets vor einem Ereignishandler mit einer höheren Sequenzzahl ausgelöst. Daher können Sie mehrere Ereignishandler hinzufügen und sich darauf verlassen, dass eine deterministische Ausführungsreihenfolge eingehalten wird.
Das innerhalb eines Receiver-Elements enthaltene Data-Element ermöglicht es, eine bestimmte Ereignishandlerbindung mit allen gewünschten benutzerdefinierten Zeichenfolgendaten zu konfigurieren. Sie können innerhalb des Data-Elements mithilfe der ReceiverData-Eigenschaft des SPListEventProperties-Parameters auf diesen Zeichenfolgenwert zugreifen und ihn anwendungsspezifisch verwenden, um Zahlen oder reguläre Ausdrücke für Prüfungsroutinen oder benutzerdefinierte Fehlermeldungen bereitzustellen:
Public Overrides Sub FieldDeleting( _
    ByVal properties As SPListEventProperties)

    Dim BindingData As String
    BindingData = properties.ReceiverData
  '*** use binding data in application-specific fashion
End Sub

Verwenden des WSS-Objektmodells
Ereignishandler mithilfe eines Receivers-Elements in einem Feature deklarativ an Ereignisse zu binden, eignet sich zwar für einige Szenarios, aber diesem Verfahren fehlt die in vielen anderen Szenarios erforderliche Flexibilität. Zum Beispiel kann das Receivers-Element nur dazu verwendet werden, einen Ereignishandler auf Website-Ebene an einen Listentyp zu binden. Dieses deklarative Verfahren bietet keine Möglichkeit dazu, einen Ereignishandler auf einer Website an eine einzelne Listeninstanz zu binden, ohne ihn gleichzeitig an alle anderen Listen desselben Typs zu binden.
Wenn Sie benutzerdefinierte SharePoint-Lösungen entwickeln, die Ereignishandler verwenden, werden Sie feststellen, dass das Binden von Ereignishandlern durch Code erheblich mehr Flexibilität bietet. Sie haben bei diesem Verfahren beispielsweise die Möglichkeit, einen Ereignishandler nur für eine einzelne Liste an ein Ereignis zu binden.
Werfen Sie einen Blick auf ein Beispiel für das Binden des Ereignishandlers für das ItemAdding-Ereignis an die Liste „Sales Leads“:
Dim SalesLeadsList As SPList = Me.Web.Lists("Sales Leads")
    '*** bind event handler to ItemAdding event
    SalesLeadsList.EventReceivers.Add( _
        SPEventReceiverType.ItemAdding, _
        GetType(MyItemEvents).Assembly.FullName, _
        GetType(MyItemEvents).FullName)
Jedes SPList-Objekt macht eine EventReceivers-Sammlung verfügbar. Die EventReceivers-Sammlung stellt eine Add-Methode mit drei verschiedenen überladenen Implementierungen bereit. Die Add-Methode in diesem letzten Beispiel repräsentiert das einfachste Verfahren, das die Übergabe von drei Parametern erfordert. Wenn Sie einen Ereignishandler durch Code binden möchten, müssen Sie mindestens den Namen der Assembly, den Namespace-kompatiblen Klassennamen und den Ereignistyp bereitstellen, indem Sie die SPEventReceiverType-Enumeration aus dem WSS-Objektmodell verwenden.
Beachten Sie, dass in Ihrem Code nicht nur Literalzeichenfolgenwerte eingebettet werden können, in denen der vierteilige Name der Assembly und der Namespace-kompatible Name der Empfängerklasse enthalten sind, sondern auch der weiter oben gezeigte Code verwendet werden kann, um diese Werte dynamisch zu ermitteln.
Der Aufruf der Add-Methode stellt das einfachste Verfahren dar, aber es ist nicht flexibel genug für alle Szenarios. Abbildung 8 veranschaulicht ein komplizierteres Verfahren, bei dem die Ereignishandlerbindung durch direktes Programmieren mit einem SPEventReceiverDefinition-Objekt durchgeführt wird. Dies bietet Ihnen die Möglichkeit, der Bindung eine spezifische GUID zuzuweisen, damit sie leichter hinzugefügt bzw. entfernt werden kann. Darüber hinaus ermöglicht dies ein Initialisieren der SequenceNumber-Eigenschaft und der Data-Eigenschaft.
Dim SalesLeadsList As SPList = Me.Web.Lists("Sales Leads")

Dim receivers As SPEventReceiverDefinitionCollection
receivers = SalesLeadsList.EventReceivers
Dim ItemAddingDefId As Guid
ItemAddingDefId = New Guid("D6C452E5-95D4-45e8-934C-30F785867000")
If (Not receivers.EventReceiverDefinitionExist(ItemAddingDefId)) Then
    Dim ItemAddingDef As SPEventReceiverDefinition
    ItemAddingDef = receivers.Add(ItemAddingDefId)
    ItemAddingDef.Name = "ItemAddingHandler"
    ItemAddingDef.Type = SPEventReceiverType.ItemAdding
    ItemAddingDef.Assembly = GetType(MyItemEvents).Assembly.FullName
    ItemAddingDef.Class = GetType(MyItemEvents).FullName
    ItemAddingDef.Data = "My Custom Data"
    ItemAddingDef.SequenceNumber = 1001
    ItemAddingDef.Update()
End If

In diesem Artikel konnten die Möglichkeiten der Bindung von Ereignishandlern über das WSS-Objektmodell nur grob angerissen werden. An dieser Stelle wurde als Beispiel die EventReceivers-Sammlung einer Liste vorgeführt, aber es gibt noch verschiedene weitere Typen im WSS-Objektmodell, die über eine EventReceivers-Sammlung verfügen und als Ereignishosts verwendet werden können. Beispiele für derartige Typen sind Websites, Inhaltstypen und Dateien.

Senden Sie Fragen und Kommentare für Ted an mmoffice@microsoft.com.


Ted Pattison ist Autor, Schulungsleiter und SharePoint-MVP und lebt in Tampa, Florida, USA. Ted hat gerade sein Buch mit dem Titel „Inside Windows SharePoint Services 3.0“ für Microsoft Press fertig gestellt. Zusätzlich bietet er über sein Unternehmen Ted Pattison Group (www.TedPattison.net) Schulungen zu SharePoint für professionelle Entwickler an.

Page view tracker