Freigeben über


Integration des Unternehmensereignis-Add-Ins in SharePoint

Das BusinessApps.CorporateEventsApp-Beispiel zeigt, wie Sie ein zentralisiertes Unternehmensereignis-Verwaltungssystem als vom Anbieter gehostetes Add-In implementieren, das mit Ihren vorhandenen Branchenanwendungen (Line-of-Business, LOB) integriert werden kann.

Genau gesagt zeigt das BusinessApps.CorporateEventsApp-Beispiel, wie eine ASP.NET-Webanwendung implementiert wird, die mit SharePoint als Datenspeicher für LOB-Entitäten interagiert. Außerdem zeigt es, wie Sie mehrere Schritte einer komplexen Geschäftsaufgabe mit einem einzigen vom Anbieter gehosteten Add-In implementieren.

Diese Beispiel-App implementiert ein zentralisiertes Verwaltungssystem, das aus SharePoint-Entitäten (Listen und Inhaltstypen) besteht. Für jeden neuen Inhaltstyp erstellt sie entsprechende LOB-Entitäten in einer ASP.NET-Webanwendung. Komponenten der Webanwendung werden als remote gehostete Add-In-Webparts auf der SharePoint-Benutzeroberfläche und als vollständig auf dem Remotewebhost ausgeführte Seiten ausgeführt. Das Add-In überschreibt die Standardstartseite für Ihre SharePoint-Website, sodass die Homepage der Website mit benutzerdefiniertem Branding präsentiert werden kann.

Verwenden des BusinessApps.CorporateEventsApp-Beispiels

Konfigurieren des Beispiels

Wenn Sie die Beispiel-App BusinessApps.CorporateEventsApp starten, bietet die Homepage eine Option zum Konfigurieren des Beispiels. Außerdem enthält sie Verweise auf zahlreiche Ressourcen für weitere Informationen.

Wenn Sie Start configuration wählen, wechseln Sie zur Konfigurationsseite, wie in der folgenden Abbildung gezeigt. Wenn Sie auf der Konfigurationsseite Initialize the data store wählen, werden die SharePoint-Entitäten und Beispieldaten bereitgestellt, die das Beispiel unterstützen.

Screenshot des Bildschirms


Nachdem Sie den Datenspeicher initialisiert haben, können Sie zu Ihrer Website zurückkehren, um eine neue Startseite (die Seite EventsHome.aspx) anzuzeigen. Sie wird von zwei Webparts aufgefüllt, die das Add-In bereitgestellt hat, wie in der folgenden Abbildung gezeigt. In der linken Spalte sehen Sie die vier neuen Listen, die vom Add-In installiert wurden. Die Liste von Unternehmensereignissen ist mit Beispieldaten gefüllt.

Screenshot der Add-In-Startseite, die mit Webparts bereitgestellt wird


Jedes Webpart enthält Links zu den einzelnen angezeigten Ereignissen, unter denen Sie die Ereignisdetails anzeigen können. Wenn Sie einen Link auswählen, wird die Ereignisdetailseite separat auf dem Remotehost ausgeführt, wie in der folgenden Abbildung gezeigt. Sie können Back to Site auf der Seite wählen, um zur SharePoint-Website zurückzukehren und sich für das Ereignis zu registrieren.

Screenshot der Add-In-Benutzeroberfläche mit dem Unternehmensereignisbildschirmbereich mit Ereignisdetails


Die Registrierungsseite wird separat auf dem Remotehost ausgeführt und enthält einen Link zurück zur SharePoint-Hostwebsite. Wenn Sie sich für das Ereignis registriert haben, wird Ihr Name auf der neu installierten Liste Event Registration angezeigt.

Screenshot des Add-In-Registrierungsbildschirms für Unternehmensereignisse


Datei „Models/DataInitializer.cs“

Die Datei „Models/DataInitializer.cs“ enthält den Code, der ausgeführt wird, wenn Sie auf diese Schaltfläche klicken. Der Code in dieser Datei erstellt vier neue SharePoint-Listen zusammen mit vier entsprechenden Inhaltstypen und stellt diese bereit:

  • Corporate Events (Unternehmensereignisse)
  • Event Registration (Ereignisregistrierung)
  • Event Speakers (Ereignissprecher)
  • Event Sessions (Ereignissitzungen)

