Appeler un service WCF depuis Silverlight
Par
Ludovic Lefort (Site web) (Blog)
J'ai lu dans plusieurs forums que pas mal de personnes éprouvaient quelques difficultés pour appeler un service WCF depuis une application Silverlight. C'est la raison pour laquelle j'ai décidé d'écrire cet article.
0. Introduction
1. Pré-requis
2. Première étape : création d'un site web
3. Le projet Silverlight
4. Le projet WCF
5. Ajouter le service WCF au projet Silverlight
6. Appeler un webservice hébergé sur un autre site
7. Liens
0. Introduction
Dans sa version actuelle (2 beta 1) silverlight ne permet de référencer un autre projet (class library).
La seule manière de le faire est de passer par une couche de Web service.
Cela peut se faire par des service web asp.net 2.0 ou grâce à Windows Communication Foundation (WCF) ajoutés dans le framework .net 3.0
Microsoft recommande l'utilisation de WCF. J'ai donc choisi cette technologie pour cet article.
1. Pré-requis
2. Première étape : création d'un site web
Pour commencer nous allons créer un nouveau site web asp.net avec Visual Studio 2008, appelons le SilverlightWCFDemo :
3. Le projet Silverlight
Il nous faut à présent ajouter un nouveau projet à notre solution qui contiendra l'animation silverlight.
Clic droit sur la solution -> add -> new project.
Dans la rubrique Silverlight, choisissez Silverlight Application et nommée la SilverlightAnimation :
Après avoir cliqué sur OK Visual Studio va vous demander de lier ce projet à un site web, cliquez sur OK :
Normallement visual studio a du vous ajouter une page nommée SilverlightAnimationTestPage.aspx contenant votre animation silverlight et qui sera executée au démmarrage de votre site web.
Pour tous ceux qui ont eu la joie de tester la version 1 de Silverlight : quel progrès :)
Modifions à présent le fichier Page.xml (animation silverlight) qui actuellement vierge.
Pour le design de mon animation j'utilise Microsoft Expresion Blend mais vous pouvez également travailler directement en xaml depuis Visual Studio.
Voici le contenu de notre animation pour cet exemple :
<UserControl x:Class="SilverlightAnimation.Page"
xmlns="http://schemas.microsoft.com/client/2007"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Width="400" Height="300">
<UserControl.Resources>
<Storyboard x:Name="AnimResult">
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="textBlock" Storyboard.TargetProperty="(TextBlock.FontSize)" BeginTime="00:00:00">
<SplineDoubleKeyFrame KeyTime="00:00:02" Value="72"/>
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="textBlock" Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleX)" BeginTime="00:00:00">
<SplineDoubleKeyFrame KeyTime="00:00:02" Value="9.107"/>
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="textBlock" Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleY)" BeginTime="00:00:00">
<SplineDoubleKeyFrame KeyTime="00:00:02" Value="2.242"/>
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="textBlock" Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[3].(TranslateTransform.X)" BeginTime="00:00:00">
<SplineDoubleKeyFrame KeyTime="00:00:02" Value="54.789"/>
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="textBlock" Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[3].(TranslateTransform.Y)" BeginTime="00:00:00">
<SplineDoubleKeyFrame KeyTime="00:00:02" Value="39.732"/>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</UserControl.Resources>
<Grid x:Name="LayoutRoot" Background="White">
<TextBox x:Name="txtX" Height="23" Margin="8,8,0,0" VerticalAlignment="Top" Text="2" Width="64" HorizontalAlignment="Left"/>
<TextBlock Height="32" HorizontalAlignment="Left" Margin="86,8,0,0" VerticalAlignment="Top" Width="20" Text="+"/>
<TextBox x:Name="txtY" Height="28" Margin="119,8,0,0" VerticalAlignment="Top" Text="3" Width="64" HorizontalAlignment="Left"/>
<TextBlock HorizontalAlignment="Left" Margin="146,110,0,128" VerticalAlignment="Stretch" Width="28" Text="?" TextWrapping="Wrap" FontSize="48" RenderTransformOrigin="0.60699999332428,0.515999972820282" x:Name="textBlock">
<TextBlock.RenderTransform>
<TransformGroup>
<ScaleTransform/>
<SkewTransform/>
<RotateTransform/>
<TranslateTransform/>
</TransformGroup>
</TextBlock.RenderTransform>
</TextBlock>
<Button x:Name="btnSubmit" Height="28" Margin="198,8,119,0" VerticalAlignment="Top" Content="SUM"/>
</Grid>
</UserControl>
|
Vous devriez obtenir ceci :
Vous l'aurez surement déjà compris un clic sur le bouton "Sum" devra nous donner le résultat de la somme des deux TextBox et déclencher le storyboard "AnimResult".
Ajoutons donc le code nécessaire à l'éxécution du storyboard. Ce se fait dans le fichier page.xml.cs :
public partial class Page : UserControl
{
public Page()
{
InitializeComponent();
this.btnSubmit.MouseLeftButtonUp += new MouseButtonEventHandler(btnSubmit_MouseLeftButtonUp);
}
void btnSubmit_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
this.AnimResult.Begin();
}
}
|
Il nous reste à présent à faire la somme des deux textbox pour cela nous allons utiliser WCF.
4. Le projet WCF
Comme pour le projet silverlight : clic droit sur la solution --> add --> new projet.
Dans la partie Web choisissez WCF Service Application et nommé le WCFService1 :
Parmi les fichiers créés automatiquement par le template, deux doivent attiré notre attention : IService1.cs et Service1.cs.
IService1.cs est une interface qui ne contiendra donc que les signatures des méthodes alors que Service1.cs pemettra son implémentation.
Ces fichiers contiennent des exemples de codes que nous pouvons supprimer et remplacer par notre méthode :
IService1.cs :
namespace WCFService1
{
[ServiceContract]
public interface IService1
{
[OperationContract]
int getSum(int x, int y);
}
}
|
Service1.cs :
namespace WCFService1
{
public class Service1 : IService1
{
public int getSum(int x,int y)
{
return x + y;
}
}
}
|
Jettons maintenant un oeil sur le fichier web.config de notre service, plus précisement sur la section system.serviceModel :
<system.serviceModel>
<services>
<service name="WCFService1.Service1" behaviorConfiguration="WCFService1.Service1Behavior">
<endpoint address="" binding="basicHttpBinding" contract="WCFService1.IService1">
<identity>
<dns value="localhost"/>
</identity>
</endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="WCFService1.Service1Behavior">
<serviceMetadata httpGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="false"/>
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
|
Silverlight n'est compatible avec le service qu'en basicHttpBinding. Cette ligne est donc très importante :
<endpoint address="" binding="basicHttpBinding" contract="WCFService1.IService1">
|
5. Ajouter le service WCF au projet Silverlight
Nous avons créé une animation Silverlight et un service WCF, reste maintenant à lier les deux.
Pour cela : clic droit sur le projet silverligt --> add Service Reference.
Vous obtenez alors une fenêtre permettant de sélectionner un service :
Ouvrez ensuite le menu discover et choisissez "Service in solution" par ajouter un service présent dans la solution :
Choisissez Service1 dans la liste et appelez le MonService :
Reste ensuite à utiliser le proxy que nous venons de créer. Modifions donc notre code dans le fichier page.xaml.cs :
namespace SilverlightAnimation
{
public partial class Page : UserControl
{
public Page()
{
InitializeComponent();
this.btnSubmit.MouseLeftButtonUp += new MouseButtonEventHandler(btnSubmit_MouseLeftButtonUp);
}
void btnSubmit_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
MonService.Service1Client client = new SilverlightAnimation.MonService.Service1Client();
client.getSumCompleted += new EventHandler<SilverlightAnimation.MonService.getSumCompletedEventArgs>(client_getSumCompleted);
client.getSumAsync(Convert.ToInt32(txtX.Text), Convert.ToInt32(txtY.Text));
}
void client_getSumCompleted(object sender, SilverlightAnimation.MonService.getSumCompletedEventArgs e)
{
int result = e.Result;
this.textBlock.Text = result.ToString();
this.AnimResult.Begin();
}
}
}
|
En Silverlight il n'est possible d'appeler un service que de manière asynchrone c'est donc la raison pour laquelle nous commençons par attacher une méthode à l'event getSumCompleted de notre client.
Le résultat de la méthode est récupérée dans le paramètre e passé à la méthode client_getSumCompleted.
6. Appeler un webservice hébergé sur un autre site
Par défaut Silverlight refuse d'utiliser un webservice hébergé sur un autre site que l'application pour contourner ce problème et autoriser le "Cross Domain" vous devez ajouter le fichier crossdomain.xml à la racine de votre
serveur web.
Voici son contenu :
<access-policy>
<cross-domain-access>
<policy>
<allow-from>
<domain uri="*"/>
</allow-from>
<grant-to>
<resource path="/" include-subpaths="true"/>
</grant-to>
</policy>
</cross-domain-access>
</access-policy>
|
La section grant-to permet de définir les répertoires pouvant être appelés par l'application.
La section allow-from quand à elle défini les domaines pouvant utiliser le web service.
7. Liens


Ce document est issu de http://www.developpez.com et reste la propriété exclusive de son auteur.
La copie, modification et/ou distribution par quelque moyen que ce soit est soumise à l'obtention préalable de l'autorisation de l'auteur.