Verwenden von Ereignisempfängern in SharePoint Foundation 2010 (Teil 2 von 2)

SharePoint 2010

Zusammenfassung: Mithilfe von Ereignisempfängern in Microsoft SharePoint Foundation 2010 kann Ihr benutzerdefinierter Code auf bestimmte Aktionen in einem SharePoint-Objekt reagieren. Praktische Beispiele in diesem Artikel zeigen, wie Sie mithilfe von Ereignissen Ihre SharePoint-Anwendungen optimieren.

Nachdem Sie nun über solide Kenntnisse des Ereignismodells in Microsoft SharePoint Foundation 2010 verfügen, können Sie mit dem Erstellen der Ereignisbehandlung im eigenen Code beginnen. Im Rest dieses Artikels werden fünf Beispiele vorgestellt, in denen das SharePoint-Ereignismodell auf verschiedene Weise verwendet wird:

  • Senden von Ankündigungen Ankündigungen, die Hunderten von Websites in einer Websitesammlung hinzugefügt wurden, werden im Announcements-Webpart auf der Stammwebsite angezeigt.

  • Aufteilen von Elementen Wenn ein Element einer Liste hinzugefügt wird, wird das Element automatisch in mindestens zwei Elemente aufgeteilt. Dieses Beispiel veranschaulicht außerdem das Stornieren eines Ereignisses ohne Fehlermeldung und mithilfe von Eigenschaftenbehälter in einem Vorabereignisempfänger.

  • Nachverfolgen von Dokumentquellen Wenn ein Dokument in einer Dokumentbibliothek bearbeitet wird, wird eine Metadateneigenschaft aktualisiert. Dieses Beispiel veranschaulicht die Eigenschaftenheraufstufung und ‑herabstufung.

  • Stornieren und Umleiten Wenn ein Benutzervorgang storniert wird, wird der Benutzer an eine Fehlerseite umgeleitet.

  • Protokollieren von Ereignissen Jedes Ereignis, das in einer Websitesammlung auftritt, wird als Listenelement in einer auf der Website gespeicherten Liste protokolliert.

Für jedes dieser Beispiele können Sie eine Microsoft Visual Studio-Projektmappe herunterladen:

Als Orientierung für die Beispiele finden Sie im Folgenden eine Übersicht über das SharePoint-Ereignismodell. In Tabelle 3 sind alle SharePoint Foundation 2010-Ereignisempfänger gruppiert nach dem Gültigkeitsbereich, die zugehörigen Klassen sowie die Ereignishosts, denen sie zugeordnet werden können, aufgelistet.

Tabelle 3. Ereignisempfänger gruppiert nach dem Gültigkeitsbereich

Bereich

Methoden

Klasse

Hosts

Websitesammlung

  • SiteDeleting

  • SiteDeleted

SPWebEventReceiver

  • Websitesammlung

Web

  • WebAdding

  • WebProvisioned

  • WebDeleting

  • WebDeleted

  • WebMoving

  • WebMoved

SPWebEventReceiver

  • Websitesammlungsweb

Liste

  • ListAdding

  • ListAdded

  • ListDeleting

  • ListDeleted

SPListEventReceiver

  • Websitesammlungsweb

  • Listenvorlagen

Liste

  • EmailReceived

SPEmailEventReceiver

  • Websitesammlung

  • Web

  • Listenvorlagen

  • Listeninstanzen

Feld

  • FieldAdding

  • FieldAdded

  • FieldUpdating

  • FieldUpdated

  • FieldDeleting

  • FieldDeleted

SPListEventReceiver

  • Websitesammlung

  • Web

  • Listenvorlagen

  • Listeninstanzen

Element

  • ItemAdding

  • ItemAdded

  • ItemUpdating

  • ItemUpdated

  • ItemDeleting

  • ItemDeleted

  • ItemCheckingIn

  • ItemCheckedIn

  • ItemCheckingOut

  • ItemCheckedOut

  • ItemFileMoving

  • ItemFileMoved

  • ItemFileConverted

  • ItemAttachmentAdding

  • ItemAttachmentAdded

  • ItemAttachmentDeleting

  • ItemAttachmentDeleted

SPItemEventReceiver

  • Websitesammlung

  • Web

  • Listenvorlagen

  • Listeninstanzen

  • Inhaltstyp

Workflow

  • WorkflowStarting

  • WorkflowStarted

  • WorkflowCompleted

  • WorkflowPostponed

SPWorkflowEventReceiver

  • Websitesammlung

  • Web

  • Listenvorlagen

  • Listeninstanzen

  • Inhaltstyp

In diesem Beispiel ist eine Websitesammlung mit Hunderten einzelner Websites vorhanden. In der Stammwebsite gibt es ein Announcements-Webpart. In diesem Szenario sollen alle Ankündigungen, die auf einer der Websites angezeigt werden, im Announcements-Webpart, das Sie in der Stammwebsite der Websitesammlung platziert haben, angezeigt werden.

Klicken Sie, um Code abzurufen. Beispielcode herunterladen: SharePoint 2010: Verwenden von Ereignisempfängern, Beispiel 1: Senden von Ankündigungen (in englischer Sprache)

Entwurf

Davon ausgehend, dass in der Stammwebsite der Websitesammlung eine Liste Announcements vorhanden ist, muss zunächst der Homepage der Stammwebsite das Webpart für diese Liste hinzugefügt werden.

So fügen Sie ein Announcements-Webpart hinzu

  1. Navigieren Sie zur Homepage der Stammwebsite Ihrer Websitesammlung.

  2. Klicken Sie auf die Registerkarte Seite, und klicken Sie dann auf Seite bearbeiten.

  3. Klicken Sie auf die Registerkarte Einfügen, und klicken Sie dann auf Vorhandene Liste. Alle Listen und Dokumentbibliotheken der Stammwebsite werden angezeigt.

  4. Wählen Sie die Liste Announcements aus, und klicken Sie auf Hinzufügen.

Im nächsten Schritt müssen Sie alle Ankündigungen kopieren, die auf einer der Unterwebsites in der Liste Announcements der Stammwebsite bereitgestellt wurden. Dazu erstellen Sie einen ItemAdded-Ereignisempfänger, mit dem alle Elemente, die einer Liste hinzugefügt wurden (basierend auf der Announcements-Listenvorlage), in die Liste Announcements in der Stammwebsite kopiert werden. Die Ereignislogik sollte für jede Ankündigungsliste ausgelöst werden, die in einer Website der Websitesammlung vorhanden ist (mit Ausnahme der Liste Announcements der Stammwebsite).

Implementierung

Erstellen Sie in Microsoft Visual Studio 2010 ein Projekt basierend auf der Ereignisempfänger-Projektvorlage von SharePoint 2010. Wählen Sie die Bereitstellung der Lösung als Sandkastenlösung aus. Wählen Sie im Assistenten zum Anpassen von SharePoint die Liste Announcements als Ereignisquelle und ItemAdded als zu überschreibendes Ereignis aus (siehe Abbildung 6).

Abbildung 6. Assistent zum Anpassen von SharePoint

Assistenten zum Anpassen von SharePoint