Der Code in dieser Datei verwendet eine Methode ähnlich derjenigen, die im Core.ModifyPages-Beispiel verwendet wird, um eine benutzerdefinierte Seite zur Website hinzuzufügen.

            // Create default wiki page.
            web.AddWikiPage("Site Pages", "EventsHome.aspx");
AddWikiPage is an extension method from the Core.DevPnPCore project to add a new page to the site. This new page also becomes the new WelcomePage for the site. It also prepares to add the web parts to this page.
            var welcomePage = "SitePages/EventsHome.aspx";
            var serverRelativeUrl = UrlUtility.Combine(web.ServerRelativeUrl, welcomePage);

            File webPartPage = web.GetFileByServerRelativeUrl(serverRelativeUrl);

            if (webPartPage == null) {
                return;
            }

            web.Context.Load(webPartPage);
            web.Context.Load(webPartPage.ListItemAllFields);
            web.Context.Load(web.RootFolder);
            web.Context.ExecuteQuery();

            web.RootFolder.WelcomePage = welcomePage;
            web.RootFolder.Update();
            web.Context.ExecuteQuery();


Die Datei „Models\DataInitializer.cs“ definiert auch den XML-Code für beide Webparts, die auf der neuen Startseite angezeigt werden, und fügt dann beide zu der Seite hinzu. Die folgenden Beispiele zeigen, wie dies für das „Featured Events“-Webpart funktioniert.

Definieren der Webpart-XML

            var webPart1 = new WebPartEntity(){
                WebPartXml = @"<webParts>
  <webPart xmlns='http://schemas.microsoft.com/WebPart/v3'>
    <metaData>
      <type name='Microsoft.SharePoint.WebPartPages.ClientWebPart, Microsoft.SharePoint, Version=16.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c' />
      <importErrorMessage>Cannot import this web part.</importErrorMessage>
    </metaData>
    <data>
      <properties>
        <property name='Description' type='string'>Displays featured events</property>
        <property name='FeatureId' type='System.Guid, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'>3a6d7f41-2de8-4e69-b4b4-0325bd56b32c</property>
        <property name='Title' type='string'>Featured Events</property>
        <property name='ProductWebId' type='System.Guid, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'>12ae648f-27db-4a97-9c63-37155d3ace1e</property>
        <property name='WebPartName' type='string'>FeaturedEvents</property>
        <property name='ProductId' type='System.Guid, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'>3a6d7f41-2de8-4e69-b4b4-0325bd56b32b</property>
        <property name='ChromeState' type='chromestate'>Normal</property>
      </properties>
    </data>
  </webPart>
</webParts>",
                WebPartIndex = 0,
                WebPartTitle = "Featured Events",
                WebPartZone = "Rich Content"
            };


Hinzufügen der Webparts zur Seite

        var limitedWebPartManager = webPartPage.GetLimitedWebPartManager(Microsoft.SharePoint.Client.WebParts.PersonalizationScope.Shared);
        web.Context.Load(limitedWebPartManager.WebParts);
        web.Context.ExecuteQuery();

        for (var i = 0; i < limitedWebPartManager.WebParts.Count; i++) {
            limitedWebPartManager.WebParts[i].DeleteWebPart();
        }
        web.Context.ExecuteQuery();

        var oWebPartDefinition1 = limitedWebPartManager.ImportWebPart(webPart1.WebPartXml);
        var oWebPartDefinition2 = limitedWebPartManager.ImportWebPart(webPart2.WebPartXml);
        var wpdNew1 = limitedWebPartManager.AddWebPart(oWebPartDefinition1.WebPart, webPart1.WebPartZone, webPart1.WebPartIndex);
        var wpdNew2 = limitedWebPartManager.AddWebPart(oWebPartDefinition2.WebPart, webPart2.WebPartZone, webPart2.WebPartIndex);
        web.Context.Load(wpdNew1);
        web.Context.Load(wpdNew2);
        web.Context.ExecuteQuery();


