Sharepoint 2010 ; BCS; BDC; Bing Maps; SQL AZURE; Windows Azure

Sharepoint 2010 – BCS ECT ,Windows Azure WCF et Bing Maps Partie 2

Posted on

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

image

 

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

image

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

 

image

 

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

image

 

Une fois cela réalisé vous devriez avoir côté BCS la configuration Stores disponible et votre liste visible.

 

 

imageExternal Content Type information

 

 

image

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

image

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 :

image

Sharepoint 2010 – BCS ECT ,Windows Azure WCF et Bing Maps Partie 1

Posted on

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 :

 

20091021.MSP - Introduction à Azure - ssfartz

SQL AZURE

Commençons dans un premier temps à se connecter sur notre plateforme Azure et de créer notre jeu de données.

 

image

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

.image

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éé.

image

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 “ SharePointCallingSvcimage

 

Une fois lancé ajouté un nouvel élément de type “ ADO.NET Entity Data Model

Puis cochez comme dans l’image suivanteimage

 

Puis sélectionnez la table “ StoreInformation” en cochant comme ci :

 image

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

image

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

image

Rendez vous dans votre portail Azure et créer un “Service hébergé

imageimage

 

 

 

 

Puis remplissez les champs :image

Une fois le service hébergé créé vous pouvez vous rendre sur sa page et invoquez le Service WCF :

image