Hiermit wird wie im folgenden Codeauszug veranschaulicht ein neues Feature mit Webgültigkeitsbereich und einem <Receivers>-Element, mit dem der ItemAdded-Ereignisempfänger an die Announcements-Listenvorlage gebunden wird (ListTemplateId="104"), erstellt.

<Receivers ListTemplateId="104">
  <Receiver>
    <Name>EventReceiver1ItemAdded</Name>
    <Type>ItemAdded</Type>
    <Assembly>$SharePoint.Project.AssemblyFullName$</Assembly>
    <Class>BroadcastAnn.EventReceiver1.EventReceiver1</Class>
    <SequenceNumber>10000</SequenceNumber>
  </Receiver>
</Receivers>

In Tabelle 4 werden die verschiedenen Elemente des <Receiver>-Elements erläutert.

Tabelle 4. Elemente des Receiver-Elements

Element

Beschreibung

Wert in diesem Beispiel

Name

Der Name der Ereignisempfängerbindung.

EventReceiver1ItemAdded. Sie können einen eigenen Namen eingeben.

Type

Der Ereignistyp, bei dem es sich um eine Textdarstellung einer der Werte der SPEventType-Enumeration handeln kann.

ItemAdded.

Assembly

Der vollständige Assemblyname der DLL, die den Ereignisempfängercode enthält.

$SharePoint.Project.AssemblyFullName$. Dieser Name wird in den vollständigen Assemblynamen konvertiert, wenn die Lösung von Visual Studio 2010 erstellt wird.

Class

Der Namespace und die Klasse (im Format Namespace.Klasse), die von SPEventReceiverBase erbt und den Ereignisempfängercode enthält.

BroadcastAnn.EventReceiver1.EventReceiver1, wobei "BroadcastAnn.EventReceiver1" der Namespace und "EventReceiver1" der Klassenname ist.

SequenceNumber

Die Ausführungsreihenfolge für das Ereignis. Wenn z. B. zwei ItemAdding-Ereignisse an denselben Ereignishost gebunden sind, wird das Ereignis mit der niedrigeren Sequenznummer zuerst ausgelöst.

10000. Dies ist im Prinzip ein Standardwert.

Synchronization

Ob es sich um ein synchrones oder asynchrones Ereignis handelt. Nachfolgeereignisse sind asynchron.

Da wir die Synchronisierung nicht angegebenen haben und ItemAdded ein Nachfolgeereignis ist, ist der Standardmodus asynchron.

Um das Ereignis für alle Websites in der Websitesammlung auszulösen, muss der Gültigkeitsbereich des Features in "Site" geändert werden. Dadurch wird die Funktionalität aktiviert, wenn wir das Feature auf der Websitesammlung aktivieren, und das Feature muss nicht für jede Unterwebsite aktiviert werden. Beachten Sie, dass sich der Gültigkeitsbereich "Site" eines Features auf die Websitesammlung bezieht (siehe Abbildung 7); der Gültigkeitsbereich "Web" bezieht sich auf die Websites.

Abbildung 7. Festlegen des Featuregültigkeitsbereichs

Festlegen des Featurebereichs

Im nächsten Schritt müssen Sie die Datei EventReceiver1.cs öffnen und dem ItemAdded-Ereignis Code hinzufügen. Mit diesem Code wird das Element, das der Liste Announcements in der Unterwebsite hinzugefügt wurde, in die Liste Announcements in der Stammwebsite kopiert. Außerdem wird dem Titel der Name der Person angefügt, die die Ankündigung gemacht hat, und dem Textkörper wird die URL der Unterwebsite hinzugefügt, in der die Ankündigung gemacht wurde.

public override void ItemAdded(SPItemEventProperties properties)
{
    // Get a reference to the site collection.
    SPSite site = properties.OpenSite();

    // Get a reference to the current site.
    SPWeb currentWeb = properties.OpenWeb();

    // Get a reference to the root site.
    SPWeb rootWeb = site.RootWeb;

    // Skip if the root web is the same as the current web.
    if (rootWeb.Url == currentWeb.Url)
    {
        return;
    }

    // Get the current list.
    SPList currentList = properties.List;

    // Get the announcement list on the root site.
    SPList rootList = rootWeb.Lists["Announcements"];

    // Get the list item that was added.
    SPListItem currentListItem = properties.ListItem;

    // Add the announcement item to the list on the root web.
    SPListItem rootListItem = rootList.Items.Add();
    foreach (SPField field in currentList.Fields)
    {
        if (!field.ReadOnlyField)
        {
            rootListItem[field.Id] = currentListItem[field.Id];
        }
    }

    // Append the user display name to the title.
    rootListItem["Title"] += " - " + properties.UserDisplayName;

    // Append the web URL to the body.
    rootListItem["Body"] += string.Format("This announcements was made by {0} on subweb {1}",
      properties.UserLoginName, properties.WebUrl);

    rootListItem.Update();
}

Nun können Sie die Lösung erstellen und den Debugger starten. Bei diesem Vorgang wird die Lösung erstellt, die Lösung wird in der SharePoint-Websitesammlung bereitgestellt, und der Browser wird auf der Homepage Ihrer Websitesammlung gestartet. Achten Sie unbedingt darauf, dass in der Websitesammlung die Liste Announcements vorhanden ist.

Schließlich erstellen Sie eine neue Unterwebsite basierend auf der Teamwebsitevorlage. Fügen Sie der Liste Announcements ein Element hinzu, und bestätigen Sie, dass eine Kopie des Elements in der Liste Announcements in der Stammwebsite angezeigt wird (siehe Abbildung 8).

Abbildung 8. Der Liste "Announcements" in der Stammwebsite hinzugefügtes Element

Element wurde der Ankündigungsliste der Stammwebsite hinzugefügt

In diesem Beispiel soll einer Liste ein Element hinzugefügt werden, das dann in zwei neue Elemente aufgeteilt werden soll. Wenn z. B. ein Benutzer ein Xbox 360-Bündel hinzufügt, möchten Sie möglicherweise verhindern, dass dieses Element hinzugefügt wird, und stattdessen der Liste zwei andere Elemente hinzufügen: "Xbox 360" und "Kinect". Ein noch besseres Beispiel ist ein Szenario, in dem Sie eine ZIP-Datei hochladen und dann den Inhalt der Datei so extrahieren, dass jede Datei als separates Element hinzugefügt wird.

Zur Unterstützung des Szenarios zum Aufteilen von Elementen wird in diesem Beispiel auch gezeigt, wie eine Aktion ohne Fehlermeldung in einem Vorabereignisempfänger storniert wird.

Klicken Sie, um Code abzurufen. Beispielcode herunterladen: SharePoint 2010: Verwenden von Ereignisempfängern, Beispiel 2: Aufteilen von Elementen (in englischer Sprache)

Entwurf

Dieses Projekt erfordert drei Inhaltstypen zur Darstellung der drei Elemente: "Xbox 360 Bundle", "Xbox 360" bzw. "Kinect". In diesem Szenario benötigen wir nur die Titel der Elemente, alle Inhaltstypen erben vom Inhaltstyp "Items", ohne dass zusätzliche Felder hinzugefügt werden.

Wenn ein neues Element basierend auf dem Inhaltstyp "Xbox 360 Bundle" hinzugefügt wird, soll entweder dieses Element gelöscht werden oder andernfalls das Hinzufügen storniert werden, und anschließend sollen zwei weitere Elemente basierend auf den Inhaltstypen "Xbox 360" und "Kinect" erstellt werden.