Im Modellverzeichnis Ihres Webprojekts werden Sie feststellen, dass diese MVC ASP.NET-Webanwendung vier Klassennamen enthält, die den Listen und Inhaltstypen entsprechen, die das Add-In installiert hat:

  • Event.cs (Corporate Events)
  • Registration.cs (Event Registration)
  • Session.cs (Event Sessions)
  • Speaker.cs (Event Speakers)

Diese vier Klassen und die entsprechenden SharePoint-Inhaltstypen bilden zusammen die vier LOB-Entitäten, die in diesem Add-In verwendet werden.

Die Datei „DataInitializer.cs“ fügt Beispieldaten für die Liste Corporate Events durch Erstellen von Beispiel-Event-Objekten hinzu, die dem Inhaltstyp Corporate Events entsprechen und die das Add-In zur Liste Corporate Events hinzufügt.

Wenn Sie sich für eine Veranstaltung registrieren, erstellt das Add-In ein Registration-Objekt, das dem Inhaltstyp Event Registration entspricht und das vom Add-In zur Liste Event Registration hinzugefügt wird. Das Beispiel hat die Objekte Session und Speaker noch nicht vollständig implementiert, daher funktioniert das Add-In derzeit nicht mit diesen Objekten.

Die folgende Tabelle enthält die Eigenschaften, die von den Klassen implementiert werden müssen, die von der abstrakten Klasse BaseListItem erben.

Member Beschreibung
ContentTypeName Ruft den Inhaltstyp ab, der dem Element zugeordnet ist. Ist dieser NULL, wird dem Element beim Speichern der Standardinhaltstyp der Bibliothek zugewiesen.
FieldInternalNames Eine Liste von Feldnamen, die für eine bessere Leistung beim Überprüfen von Felddaten vor dem Speichern zwischengespeichert werden können.
ListTitle Ruft den Titel der Liste ab (Groß-/Kleinschreibung).

Die folgende Tabelle enthält die Methoden, die von den Klassen implementiert werden müssen, die von der abstrakten Klasse BaseListItem erben. Diese Methoden geben Parameter zurück, die auf für Blitting geeignete Typen festgelegt werden sollten, damit sie auf unterschiedlichen Plattformen verwendet werden können.

Methode Beschreibung
ReadProperties(ListItem) Liest Eigenschaften aus dem ListItem-Objekt mithilfe der Methoden BaseGet und BaseGetEnum und weist sie Eigenschaften der Unterklasse zu.
SetProperties(ListItem) Legt Eigenschaften für das ListItem-Objekt mithilfe der Methoden BaseSet und BaseSetTaxonomyField der abstrakten Klasse fest.

Die folgende Tabelle enthält die Hilfsmethoden aus der BaseListItem-Klasse, welche die Unterklassen zum Implementieren der Methoden ReadProperties und SetProperties benötigen.

Hilfsmethode Beschreibung
BaseGet(ListItem item, string internalName) Ruft die Eigenschaft, die vom internalName-Parameter definiert wird, von ListItem ab und gibt sie vom generischen Typ T zurück.
BaseSet(ListItem item, string internalName, object value) Legt die ListItem-Eigenschaft fest, die vom internalName-Parameter definiert wird.
BaseSetTaxonomyField(ListItem item, string internalName, string label, Guid termId) Legt das ListItem-Taxonomiefeld fest, das von den Parametern internalName und termId definiert wird.
BaseGetEnum(ListItem item, string internalName, T defaultValue) Ruft den Wert der Enumerationseigenschaft ab, die vom internalName-Parameter definiert wird. Gibt den Wert des defaultValue-Parameters zurück, wenn die Eigenschaft nicht festgelegt ist.

Die Datei Event.cs enthält die folgenden Implementierungen der Methoden ReadProperties und SetProperties.

