Intégration de complément d’événement d’entreprise avec SharePoint
L’exemple BusinessApps.CorporateEventsApp montre comment implémenter un système centralisé de gestion des événements d’entreprise en tant que complément hébergé par un fournisseur s’intégrant avec vos applications métier existantes.
Plus précisément, l’exemple BusinessApps.CorporateEventsApp montre comment implémenter une application web ASP.NET qui interagit avec SharePoint en tant que magasin de données pour des entités métier. Il montre également comment implémenter plusieurs étapes dans une tâche complexe avec un seul complément hébergé par un fournisseur.
Cet exemple d’application implémente un système de gestion centralisé constitué d’entités SharePoint (listes et types de contenus). Pour chaque nouveau type de contenu, il crée des entités métier correspondantes dans une application web ASP.NET. Les composants de l’application web s’exécutent en tant que composants de complément hébergés distants dans l’interface SharePoint, ainsi qu’en tant que pages s’exécutant entièrement sur l’hôte web distant. Le complément remplace la page d’accueil par défaut de votre site SharePoint afin que celui-ci puisse présenter une interface personnalisée sur sa page d’accueil.
Utilisation de l’exemple BusinessApps.CorporateEventsApp
Configurer l’exemple
Lorsque vous démarrez l’exemple d’application BusinessApps.CorporateEventsApp, la page d’accueil vous permet de configurer l’exemple. Il vous indique également un certain nombre de ressources pour accéder à des informations supplémentaires.
Lorsque vous choisissez Démarrer la configuration, vous accédez à la page de configuration, comme illustré dans la figure suivante. Lorsque vous choisissez Initialiser le magasin de données sur la page Configuration, l’exemple déploie les entités et exemples de données SharePoint sur lesquels l’exemple s’appuie.
Une fois le magasin de données initialisé, vous pouvez revenir à votre site pour voir la nouvelle page d’accueil (EventsHome.aspx), qui contient deux composants WebPart déployés par le complément, comme illustré dans la figure suivante. La colonne de gauche affiche les quatre nouvelles listes installées par le complément. La liste Événements d’entreprise contient des exemples de données.
Chaque composant WebPart contient des liens vers les événements affichés, où vous pouvez voir les détails de ceux-ci. Lorsque vous choisissez un lien, la page des détails de l’événement s’affiche séparément sur l’hôte distant, comme illustré dans la figure suivante. L’option Retour au site sur la page permet de revenir au site SharePoint pour s’inscrire à l’événement.
La page d’inscription s’exécute séparément sur l’hôte distant, affichant un lien vers le site de l’hôte SharePoint. Lorsque vous avez fini de vous inscrire à l’événement, votre nom apparaît dans la liste Inscription à l’événement nouvellement installée.
Fichier Models/DataInitializer.cs
Le fichier Models/DataInitializer.cs contient le code qui s’exécute lorsque vous choisissez ce bouton. Le code de ce fichier crée et déploie quatre nouvelles listes SharePoint, ainsi que quatre types de contenus correspondants :
- Événements d’entreprise
- Inscription à l’événement
- Intervenants de l’événement
- Sessions de l’événement
Le code de ce fichier utilise une méthode similaire à celle utilisée dans l’exemple Core.ModifyPages pour ajouter une page personnalisée au site.
// 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();
Le fichier Models\DataInitializer.cs définit également le code XML des deux composants WebPart affichés sur la nouvelle page de bienvenue, puis les ajoute à la page. Les exemples suivants montrent comment cela fonctionne pour le composant WebPart Événements suggérés.
Définir le code XML d’un composant WebPart
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"
};
Ajouter les composants WebPart à la page
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();
Dans le répertoire Modèles de votre projet web, vous pouvez remarquer que cette application web MVC ASP.NET contient quatre noms de classe correspondant aux listes et aux types de contenus que le complément a installés :
- Event.cs (Événements d’entreprise)
- Registration.cs (Inscription à l’événement)
- Session.cs (sessions de l’événement)
- Speaker.cs (Intervenants de l’événement)
Ces quatre classes et leurs types de contenus SharePoint correspondants constituent ensemble les quatre entités métier utilisées dans ce complément.
Le fichier DataInitializer.cs ajoute des exemples de données à la liste Événements d’entreprise en créant des exemples d’objets Événement correspondant au type de contenu Événements d’entreprise, que le complément ajoute à la liste Événements d’entreprise.
Lorsque vous vous inscrivez à un événement, le complément crée un objet Inscription qui correspond au type de contenu Inscription à l’événement et que le complément ajoute à la liste Inscription à l’événement. L’exemple n’ayant pas encore entièrement implémenté les objets Session et Intervenant, le complément ne fonctionne pas actuellement avec ces objets.
Le tableau suivant répertorie les propriétés que doivent implémenter les classes qui héritent de la classe abstraite BaseListItem.
Member | Description |
---|---|
ContentTypeName | Obtient le type de contenu associé avec l’élément. Si la valeur Null, le type de contenu de bibliothèque par défaut est affecté à l’élément lorsque vous l’enregistrez. |
FieldInternalNames | Liste de noms de champs pouvant être mis en cache pour améliorer les performances quand ils sont utilisés pour vérifier les données de champs avant l’enregistrement. |
ListTitle | Obtient le titre de la liste (respectant la casse). |
Le tableau suivant répertorie les méthodes que doivent implémenter les classes qui héritent de la classe abstraite BaseListItem. Ces méthodes renvoient les paramètres à définir sur des types blittables pour qu’ils soient utilisables sur plusieurs plateformes.
Méthode | Description |
---|---|
ReadProperties(ListItem) | Lit des propriétés de l’objet /ListItem à l’aide des méthodes BaseGet et BaseGetEnum, puis les affecte à des propriétés de la sous-classe. |
SetProperties(ListItem) | Définit des propriétés de l’objet /ListItem à l’aide des méthodes BaseSet et BaseSetTaxonomyField de la classe abstraite. |
Le tableau suivant répertorie les méthodes d’assistance de la classe BaseListItem dont les sous-classes ont besoin pour implémenter les méthodes ReadProperties et SetProperties.
Méthode d’assistance | Description |
---|---|
BaseGet(ListItem item, string internalName) | Obtient la propriété définie par le paramètre internalName de l’objet /ListItem, et renvoie les éléments de type générique T. |
BaseSet(ListItem item, string internalName, object value) | Définit la propriété ListItem définie par le paramètre internalName. |
BaseSetTaxonomyField(ListItem item, string internalName, string label, Guid termId) | Définit le champ de taxonomie ListItem défini par les paramètres internalName et termId. |
BaseGetEnum(ListItem item, string internalName, T defaultValue) | Récupère la valeur de la propriété enum définie par le paramètre internalName. Renvoie la valeur du paramètre defaultValue si la propriété n’est pas définie. |
Le fichier Event.cs contient les implémentations suivantes des méthodes ReadProperties et 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);
}
Les exemples de code suivants montrent comment les méthodes sous-jacentes BaseGet et BaseSet sont définies dans BaseListItem.cs.
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 && value is string) {
var urlValue = new FieldUrlValue() {
Url = value.ToString()
};
value = urlValue;
}
}
item[internalName] = value;
}
La classe BaseListItem contient également une méthode Save utilisée pour enregistrer chaque entité métier que le complément crée et manipule. Cette méthode charge la liste et détermine si l’élément actif a un ID supérieur à 0. Si l’ID n’est pas supérieur à 0, la méthode suppose qu’il n’est pas valide et crée un élément de liste. Elle utilise la méthode SetProperties pour définir les propriétés de l’objet ListItem, puis définit les propriétés de la sous-classe à l’aide de la méthode ReadProperties.
public void Save(Web web) {
var context = web.Context;
var list = web.GetListByTitle(ListTitle);
if (!IsNew && 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);
}