Dazu muss zunächst das ItemAdding-Vorabereignis an den Inhaltstyp "Xbox 360 Bundle" gebunden werden. Mit dem ItemAdding-Ereignis werden die beiden anderen Elemente erstellt und das Hinzufügen des aktuellen Elements wird storniert. Da beim Hinzufügen eines "Xbox 360"- oder "Kinect"-Elements keine Logik ausgelöst werden soll, binden wir diese Inhaltstypen nicht an Ereignisempfänger. Der Einfachheit halber werden keine Updates vorgenommen; d. h., wenn der Inhaltstyp eines Elements von "Xbox 360" in "Xbox 360 Bundle" oder "Kinect" geändert wird.

Beim Stornieren des Hinzufügens des Inhaltstyps "Xbox 360 Bundle" soll keine Fehlermeldung angezeigt werden. Da wir in einem Vorabereignis auf das Element, das hinzugefügt wird, zugreifen (bevor ein Commit für die Änderungen in der Inhaltsdatenbank ausgeführt wird), lautet die properties.ListItem-Eigenschaft weiterhin null. Für den Zugriff auf die Elementfelder muss der properties.AfterProperties-Eigenschaftenbehälter verwendet werden. Auf diese Weise kann auf die zu kopierenden Daten (in diesem Beispiel nur der Titel) anhand der internen Feldnamen im Listenschema zugegriffen werden.

Implementierung

Erstellen Sie ein Visual Studio 2010-Projekt basierend auf der Vorlage Leeres SharePoint-Projekt. Wählen Sie die Bereitstellung der Lösung als Sandkastenlösung aus. Klicken Sie mit der rechten Maustaste auf das Projekt, und klicken Sie auf Neues Element hinzufügen. Wählen Sie Inhaltstyp aus, benennen Sie das Element Xbox360Bundle, und klicken Sie auf Hinzufügen. Visual Studio erstellt den Inhaltstyp mit dem Namen Projektname – Xbox360Bundle.

Wichtiger Hinweis Wichtig

Ändern Sie den Namen in der Datei Element.xml unbedingt in Xbox360Bundle.

Wiederholen Sie diese Schritte für die beiden anderen Inhaltstypen, und verwenden Sie die Namen Xbox360 und Kinect.

Klicken Sie anschließend mit der rechten Maustaste auf das Projekt, und fügen Sie ein neues Ereignisempfängerelement mit dem Namen BundleEventReceiver hinzu. Wählen Sie Ein Element wird hinzugefügt aus, und klicken Sie auf Fertig stellen. Bei diesem Schritt wird eine Ereignisempfängerklasse erstellt, mit der das ItemAdding-Ereignis überschrieben wird. Standardmäßig wird das Ereignis jedoch auch an eine Listenvorlage gebunden. Wir möchten das Ereignis anstelle der Listenvorlage an den Inhaltstyp Xbox360Bundle binden. Deshalb muss die Ereignisbindung Elements.xml (siehe das ausgewählte Element in Abbildung 9) gelöscht und die Bindung in der Datei Element.xml für den Inhaltstyp Xbox360Bundle hinzugefügt werden.

Abbildung 9. "Elements.xml"-Bindung

Elements.xml-Bindung

Überprüfen Sie vor dem Hinzufügen der Ereignisempfängerbindung, dass das Inherits-Attribut des Inhaltstyps in Elements.xml auf FALSE und nicht auf TRUE festgelegt ist. Andernfalls funktioniert die Ereignisempfängerbindung für den Inhaltstyp nicht. Da keine Vererbung mehr verwendet wird, müssen wir alle Feldverweise selbst definieren. So muss ein Feldverweis auf das Feld Title hinzugefügt werden. Die Datei Element.xml für den Inhaltstyp Xbox360Bundle sollte in etwa wie folgt aussehen.

<Elements xmlns="http://schemas.microsoft.com/sharepoint/">
  <!-- Parent ContentType: Item (0x01) -->
  <ContentType ID="0x01004497ac28eb9a47fbabee43f48c3f5973"
               Name="Xbox360Bundle"
               Group="Custom Content Types"
               Description="My Content Type"
               Inherits="FALSE"
               Version="0">
    <FieldRefs>
      <FieldRef ID="{fa564e0f-0c70-4ab9-b863-0177e6ddd247}" 
                Name="Title" 
                Required="TRUE" 
                ShowInNewForm="TRUE" 
                ShowInEditForm="TRUE"/>
    </FieldRefs>
    <XmlDocuments>
      <XmlDocument NamespaceURI="http://schemas.microsoft.com/sharepoint/events">
        <spe:Receivers xmlns:spe="http://schemas.microsoft.com/sharepoint/events">
          <Receiver>
            <Name>Item Adding Event</Name>
            <Type>ItemAdding</Type>
            <Assembly>$SharePoint.Project.AssemblyFullName$</Assembly>
            <Class>ItemSplitting.BundleEventReceiver.BundleEventReceiver</Class>
            <SequenceNumber>10000</SequenceNumber>
          </Receiver>
        </spe:Receivers>
      </XmlDocument>
    </XmlDocuments>
  </ContentType>
</Elements>

Nun befassen wir uns mit der Datei BundleEventReceiver.cs und fügen dem ItemAdding-Ereignis Code hinzu, mit dem das Hinzufügen des Xbox360Bundle-Elements storniert wird und zwei neue Elemente basierend auf den Inhaltstypen Xbox360 und Kinect erstellt werden.

public override void ItemAdding(SPItemEventProperties properties)
{
    // Get a reference to the current list.
    SPList list = properties.List;

    // Get the "Xbox360" content type.
    SPContentType xboxContentType = list.ContentTypes["XBox360"];

    // Get the "Kinect" content type.
    SPContentType kinectContentType = list.ContentTypes["Kinect"];

    // If any of the content types are null, they were not created.
    if (xboxContentType == null || kinectContentType == null)
    {
        properties.Status = SPEventReceiverStatus.CancelWithError;
        properties.ErrorMessage = "The Xbox360 and Kinect content types must be present.";
        return;
    }

    // Disable event firing so that ItemAdding is not called recursively.
    this.EventFiringEnabled = false;

    // Create the "Xbox360" item.
    SPListItem xboxItem = list.AddItem();
    xboxItem["Title"] = properties.AfterProperties["Title"] + " (Xbox 360)";
    xboxItem["ContentTypeId"] = xboxContentType.Id;
    xboxItem.Update();

    // Create the "Kinect" item.
    SPListItem kinectItem = list.AddItem();
    kinectItem["Title"] = properties.AfterProperties["Title"] + " (Kinect)";
    kinectItem["ContentTypeId"] = kinectContentType.Id;
    kinectItem.Update();

    // Re-enable event firing.
    this.EventFiringEnabled = true;

    // Cancel the creation of the "Xbox360Bundle" item but don't throw an error.
    properties.Status = SPEventReceiverStatus.CancelNoError;
}