ReadProperties

        protected override void ReadProperties(ListItem item) {
            RegisteredEventId = BaseGet<string>(item, FIELD_REGISTERED_EVENT_ID);
            Description = BaseGet<string>(item, FIELD_DESCRIPTION);
            Category = BaseGet<string>(item, FIELD_CATEGORY);
            EventDate = BaseGet<DateTime?>(item, FIELD_DATE);
            Location = BaseGet<string>(item, FIELD_LOCATION);
            ContactEmail = BaseGet<string>(item, FIELD_CONTACT_EMAIL);
            Status = BaseGetEnum<EventStatus>(item, FIELD_STATUS);
            var imageUrl = BaseGet<FieldUrlValue>(item, FIELD_IMAGE_URL);

            if (imageUrl != null)
                ImageUrl = imageUrl.Url;
        }

SetProperties

        protected override void SetProperties(ListItem item) {
            BaseSet(item, FIELD_REGISTERED_EVENT_ID, RegisteredEventId);
            BaseSet(item, FIELD_DESCRIPTION, Description);
            BaseSet(item, FIELD_CATEGORY, Category);
            BaseSet(item, FIELD_DATE, EventDate);
            BaseSet(item, FIELD_LOCATION, Location);
            BaseSet(item, FIELD_CONTACT_EMAIL, ContactEmail);
            BaseSet(item, FIELD_STATUS, Status.ToEnumDescription());
            BaseSet(item, FIELD_IMAGE_URL, ImageUrl);
        }

Die folgenden Codebeispiele verdeutlichen, wie die zugrunde liegenden Methoden BaseGet und BaseSet in BaseListItem.cs definiert sind.

BaseGet

protected T BaseGet<T>(ListItem item, string internalName){
            var field = _fields[internalName.ToLowerInvariant()];
            var value = item[field.InternalName];
            return (T)value;
        }


BaseSet

protected void BaseSet(ListItem item, string internalName, object value) {
            if (_fields.ContainsKey(internalName)) {
                var field = _fields[internalName.ToLowerInvariant()];

                if (field is FieldUrl &amp;&amp; value is string) {
                    var urlValue = new FieldUrlValue() {
                        Url = value.ToString()
                    };
                    value = urlValue;
                }
            }
            item[internalName] = value;
        }

Die BaseListItem-Klasse enthält auch eine Save-Methode, die verwendet wird, um jede vom Add-In erstellte und bearbeitete LOB-Entität zu speichern. Diese Methode lädt die Liste und bestimmt, ob das aktuelle Element eine ID besitzt, die größer als 0 ist. Wenn die ID nicht größer als 0 ist, wird angenommen, dass es nicht gültig ist, und ein neues Listenelement erstellt. Sie verwendet die SetProperties-Methode zum Festlegen von Eigenschaften für ListItem und legt dann die Eigenschaften für die Unterklassen mithilfe der ReadProperties-Methode fest.

public void Save(Web web) {
            var context = web.Context;
            var list = web.GetListByTitle(ListTitle);
            if (!IsNew &amp;&amp; Id > 0) {
                ListItem = list.GetItemById(Id);
            }
            else {
                var listItemCreationInfo = new ListItemCreationInformation();
                ListItem = list.AddItem(listItemCreationInfo);
            }

            // Ensure that the fields have been loaded.
            EnsureFieldsRetrieved(ListItem);

            // Set the properties on the list item.
            SetProperties(ListItem);
            BaseSet(ListItem, TITLE, Title);

            // Use if you want to override the created/modified date.
            //BaseSet(ListItem, CREATED, Created);
            //BaseSet(ListItem, MODIFIED, Modified);

            ListItem.Update();

            if (!string.IsNullOrEmpty(ContentTypeName)) {
                var contentType = list.GetContentTypeByName(ContentTypeName);
                if (contentType != null)
                    BaseSet(ListItem, "ContentTypeId", contentType.Id.StringValue);
            }

            ListItem.Update();

            // Execute the batch.
            context.ExecuteQuery();

            // Reload the properties.
            ListItem.RefreshLoad();
            UpdateBaseProperties(ListItem);
            ReadProperties(ListItem);
        }

Siehe auch