Bing Maps
Sharepoint 2010 – BCS ECT ,Windows Azure WCF et Bing Maps Partie 2
Une fois que l’on a déployé notre Service WCF et que celui-ci s’avère fonctionnel nous pouvons maintenant nous attaquer à la configuration de notre BCS puis de la création de notre code Sharepoint avec Bing Maps en Silverlight
BCS Configuration
Rendez-vous dans “Sharepoint Administation Central”> Manage Service Application > Business Data Connectivity Service Proxy
Ajoutons les autorisations en cliquant sur “Set Metadata Store Permission” et ajoutez un utilisateur
Depuis Sharepoint Designer ajoutons un External Content Type
Ajoutez un Nom (Stores) et laissez les options par défaut puis ajouter votre Service WCF en cliquant sur “ Click Here to discover external ….”
Ici voici le résultat de ma configuration
Puis cliquez sur “Add connection” puis le type “WCF” et renseignez les paramètres suivants :
– Service WSDL : http://myservice.cloudapp.net/myservice.svc?wsdl
– Service = http://myservice.cloudapp.net/myservice.svc
– Name (optional) : Stores
Laissez le reste par défaut. Ici voici le résultat de ma connection
Dans l’arborescence sélectionnez la méthode GetStore puis cliquez droit sur New Read Item Operation.
Mettez bien en paramètres sur le “Map to Identifier” le champ StoreID et sur Identifier le champ StoreID
Dans l’arborescence sélectionnez la méthode GetStores puis cliquez droit sur New Read List Operation.
Faites de même qu’avec GetStore.
Ensuite générez les formulaires en cliquant sur “Create & Lists Forms” et donnez le nom de “MyStoreBingLists”
Une fois cela réalisé vous devriez avoir côté BCS la configuration Stores disponible et votre liste visible.
External Content Type information
MyStoreBingLists
Sharepoint Project
Prérequis :
· Visual Studio 2010 SharePoint Power tool –http://visualstudiogallery.msdn.microsoft.com/en-us/8e602a8c-6714-4549-9e95-f3700344b0d9
· Microsoft Silverlight Plug-in for Browsers – http://www.microsoft.com/getsilverlight/
· Bing Maps Silverlight Control SDK – http://www.microsoft.com/downloads/details.aspx?displaylang=en&FamilyID=beb29d27-6f0c-494f-b028-1e0e3187e830
· Microsoft Silverlight Developer runtime – http://go.microsoft.com/fwlink/?LinkID=188039
Afin de pouvoir publier notre fichier (XAP) silverlight dans Sharepoint, créez avant tout une Bibliothèques de Documents en la nommant “SLLIB”
Ensuite créez un projet Sharepoint vide et lui ajouté un item Elements.xml avec le code suivant :
<?xml version="1.0" encoding="utf-8"?> <Elements xmlns="http://schemas.microsoft.com/sharepoint/"> <Module Name="Silverlight Application Module" Url="SLLIB"> <File Path="Silverlight Application ModuleSharePoint2010HOL.xap" Url="Silverlight Application Module/SharePoint2010HOL.xap" Type="GhostableInLibrary"/> </Module> </Elements>
puis lui ajouté un fichier de type module en le nommant Silverlight Application Module puis clic droit propriétés> Project Output References
Si vous êtes perdu voici un lien d’aide : http://bryantlikes.com/GettingStartedWithSilverlightAndSharePoint2010.aspx
Silverlight Project
Ajouter un nouveau projet de type Silverlight et ajouter les références dans MainPage.xaml.cs:
using Microsoft.Maps.MapControl;
using Microsoft.SharePoint.Client;
Design
Le code XAML est le suivant :
<UserControl x:Class="SharePoint2010HOL.MainPage" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d" xmlns:m="clr-namespace:Microsoft.Maps.MapControl;assembly=Microsoft.Maps.MapControl" d:DesignHeight="400" d:DesignWidth="750" > <Grid x:Name="LayoutRoot" Background="White" > <m:Map x:Name="MainMap" CredentialsProvider="KEYBINGMAPS" AnimationLevel="Full" Mode="AerialWithLabels" ZoomLevel="5" Center="38.000,-95.000" > <m:Map.Children> <m:MapLayer x:Name="PolygonsLayer" Visibility="Visible"/> <m:MapLayer x:Name="Pushpins" Visibility="Visible"/> <m:MapLayer x:Name="ContentPopupLayer"> <Canvas x:Name="ContentPopup" Visibility="Collapsed" Opacity="0.9"> <Rectangle x:Name="ContentPopupRectangle" Fill="White" Canvas.Left="0" Canvas.Top="0" Height="100" Width="300" RadiusX="10" RadiusY="10"/> <StackPanel Canvas.Left="10" Canvas.Top="10"> <TextBlock x:Name="ContentPopupText" FontSize="12" FontWeight="Bold" ></TextBlock> <TextBlock x:Name="ContentPopupDescription" Width="275" FontSize="12" TextWrapping="Wrap"/> </StackPanel> </Canvas> </m:MapLayer> </m:Map.Children> </m:Map> </Grid> </UserControl>
Code-Behind XAML
using System; using System.Collections.Generic; using System.Linq; using System.Net; using System.Windows; using System.Windows.Controls; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Animation; using System.Windows.Shapes; using Microsoft.Maps.MapControl; using Microsoft.SharePoint.Client; namespace SharePoint2010HOL { public partial class MainPage : UserControl { ListItemCollection listItems; public MainPage() { InitializeComponent(); this.Loaded += new RoutedEventHandler(MainPage_Loaded); } void MainPage_Loaded(object sender, RoutedEventArgs e) { //ClientContext context = new ClientContext("http://vwk-sp2010/sites/demo/"); ClientContext context = new ClientContext(ApplicationContext.Current.Url); List customersList = context.Web.Lists.GetByTitle("MyStoreBingLists"); CamlQuery query = new Microsoft.SharePoint.Client.CamlQuery(); query.ViewXml = @"<View>" + @"<Query><OrderBy>" + @"<FieldRef Name='StoreName' Ascending='True' />" + @"</OrderBy></Query>" + @"<ViewFields>" + @"<FieldRef Name='StoreID' />" + @"<FieldRef Name='StoreName' />" + @"<FieldRef Name='StoreHours' />" + @"<FieldRef Name='StorePhone' />" + @"<FieldRef Name='StoreLongitude' />" + @"<FieldRef Name='StoreLatitude' />" + // @"<FieldRef Name='StoreTitle' />" + @"<FieldRef Name='StoreAddress' />" + @"</ViewFields>" + @"</View>"; listItems = customersList.GetItems(query); context.Load(listItems, items => items.Include( item => item["StoreID"], item => item["StoreName"], item => item["StoreHours"], item => item["StorePhone"], item => item["StoreLongitude"], item => item["StoreLatitude"], //item => item["StoreTitle"], item => item["StoreAddress"] )); context.ExecuteQueryAsync(new ClientRequestSucceededEventHandler(OnRequestSucceeded), new ClientRequestFailedEventHandler(OnRequestFailed)); } private void OnRequestSucceeded(Object sender, ClientRequestSucceededEventArgs args) {this.Dispatcher.BeginInvoke(DisplayCustomerInfo); } private void DisplayCustomerInfo() { foreach (ListItem item in listItems) { Pushpins.Children.Clear(); for (int i = 0; i < listItems.Count; i++) { string description = "Store: " + listItems[i].FieldValues["StoreName"].ToString() + "nAddress: " + listItems[i].FieldValues["StoreAddress"].ToString() + "nPhone: " + listItems[i].FieldValues["StorePhone"].ToString() + "nHours: " + listItems[i].FieldValues["StoreHours"].ToString(); CreatePushpin(new Location(Convert.ToDouble(listItems[i].FieldValues["StoreLatitude"].ToString()), Convert.ToDouble(listItems[i].FieldValues["StoreLongitude"].ToString())), description); }} } private void OnRequestFailed(object sender, ClientRequestFailedEventArgs e) { Dispatcher.BeginInvoke(() => { MessageBox.Show("Error: " + e.Message);}); } private void CreatePushpin(Location location, string description) { Pushpin pushpin = new Pushpin(); pushpin.Width = 7; pushpin.Height = 10; pushpin.Tag = description; pushpin.Location = location; Pushpins.AddChild(pushpin, location, PositionOrigin.Center); pushpin.MouseEnter += new MouseEventHandler(Shape_MouseEnter); pushpin.MouseLeave += new MouseEventHandler(Shape_MouseLeave); } private void Shape_MouseEnter(object sender, MouseEventArgs e) { if (sender.ToString() == "Microsoft.Maps.MapControl.Pushpin") { Pushpin content = sender as Pushpin; Canvas.SetZIndex(content, 500); ContentPopupText.Text = content.Name; ContentPopupDescription.Text = content.Tag.ToString(); } else { MapPolygon content = sender as MapPolygon; Canvas.SetZIndex(content, 500); ContentPopupText.Text = "Polygon ID: " + content.Name; ContentPopupDescription.Text = content.Tag.ToString(); } Point point = e.GetPosition(MainMap); Location location = MainMap.ViewportPointToLocation(point); MapLayer.SetPosition(ContentPopup, location); MapLayer.SetPositionOffset(ContentPopup, new Point(25, -50)); ContentPopup.Visibility = Visibility.Visible; } private void Shape_MouseLeave(object sender, MouseEventArgs e) { UIElement content = sender as UIElement; Canvas.SetZIndex(content, 100); ContentPopup.Visibility = Visibility.Collapsed; } } }
APP.XAML
Modifiez la méthode “Application_Startup” afin qu’elle puisse bénéficier du Context Sharepoint
private void Application_Startup(object sender, StartupEventArgs e) { ApplicationContext.Init(e.InitParams, SynchronizationContext.Current); this.RootVisual = new MainPage(); }
Déploiement XAP
Cliquez droit sur le projet Sharepoint et faire “Deploy”. Vérifiez dans la Bibliothèque “SLLIB” que le fichier XAP s’est bien déployé. Puis ajoutez une Web Part Silverlight à votre page et renseignez lui le chemin absolu de votre fichier .xap.
Cela nous donnera le résultat final suivant :
Sharepoint 2010 – BCS ECT ,Windows Azure WCF et Bing Maps Partie 1
Dans ce billet nous allons mettre en place l’utilisation de Bing Maps avec un service WCF Azure qui expose les données de SQL Azure, le tout dans Sharepoint 2010 sous la forme d’un External Content Type.
Pour faire plus simple voilà le schéma :
SQL AZURE
Commençons dans un premier temps à se connecter sur notre plateforme Azure et de créer notre jeu de données.
Créer votre database dans mon cas elle s’appelle demo et est de type Web Edition 1GB
Renseignez les règles de Pare-feu en ajoutant votre adresse IP
Maintenant nous pouvons nous connecter depuis SQL SERVER 2008 R2 ou depuis Visual Studio 2010 en renseignant votre chaine de connexion(xxxxxxx.database.windows.net) et le mot de passe créé.
Puis exécutez le script ci-dessous
Script SQL
CREATE TABLE [StoreInformation](
[StoreID] [int] IDENTITY(1,1)NOT NULL PRIMARY KEY CLUSTERED,
[StoreTitle] [nvarchar](8)NULL,
[StoreName] [nvarchar](50)NOT NULL,
[StoreAddress] [nvarchar](50)NOT NULL,
[StorePhoneNumber] [nvarchar](50)NULL,
[Latitude] [nvarchar](30)NULL,
[Longitude] [nvarchar](30)NULL,
[Hours] [nvarchar](30)NULL,
[Timestamp] [timestamp] NOT NULL,
)INSERT INTO [StoreInformation]
([StoreTitle],[StoreName],[StoreAddress],[StorePhoneNumber],[Latitude],[Longitude],[Hours])
VALUES
(‘1-C’, ‘LLK’, ‘Stanton, Denver, CO, USA’,’322-555-0188′, ‘39.6274999999999998’, ‘-104.221′, ’12’),
(‘2-C’, ‘Contoso’, ‘East King Alfred Mall, Denver, CO, USA’,’322-555-0188′, ‘39.556473221’, ‘-104.001′, ’12’),
(‘3-C’, ‘Jackson’, ‘Eastside Mall, Denver, CO, USA’,’322-555-1128′, ‘39.1121112321’, ‘-104.112′, ’12’),
(‘4-C’, ‘Hockey’, ‘Westside Mall, Denver, CO, USA’,’322-555-8839′, ‘39.221232122’, ‘-103.999′, ’12’),
(‘5-C’, ‘REI’, ‘Kareen Area Mall, Denver, CO, USA’,’322-555-9910′, ‘39.4432344432’, ‘-104.019′, ’12’),
(‘6-C’, ‘Cantrell’, ‘Saanich Mall, Denver, CO, USA’,’322-555-0029′, ‘39.61029102211’, ‘-103.892′, ’12’),
(‘7-C’, ‘PIA’, ‘Debson-Heights Mall, Denver, CO, USA’,’322-555-1028′, ‘39.11211212112’, ‘-104.001′, ’12’),
(‘8-C’, ‘Jacks’, ‘Perial Mall, Denver, CO, USA’,’322-555-2271′, ‘38.209102912’, ‘-103.920′, ’12’),
(‘9-C’, ‘TTT’, ‘Downtown Mall, Denver, CO, USA’,’322-555-1121′, ‘39.00001920192’, ‘-104.110′, ’12’),
(’10-C’, ‘AI’, ‘Southside Mall, Denver, CO, USA’,’322-555-8878′, ‘39.2291829182’, ‘-104.001′, ’12’),
(’11-C’, ‘J and J’, ‘Westmont Mall, Denver, CO, USA’,’322-555-9280′, ‘39.62888392819’, ‘-104.555′, ’12’)
WCF
Maintenant que nos données sont publiés nous allons créer notre service WCF Azure. La démarche est celle fourni par Steve Fox dans son article suivant :http://blogs.msdn.com/b/steve_fox/archive/2011/11/12/leveraging-wcf-services-to-connect-bcs-with-sharepoint-online.aspx
Configuration
Ouvrez Visual Studio et créer un nouveau projet Windows Azure.
Puis nommez la solution “ SharePointCallingSvc”
Une fois lancé ajouté un nouvel élément de type “ ADO.NET Entity Data Model”
Puis cochez comme dans l’image suivante
Puis sélectionnez la table “ StoreInformation” en cochant comme ci :
N’oubliez pas enfin de modifier les propriétés sur Model1.edmx comme tel :
Action de génération => EntityDeploy
Copier dans le répertoire de sortie => Toujours copier
Modification du code
Supprimez dès le début les codes fournis ajouter une classe “ StoreDetails”
Classe StoreDetails.cs
namespace SharePointCallingSvc { public class StoreDetails { public int StoreID{get; set;} public string StoreLongitude { get; set; } public string StoreLatitude { get; set; } public string StoreName{get;set;} public string StoreAddress{get;set;} public string StorePhone{get;set;} public string StoreHours{get;set;} public string StoreTitle { get; set; } } }
Interface IService1.cs
using System.ServiceModel; namespace SharePointCallingSvc { [ServiceContract] public interface IService1 { [OperationContract] StoreDetails[] GetStores(); [OperationContract] StoreDetails GetStore(int StoreID); } }
Classe Service1.svc.cs
using System.Linq; using System.ServiceModel.Activation; namespace SharePointCallingSvc { [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)] public class Service1 : IService1 { public StoreDetails[] GetStores() { using (StoresEntities db = new StoresEntities()) { var myItems = (from c in db.StoreInformations select c); StoreDetails[] myStoreArray = new StoreDetails[myItems.Count()]; int i = 0; foreach (StoreInformation item in myItems) { myStoreArray[i] = new StoreDetails(); myStoreArray[i].StoreLatitude = item.Latitude; myStoreArray[i].StoreLongitude = item.Longitude; myStoreArray[i].StoreAddress = item.StoreAddress; myStoreArray[i].StoreName = item.StoreName; myStoreArray[i].StorePhone = item.StorePhoneNumber; myStoreArray[i].StoreHours = item.Hours; myStoreArray[i].StoreID = item.StoreID; i++; } return myStoreArray; } } public StoreDetails GetStore(int paramStoreID) { using (StoresEntities db = new StoresEntities()) { var myItem = (from c in db.StoreInformations where c.StoreID == paramStoreID select c).FirstOrDefault(); StoreDetails returnStore = new StoreDetails(); returnStore.StoreID = myItem.StoreID; returnStore.StoreName = myItem.StoreName; returnStore.StoreAddress = myItem.StoreAddress; returnStore.StoreHours = myItem.Hours; returnStore.StorePhone = myItem.StorePhoneNumber; returnStore.StoreTitle = myItem.StoreTitle; returnStore.StoreLatitude = myItem.Latitude; returnStore.StoreLongitude = myItem.Longitude; return returnStore; } } } }
Déploiement de du Service WCF
Maintenant compilez pour voir si vous n’avez pas d’erreur puis cliquez droit sur le WindowsAzureProject et “Publier” et sélectionnez dans le fenêtre “Create Service Package Only”
Rendez vous dans votre portail Azure et créer un “Service hébergé”
Une fois le service hébergé créé vous pouvez vous rendre sur sa page et invoquez le Service WCF :
TechDays 2012 – Ask The Expert
C’est avec une grande joie que je serai présent aux TechDays 2012 en tant qu’ATE (Ask-The-Expert) dans le pôle Efficacité Collective et Individuelle .
De plus je serai aussi sur le stand Communautaire ExiaMS (http://www.exiams.fr/).
@bientôt