Beachten Sie beim vorherigen Code die folgenden wichtigen Details:

  • Wenn Inhaltstypen nicht an die Liste gebunden sind, wird das ItemAdding-Ereignis storniert und die Fehlermeldung "The Xbox360 and Kinect content types must be present." angezeigt. Beachten Sie, dass es nicht erforderlich ist, die Anweisung properties.Cancel = true hinzuzufügen.

  • Zur Vermeidung rekursiver Aufrufe von ItemAdding (bis zu einem bestimmten Grenzwert in der Aufrufliste), deaktivieren wir die Ereignisauslösung, bevor wir Elemente im ItemAdding-Ereignis hinzufügen. Nachdem alle Elemente hinzugefügt wurden, aktivieren wir die Ereignisauslösung wieder.

  • Wir verwenden den Ausdruck properties.AfterProperties["field"] anstelle von properties.ListITem["field"], da ItemAdding ein Vorabereignis ist. Dies bedeutet, dass das Listenelement noch nicht erstellt ist und dass properties.ListItem gleich null ist.

  • Wir möchten das Element, das aufgeteilt werden soll, nicht hinzufügen. Deshalb stornieren wir das Ereignis, ohne dass ein Fehler gemeldet wird, mithilfe der Anweisung properties.Status = SPEventReceiverStatus.CancelNoError. Fügen Sie properties.Cancel=true nicht hinzu. Dadurch würde das Verhalten außer Kraft gesetzt und deshalb ein Fehler gemeldet.

Nun können Sie die Lösung erstellen und den Debugger starten. Bei diesem Vorgang wird die Lösung erstellt, die Lösung wird in der SharePoint-Websitesammlung bereitgestellt, und der Browser wird auf der Homepage Ihrer Websitesammlung gestartet.

Im nächsten Schritt erstellen Sie eine neue Liste und binden die drei Inhaltstypen an diese Liste. Stellen Sie zunächst sicher, dass der Liste Inhaltstypen hinzugefügt werden dürfen. Zu diesem Zweck können Sie auf der Seite mit den erweiterten Einstellungen der Liste Verwaltung von Inhaltstypen zulassen auf Ja festlegen. Anschließend fügen Sie die drei Inhaltstypen wie in Abbildung 10 dargestellt hinzu.

Abbildung 10. Binden von Inhaltstypen

Binden von Inhaltstypen

Nun können wir wie in Abbildung 11 dargestellt in der Liste ein neues Element basierend auf dem Inhaltstyp Xbox360Bundle erstellen.

Abbildung 11. Erstellen eines neuen Elements

Erstellen eines neuen Elements

Wenn Sie auf Speichern klicken, werden Sie bemerken, dass das Element nicht hinzugefügt wird. Stattdessen werden zwei andere Elemente hinzugefügt: "Xbox360" und "Kinect". Wenn Sie den Inhaltstyp Xbox360 oder Kinect aus der Liste entfernen, wird beim Speichern eine Fehlermeldung angezeigt.

Das Bearbeiten von Dokumenteigenschaften mithilfe von Ereignisempfängern ist ein leistungsstarkes Feature. In diesem Beispiel wird die Vorgehensweise durch das Implementieren von Eigenschaftenheraufstufungen und ‑herabstufungen mit Ereignisempfängern gezeigt. Mithilfe der Eigenschaftenheraufstufung und ‑herabstufung können Sie Dokumentmetadaten direkt im Ereignisempfängercode lesen, hinzufügen oder aktualisieren, wenn ein Dokument einer Dokumentbibliothek hinzugefügt wird oder sogar wenn ein Dokument in einer Dokumentbibliothek bearbeitet wird.

In diesem Beispiel legen wir beim Bearbeiten des Dokuments den Wert der Source-Metadateneigenschaft auf den Titel der Dokumentbibliothek fest.

Klicken Sie, um Code abzurufen. Beispielcode herunterladen: SharePoint 2010: Verwenden von Ereignisempfängern, Beispiel 3: Nachverfolgen von Dokumentquellen (in englischer Sprache)

Entwurf

In diesem Beispiel erstellen wir einen ItemUpdating-Ereignisempfänger, der an alle Dokumentbibliotheken in der Website gebunden wird. Beim Speichern eines Dokuments in der Dokumentbibliothek wird die Source-Metadateneigenschaften durch den Ereignishandlercode mit dem Wert des Dokumentbibliothektitels aktualisiert.

Zum Testen dieses Verhaltens erstellen wir zwei Dokumentbibliotheken und fügen ihnen jeweils ein Feld Source hinzu. Anschließend laden wir ein Microsoft Word-Dokument in die erste Dokumentbibliothek hoch und speichern es. Danach laden wird dieses Word-Dokument herunter, überprüfen dessen Metadaten mit dem Word-Client und laden das Dokument in die andere Dokumentbibliothek hoch. Beim Hochladen sollte der Wert des Felds Source noch mit dem Titel der Dokumentbibliothek identisch sein, in die das Dokument zuerst hochgeladen wurde. Wenn wir dann jedoch das Dokument in der neuen Dokumentbibliothek speichern, sollte dessen Source-Eigenschaftswert in den Titel der neuen Dokumentbibliothek geändert werden. Die Metadaten des neu gespeicherten Dokuments werden überprüft, um das erwartete Verhalten zu bestätigen.

Implementierung

Mit dem folgenden Code wird das ItemUpdating-Ereignis implementiert.

public override void ItemUpdating(SPItemEventProperties properties)
{
    string fieldInternalName = properties.List.Fields["Source"].InternalName;
    properties.AfterProperties[fieldInternalName] = properties.ListTitle;
}

Erstellen Sie die Lösung, und starten Sie den Debugger. Bei diesem Vorgang wird die Lösung erstellt, die Lösung wird in der SharePoint-Websitesammlung bereitgestellt, und der Browser wird auf der Homepage Ihrer Websitesammlung gestartet.

Erstellen Sie eine neue Dokumentbibliothek, und fügen Sie ihr das Feld Source hinzu. Zum Hinzufügen des Felds wechseln Sie zu den Dokumentbibliothekseinstellungen, klicken Sie auf Aus vorhandenen Websitespalten hinzufügen, wählen Sie das Feld Source aus, klicken Sie auf Hinzufügen, und klicken Sie dann auf OK.

Im nächsten Schritt laden Sie ein Word-Dokument in diese Dokumentbibliothek hoch. Beachten Sie, dass das Feld Source einen leeren Wert aufweist. Wenn Sie jedoch auf Speichern klicken, wird der Wert des Felds Source in den Titel der Dokumentbibliothek geändert.

Laden Sie eine Kopie des Dokuments auf den lokalen Computer herunter. Erstellen Sie eine neue Dokumentbibliothek, und fügen Sie ihr das Feld Source hinzu. Laden Sie das Dokument in diese neue Dokumentbibliothek hoch. Beachten Sie beim Hochladen, dass der Wert des Felds Source noch dem Titel der Dokumentbibliothek entspricht, in der das Dokument zuletzt gespeichert wurde.

Klicken Sie nun auf Save. Der Wert des Felds Source wird in den Titel der neuen Dokumentbibliothek geändert.

Dieses Beispiel basiert auf einem Szenario, in dem ein Benutzervorgang storniert wird (bei einem Fehler oder aus anderen Gründen) und der Benutzer an eine benutzerdefinierte Fehlermeldungsseite umgeleitet wird.

Klicken Sie, um Code abzurufen. Beispielcode herunterladen: SharePoint 2010: Verwenden von Ereignisempfängern, Beispiel 4: Stornieren und Umleiten (in englischer Sprache)

Entwurf

In diesem Beispiel erstellen wir einen Webereignisempfänger und fügen dem WebMoving-Ereignis Code hinzu, mit dem das Umbenennen der Website-URL storniert und der Benutzer an die Seite Websiteeinstellungen umgeleitet wird. (Der Einfachheit halber wird in diesem Beispiel die Seite Websiteeinstellungen verwendet, aber Sie können den Benutzer an eine benutzerdefinierte Fehlermeldungsseite umleiten.)

Implementierung

Erstellen Sie ein Visual Studio 2010-Projekt basierend auf der Ereignisempfänger-Projektvorlage von SharePoint 2010. Wählen Sie die Bereitstellung der Lösung als Sandkastenlösung aus. Wählen Sie im Assistenten zum Anpassen von SharePoint Webereignisse als Ereignisquelle und Eine Site wird verschoben als Ereignis aus. Ändern Sie den Gültigkeitsbereich des Features in "Site".

Fügen Sie den folgenden Code hinzu, mit dem das Umbenennungsereignis storniert und der Benutzer an die Seite Websiteeinstellungen umgeleitet wird.

public override void WebMoving(SPWebEventProperties properties)
{
    properties.Status = SPEventReceiverStatus.CancelWithRedirectUrl;
    properties.RedirectUrl = properties.Web.ServerRelativeUrl +
      "/_layouts/settings.aspx";
}

Erstellen Sie die Lösung, und starten Sie den Debugger. Bei diesem Vorgang wird die Lösung erstellt, die Lösung wird in der SharePoint-Websitesammlung bereitgestellt, und der Browser wird auf der Homepage Ihrer Websitesammlung gestartet.

Im nächsten Schritt erstellen Sie eine Unterwebsite und versuchen sie umzubenennen. (Eine neue Unterwebsite muss erstellt werden, da eine Stammwebsite nicht umbenannt werden kann.) Zum Umbenennen der Website wechseln Sie zur Seite Websiteeinstellungen. Klicken Sie im Abschnitt Aussehen und Verhalten auf Titel, Beschreibung und Symbol. Geben Sie in das Feld URL-Name einen neuen Websitenamen ein. Klicken Sie auf OK.

Beim Versuch, die Website umzubenennen, wird ein Fehler gemeldet und Sie werden an die Seite Websiteeinstellungen umgeleitet.

In diesem Beispiel wird ein Szenario verwendet, bei dem mit Ereignisprotokollierungscode jedes Ereignis, das in einer Websitesammlung vorkommt, erfasst wird und jedes Ereignis als Element in einer in der Website verwalteten Liste aufgezeichnet wird.

Klicken Sie, um Code abzurufen. Beispielcode herunterladen: SharePoint 2010: Verwenden von Ereignisempfängern, Beispiel 5: Protokollieren von Ereignissen (in englischer Sprache)

Entwurf

In Tabelle 5 sind alle SharePoint-Ereignisse aufgelistet und die Listen angegeben, in denen die verschiedenen Ereignisse protokolliert werden. Die Ereignisse SiteDeleting und SiteDeleted werden nicht protokolliert, da sie beim Löschen der Websitesammlung ausgelöst werden.

Tabelle 5. Ereignisse und Protokolle

Ereignisse

Klasse

Protokollierungsliste

SiteDeleting, SiteDeleted

SPWebEventReceiver

[nicht protokolliert]

WebAdding, WebProvisioned, WebDeleting, WebDeleted, WebMoving, WebMoved

SPWebEventReceiver

WebEventLogger

ListAdding, ListAdded, ListDeleting, ListDeleted

SPListEventReceiver

ListEventLogger

EmailReceived

SPEmailEventReceiver

ListEventLogger

FieldAdding, FieldAdded, FieldUpdating, FieldUpdated, FieldDeleting, FieldDeleted

SPListEventReceiver

ListEventLogger

ItemAdding, ItemAdded, ItemUpdating, ItemUpdated, ItemDeleting, ItemDeleted, ItemCheckingIn, ItemCheckedIn, ItemCheckingOut, ItemCheckedOut, ItemFileMoving, ItemFileMoved, ItemFileConverted, ItemAttachmentAdding, ItemAttachmentAdded, ItemAttachmentDeleting, ItemAttachmentDeleted

SPItemEventReceiver

ListItemEventLogger

WorkflowStarting, WorkflowStarted, WorkflowCompleted, WorkflowPostponed

SPWorkflowEventReceiver

WorkflowEventLogger

In diesem Beispiel werden alle Ereignismethoden aller Klassen überschrieben, die von SPEventReceiverBase erben. Außerdem wird eine zusätzliche Klasse in Common.cs erstellt, die Hilfsmethoden enthält. Wir binden die Nachfolgeereignisse als synchrone Ereignisse, sodass die entsprechenden Listen vor Abschluss des Benutzervorgangs aktualisiert werden. Das Feature, das die Ereignisbindungen ermöglicht, erhält den Gültigkeitsbereich "Site", sodass damit alle Ereignisse verwaltet werden, die in allen Websites der Websitesammlung ausgelöst werden.

Implementierung

Erstellen Sie ein Visual Studio 2010-Projekt basierend auf der Vorlage Leeres SharePoint-Projekt. Wählen Sie die Bereitstellung der Lösung als Sandkastenlösung aus.

Klicken Sie für jeden Ereignistyp in Tabelle 6 mit der rechten Maustaste auf das Projekt, klicken Sie auf Hinzufügen, zeigen Sie auf Neues Element, und klicken Sie auf Ereignisempfänger. Wählen Sie die in der Tabelle aufgelisteten Ereigniseigenschaften aus, und klicken Sie auf Fertig stellen.

Tabelle 6. Eigenschaften für neue Ereignisempfänger

Ereignistyp

Element

Ereignisse

Web

Keines

Alle Ereignisse

Liste

Keines

Alle Ereignisse

Listenelement

Benutzerdefinierte Liste

Alle Ereignisse außer Kontextereignissen

Listen-E-Mail

Benutzerdefinierte Liste

Alle Ereignisse

Listenworkflow

Benutzerdefinierte Liste

Alle Ereignisse

Zur Verwaltung aller Listenelementereignisse, E-Mail-Ereignisse und Workflowereignisse, die in einer beliebigen Liste ausgelöst werden (nicht nur in benutzerdefinierten Listen), entfernen Sie die ListTemplateId-Attribute aus den <Receivers>-Elementen. (Ändern Sie <Receivers ListTemplateId="100"> einfach in <Receivers>.)

Nachfolgeereignisse sind standardmäßig asynchron. Alle unsere Nachfolgeereignisse müssen synchron sein. Fügen Sie deshalb das <Synchronization>-Element hinzu, und legen Sie dessen Wert für jedes <Receiver>-Element in jeder Datei Elements.xml auf Synchronous fest. Beispielsweise sollte das WebDeleted-Ereignis in etwa wie folgt aussehen.

<Receiver>
  <Name>EventReceiver1WebDeleted</Name>
  <Type>WebDeleted</Type>
  <Assembly>$SharePoint.Project.AssemblyFullName$</Assembly>
  <Class>PTCEventLogger.EventReceiver1.EventReceiver1</Class>
  <SequenceNumber>10000</SequenceNumber>
  <Synchronization>Synchronous</Synchronization>
</Receiver>

Ändern Sie den Featurebereich in "Site", um Ereignisse zu verwalten, die in der gesamten Websitesammlung ausgelöst werden. Beachten Sie, dass das Erstellen einer neuen Unterwebsite das Auslösen von Ereignissen für die Websiteerstellung und alle anderen Elemente, die der Website hinzugefügt werden, bedeutet. Dadurch könnten in einer Lösung mit eingeschränkter Sicherheitsstufe zu viele Ressourcen beansprucht werden, weshalb das Erstellen der Website möglicherweise fehlschlägt. Dieses potenzielle Problem können Sie umgehen, indem Sie in den Projekteigenschaften Sandkastenlösung in False ändern oder indem Sie den Featurebereich wieder auf "Web" zurücksetzen.

Im nächsten Schritt fügen Sie dem Projekt die Klasse namens common hinzu, und platzieren Sie in der Datei namens Common.cs. Fügen Sie dieser Klasse die folgenden drei Hilfsmethoden hinzu.

  • IsBeforeEvent Gibt an, ob es sich bei einem Ereignis um ein Vorab- oder Nachfolgereignis handelt.

    /// <summary>
    /// Indicates whether an event is a Before event or an After event.
    /// </summary>
    /// <param name="eventType"></param>
    /// <returns></returns>
    private static bool IsBeforeEvent(SPEventReceiverType eventType)
    {
        return (eventType < SPEventReceiverType.ItemAdded) ? true : false;
    }
    
  • EnsureLogList Bestimmt, ob bereits eine Protokollliste vorhanden ist. Falls dies der Fall ist, erhalten wir einen Verweis auf diese Liste. Andernfalls erstellen wir die Liste und geben einen Verweis darauf zurück.

    /// <summary>
    /// Ensures that the Logs list with the specified name is created.
    /// </summary>
    /// <param name="web"></param>
    /// <param name="listName"></param>
    /// <returns></returns>
    private static SPList EnsureLogList(SPWeb web, string listName)
    {
        SPList list = null;
        try
        {
            list = web.Lists[listName];
        }
        catch
        {
            // Create list.
            Guid listGuid = web.Lists.Add(listName, listName, SPListTemplateType.GenericList);
            list = web.Lists[listGuid];
            list.OnQuickLaunch = true;
    
            // Add the fields to the list.
            // No need to add "Title" because it is added by default.
            // We use it to set the event name.
            list.Fields.Add("Event", SPFieldType.Text, true);
            list.Fields.Add("Before", SPFieldType.Boolean, true);
            list.Fields.Add("Date", SPFieldType.DateTime, true);
            list.Fields.Add("Details", SPFieldType.Note, false);
    
            // Specify which fields to view.
            SPView view = list.DefaultView;
            view.ViewFields.Add("Event");
            view.ViewFields.Add("Before");
            view.ViewFields.Add("Date");
            view.ViewFields.Add("Details");
            view.Update();
    
            list.Update();
        }
    
        return list;
    }
    
  • LogEvent Erstellt ein neues Element in der angegebenen Liste und protokolliert die Ereignisdetails in diesem Element.

    /// <summary>
    /// Log the event to the specified list.
    /// </summary>
    /// <param name="web"></param>
    /// <param name="listName"></param>
    /// <param name="eventType"></param>
    /// <param name="details"></param>
    public static void LogEvent(SPWeb web, string listName, SPEventReceiverType eventType, 
      string details)
    {
        SPList logList = Common.EnsureLogList(web, listName);
        SPListItem logItem = logList.Items.Add();
        logItem["Title"] = string.Format("{0} triggered at {1}", eventType, DateTime.Now);
        logItem["Event"] = eventType.ToString();
        logItem["Before"] = Common.IsBeforeEvent(eventType);
        logItem["Date"] = DateTime.Now;
        logItem["Details"] = details;
        logItem.Update();
    }
    

Für jede Klasse, die von SPWebEventReceiver, SPListEventReceiver, SPEmailEventReceiver, SPItemEventReceiver oder SPWorkflowEventReceiver erbt, müssen Sie eine Log-Methode für die Protokollierung der Ereigniseigenschaften in der in entsprechenden Liste erstellen. Außerdem müssen Sie alle überschriebenen Methoden ändern, damit sie diese Log-Methoden aufrufen. Die folgenden Codeauszüge veranschaulichen die Vorgehensweise für die verschiedenen Ereignisempfänger.

  • SPWebEventReceiver Ändern Sie alle überschriebenen Ereignisse. Es folgt ein Beispiel für die Vorgehensweise zum Ändern eines dieser Ereignisse.

    public override void WebProvisioned(SPWebEventProperties properties)
    {
        this.LogWebEventProperties(properties);
    }
    

    Fügen Sie die Log-Methode wie im folgenden Code gezeigt hinzu.

    private void LogWebEventProperties(SPWebEventProperties properties)
    {
        // Specify the log list name.
        string listName = "WebEventLogger";
    
        // Create string builder object.
        StringBuilder sb = new StringBuilder();
    
        // Add properties that do not throw exceptions.
        sb.AppendFormat("Cancel: {0}\n", properties.Cancel);
        sb.AppendFormat("ErrorMessage: {0}\n", properties.ErrorMessage);
        sb.AppendFormat("EventType: {0}\n", properties.EventType);
        sb.AppendFormat("FullUrl: {0}\n", properties.FullUrl);
        sb.AppendFormat("NewServerRelativeUrl: {0}\n", properties.NewServerRelativeUrl);
        sb.AppendFormat("ParentWebId: {0}\n", properties.ParentWebId);
        sb.AppendFormat("ReceiverData: {0}\n", properties.ReceiverData);
        sb.AppendFormat("RedirectUrl: {0}\n", properties.RedirectUrl);
        sb.AppendFormat("ServerRelativeUrl: {0}\n", properties.ServerRelativeUrl);
        sb.AppendFormat("SiteId: {0}\n", properties.SiteId);
        sb.AppendFormat("Status: {0}\n", properties.Status);
        sb.AppendFormat("UserDisplayName: {0}\n", properties.UserDisplayName);
        sb.AppendFormat("UserLoginName: {0}\n", properties.UserLoginName);
        sb.AppendFormat("WebId: {0}\n", properties.WebId);
        sb.AppendFormat("Web: {0}\n", properties.Web);
    
        // Log the event to the list.
        this.EventFiringEnabled = false;
        Common.LogEvent(properties.Web, listName, properties.EventType, sb.ToString());
        this.EventFiringEnabled = true;
    }
    
  • SPListEventReceiver Ändern Sie alle überschriebenen Ereignisse. Es folgt ein Beispiel für die Vorgehensweise zum Ändern eines dieser Ereignisse.

    public override void FieldAdded(SPListEventProperties properties)
    {
        this.LogListEventProperties(properties);
    }
    

    Fügen Sie die Log-Methode wie im folgenden Code gezeigt hinzu.

    private void LogListEventProperties(SPListEventProperties properties)
    {
        // Specify the log list name.
        string listName = "ListEventLogger";
    
        // Create the string builder object.
        StringBuilder sb = new StringBuilder();
    
        // Add properties that do not throw exceptions.
        sb.AppendFormat("Cancel: {0}\n", properties.Cancel);
        sb.AppendFormat("ErrorMessage: {0}\n", properties.ErrorMessage);
        sb.AppendFormat("EventType: {0}\n", properties.EventType);
        sb.AppendFormat("FeatureId: {0}\n", properties.FeatureId);
        sb.AppendFormat("FieldName: {0}\n", properties.FieldName);
        sb.AppendFormat("FieldXml: {0}\n", properties.FieldXml);
        sb.AppendFormat("ListId: {0}\n", properties.ListId);
        sb.AppendFormat("ListTitle: {0}\n", properties.ListTitle);
        sb.AppendFormat("ReceiverData: {0}\n", properties.ReceiverData);
        sb.AppendFormat("RedirectUrl: {0}\n", properties.RedirectUrl);
        sb.AppendFormat("SiteId: {0}\n", properties.SiteId);
        sb.AppendFormat("Status: {0}\n", properties.Status);
        sb.AppendFormat("TemplateId: {0}\n", properties.TemplateId);
        sb.AppendFormat("UserDisplayName: {0}\n", properties.UserDisplayName);
        sb.AppendFormat("UserLoginName: {0}\n", properties.UserLoginName);
        sb.AppendFormat("WebId: {0}\n", properties.WebId);
        sb.AppendFormat("WebUrl: {0}\n", properties.WebUrl);
        sb.AppendFormat("Web: {0}\n", properties.Web);
        sb.AppendFormat("List: {0}\n", properties.List);
    
        // Add properties that might throw exceptions.
        try
        {
            sb.AppendFormat("Field: {0}\n", properties.Field);
        }
        catch (Exception e)
        {
            sb.AppendFormat("\nError accessing properties.Field:\n\n {0}", e);
        }
    
        // Log the event to the list.
        this.EventFiringEnabled = false;
        Common.LogEvent(properties.Web, listName, properties.EventType, sb.ToString());
        this.EventFiringEnabled = true;
    }
    
  • SPEmailEventReceiver Ändern Sie das EmailReceived-Ereignis wie folgt.

    public override void EmailReceived(SPList list, SPEmailMessage emailMessage, String receiverData)
    {
        // Specify the log list name.
        string listName = "ListEmailEventLogger";
    
        // Create the string builder object.
        StringBuilder sb = new StringBuilder();
    
        // Add the email message properties.
        sb.AppendFormat("From:\t {0}\n", emailMessage.Sender);
        sb.AppendFormat("To:\t {0}\n", emailMessage.Headers["To"]);
        sb.AppendFormat("Subject:\t {0}\n", emailMessage.Headers["Subject"]);
        sb.AppendFormat("Body:\t {0}\n", emailMessage.PlainTextBody);
               
        // Log the event to the list.
        Common.LogEvent(list.ParentWeb, listName, SPEventReceiverType.EmailReceived, sb.ToString());
    }
    
  • SPItemEventReceiver Ändern Sie alle überschriebenen Ereignisse. Es folgt ein Beispiel für die Vorgehensweise zum Ändern eines dieser Ereignisse.

    public override void ItemAttachmentAdded(SPItemEventProperties properties)
    {
        this.LogItemEventProperties(properties);
    }
    Add the log method.
    private void LogItemEventProperties(SPItemEventProperties properties)
    {
        // Specify the log list name.
        string listName = "ListItemEventLogger";
    
        // Create the string builder object.
        StringBuilder sb = new StringBuilder();
    
        // Add properties that do not throw exceptions.
        sb.AppendFormat("AfterUrl: {0}\n", properties.AfterUrl);
        sb.AppendFormat("BeforeUrl: {0}\n", properties.BeforeUrl);
        sb.AppendFormat("Cancel: {0}\n", properties.Cancel);
        sb.AppendFormat("CurrentUserId: {0}\n", properties.CurrentUserId);
        sb.AppendFormat("ErrorMessage: {0}\n", properties.ErrorMessage);
        sb.AppendFormat("EventType: {0}\n", properties.EventType);
        sb.AppendFormat("ListId: {0}\n", properties.ListId);
        sb.AppendFormat("ListItemId: {0}\n", properties.ListItemId);
        sb.AppendFormat("ListTitle: {0}\n", properties.ListTitle);
        sb.AppendFormat("ReceiverData: {0}\n", properties.ReceiverData);
        sb.AppendFormat("RedirectUrl: {0}\n", properties.RedirectUrl);
        sb.AppendFormat("RelativeWebUrl: {0}\n", properties.RelativeWebUrl);
        sb.AppendFormat("SiteId: {0}\n", properties.SiteId);
        sb.AppendFormat("Status: {0}\n", properties.Status);
        sb.AppendFormat("UserDisplayName: {0}\n", properties.UserDisplayName);
        sb.AppendFormat("UserLoginName: {0}\n", properties.UserLoginName);
        sb.AppendFormat("Versionless: {0}\n", properties.Versionless);
        sb.AppendFormat("WebUrl: {0}\n", properties.WebUrl);
        sb.AppendFormat("Web: {0}\n", properties.Web);
        sb.AppendFormat("Zone: {0}\n", properties.Zone);
        sb.AppendFormat("Context: {0}\n", properties.Context);
    
        // Add properties that might throw exceptions.
        try
        {
            sb.AppendFormat("ListItem: {0}\n", properties.ListItem);
        }
        catch (Exception e)
        {
            sb.AppendFormat("\nError accessing properties.ListItem:\n\n {0}", e);
        }
    
        // Add AfterProperties property bag.
        sb.AppendFormat("AfterProperties: {0}\n", properties.AfterProperties);
        IEnumerator afterProperties = properties.AfterProperties.GetEnumerator();
        int i = 0;
        while (afterProperties.MoveNext())
        {
            DictionaryEntry entry = (DictionaryEntry)afterProperties.Current;
            sb.AppendFormat("[{0}]: ({1}, {2})\n", i++, entry.Key, entry.Value);
        }
        sb.AppendFormat("AfterProperties.ChangedProperties: {0}\n", 
          properties.AfterProperties.ChangedProperties);
        IEnumerator changedAfterProperties = 
          properties.AfterProperties.ChangedProperties.GetEnumerator();
        i = 0;
        while (changedAfterProperties.MoveNext())
        {
            DictionaryEntry entry = (DictionaryEntry)changedAfterProperties.Current;
            sb.AppendFormat("[{0}]: ({1}, {2})\n", i++, entry.Key, entry.Value);
        }
    
        // Add BeforeProperties property bag.
        sb.AppendFormat("BeforeProperties: {0}\n", properties.BeforeProperties);
        IEnumerator beforeProperties = properties.BeforeProperties.GetEnumerator();
        i = 0;
        while (beforeProperties.MoveNext())
        {
            DictionaryEntry entry = (DictionaryEntry)beforeProperties.Current;
            sb.AppendFormat("[{0}]: ({1}, {2})\n", i++, entry.Key, entry.Value);
        }
        sb.AppendFormat("BeforeProperties.ChangedProperties: {0}\n", 
          properties.BeforeProperties.ChangedProperties);
        IEnumerator changedBeforeProperties = 
          properties.BeforeProperties.ChangedProperties.GetEnumerator();
        i = 0;
        while (changedBeforeProperties.MoveNext())
        {
            DictionaryEntry entry = (DictionaryEntry)changedBeforeProperties.Current;
            sb.AppendFormat("[{0}]: ({1}, {2})\n", i++, entry.Key, entry.Value);
        }
    
        // Log the event to the list.
        this.EventFiringEnabled = false;
        Common.LogEvent(properties.Web, listName, properties.EventType, sb.ToString());
        this.EventFiringEnabled = true;
    }
    
  • SPWorkflowEventReceiver Ändern Sie alle überschriebenen Ereignisse. Es folgt ein Beispiel für die Vorgehensweise zum Ändern eines dieser Ereignisse.

    public override void WorkflowStarting(SPWorkflowEventProperties properties)
    {
        this.LogWorkflowEventProperties(properties);
    }
    

    Fügen Sie die Log-Methode wie im folgenden Code gezeigt hinzu.

    private void LogWorkflowEventProperties(SPWorkflowEventProperties properties)
    {
        // Specify the log list name.
        string listName = "WorkflowEventLogger";
    
        // Create the string builder object.
        StringBuilder sb = new StringBuilder();
    
        // Add properties that do not throw exceptions.
        sb.AppendFormat("AssociationData: {0}\n", properties.AssociationData);
        sb.AppendFormat("Cancel: {0}\n", properties.Cancel);
        sb.AppendFormat("CompletionType: {0}\n", properties.CompletionType);
        sb.AppendFormat("ErrorMessage: {0}\n", properties.ErrorMessage);
        sb.AppendFormat("EventType: {0}\n", properties.EventType);
        sb.AppendFormat("InitiationData: {0}\n", properties.InitiationData);
        sb.AppendFormat("InstanceId: {0}\n", properties.InstanceId);
        sb.AppendFormat("PostponedEvent: {0}\n", properties.PostponedEvent);
        sb.AppendFormat("ReceiverData: {0}\n", properties.ReceiverData);
        sb.AppendFormat("RedirectUrl: {0}\n", properties.RedirectUrl);
        sb.AppendFormat("RelativeWebUrl: {0}\n", properties.RelativeWebUrl);
        sb.AppendFormat("SiteId: {0}\n", properties.SiteId);
        sb.AppendFormat("Status: {0}\n", properties.Status);
        sb.AppendFormat("TerminatedByUserId: {0}\n", properties.TerminatedByUserId);
        sb.AppendFormat("WebUrl: {0}\n", properties.WebUrl);
    
        // Get activation properties.
        SPWorkflowActivationProperties activationProperties = properties.ActivationProperties;
        if (activationProperties != null)
        {
            sb.AppendFormat("ActivationProperties.AssociationData: {0}\n", 
              activationProperties.AssociationData);
            sb.AppendFormat("ActivationProperties.HistoryListId: {0}\n", 
              activationProperties.HistoryListId);
            sb.AppendFormat("ActivationProperties.HistoryListUrl: {0}\n", 
              activationProperties.HistoryListUrl);
            sb.AppendFormat("ActivationProperties.InitiationData: {0}\n", 
              activationProperties.InitiationData);
            sb.AppendFormat("ActivationProperties.ItemId: {0}\n", 
              activationProperties.ItemId);
            sb.AppendFormat("ActivationProperties.ItemUrl: {0}\n", 
              activationProperties.ItemUrl);
            sb.AppendFormat("ActivationProperties.ListId: {0}\n", 
              activationProperties.ListId);
            sb.AppendFormat("ActivationProperties.ListUrl: {0}\n", 
              activationProperties.ListUrl);
            sb.AppendFormat("ActivationProperties.Originator: {0}\n", 
              activationProperties.Originator);
            sb.AppendFormat("ActivationProperties.OriginatorEmail: {0}\n", 
              activationProperties.OriginatorEmail);
            sb.AppendFormat("ActivationProperties.SiteId: {0}\n", 
              activationProperties.SiteId);
            sb.AppendFormat("ActivationProperties.SiteUrl: {0}\n", 
              activationProperties.SiteUrl);
            sb.AppendFormat("ActivationProperties.TaskListId: {0}\n", 
              activationProperties.TaskListId);
            sb.AppendFormat("ActivationProperties.TaskListUrl: {0}\n", 
              activationProperties.TaskListUrl);
            sb.AppendFormat("ActivationProperties.TemplateName: {0}\n", 
              activationProperties.TemplateName);
            sb.AppendFormat("ActivationProperties.WebId: {0}\n", 
              activationProperties.WebId);
            sb.AppendFormat("ActivationProperties.WebUrl: {0}\n", 
              activationProperties.WebUrl);
            sb.AppendFormat("ActivationProperties.WorkflowId: {0}\n", 
              activationProperties.WorkflowId);
    
            // Add properties that might throw exceptions.
            try
            {
                sb.AppendFormat("ActivationProperties.Context: {0}\n", 
                  activationProperties.Context);
                sb.AppendFormat("ActivationProperties.HistoryList: {0}\n", 
                  activationProperties.HistoryList);
                sb.AppendFormat("ActivationProperties.Item: {0}\n", 
                  activationProperties.Item);
                sb.AppendFormat("ActivationProperties.List: {0}\n", 
                  activationProperties.List);
                sb.AppendFormat("ActivationProperties.OriginatorUser: {0}\n", 
                  activationProperties.OriginatorUser);
                sb.AppendFormat("ActivationProperties.Site: {0}\n", 
                  activationProperties.Site);
                sb.AppendFormat("ActivationProperties.TaskList: {0}\n", 
                  activationProperties.TaskList);
                sb.AppendFormat("ActivationProperties.Web: {0}\n", 
                  activationProperties.Web);
                sb.AppendFormat("ActivationProperties.Workflow: {0}\n", 
                  activationProperties.Workflow);
            }
            catch (Exception e)
            {
                sb.AppendFormat("\nError accessing ActivationProperties property:\n\n {0}", e);
            }
        }
        else
        {
            sb.AppendFormat("ActivationProperties is null\n");
        }
    
        // Log the event to the list.
        this.EventFiringEnabled = false;
        Common.LogEvent(properties.ActivationProperties.Web, listName, 
          properties.EventType, sb.ToString());
        this.EventFiringEnabled = true;
    }
    

Nun sind Sie vertraut mit dem kompletten SharePoint 2010-Ereignismodell, dem Erstellen von Ereignisempfängern sowie dem Bereitstellen von Projekten, mit denen Ereignisempfänger implementiert werden. (Sie wissen auch, wie viel Arbeitsaufwand Sie sich mit der Ereignisempfänger-Projektvorlage in Visual Studio 2010 sparen können.) Und Sie verfügen über mehrere praktische Beispiele, die Sie an Ihre speziellen Anforderungen anpassen können. Falls Sie noch mehr Informationen zum SharePoint-Ereignismodell benötigen, können Sie sich mit dem SharePoint 2010 SDK befassen und sich zunächst mit Ereignisse in SharePoint Foundation 2010 beschäftigen.

Anzeigen: