Bonjour à tous !

Autant être clair, j'essaie depuis quelques jours de comprendre le fonctionnement de Silverlight et de WCF.

Je vous avouerais que c'est fortement pénible de faire communiquer un projet WCF avec une appli Silverlight.

J'ai donc un projet Silverlight, pour communiquer avec ma base de donnée, je me suis décidé à utiliser WCF. J'ai donc crée un projet Windows Communication Foundation.

Pour commencer doucement je me suis dit que j'allais tester la fonction GetData fournit en exemple.

Voici le code :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public class CommercialService : ICommercialService
    {
        public string GetData(int value)
        {
            return string.Format("You entered: {0}", value);
        }
 
        public CompositeType GetDataUsingDataContract(CompositeType composite)
        {
            if (composite.BoolValue)
            {
                composite.StringValue += "Suffix";
            }
            return composite;
        }
et
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
   [ServiceContract]
    public interface ICommercialService
    {
 
        [OperationContract]
        string GetData(int value);
 
        [OperationContract]
        CompositeType GetDataUsingDataContract(CompositeType composite);
 
        //[OperationContract]
        //List<T_REGION> GetRegions();
 
        // TODO: Add your service operations here
    }
 
 
    // Use a data contract as illustrated in the sample below to add composite types to service operations.
    [DataContract]
    public class CompositeType
    {
        bool boolValue = true;
        string stringValue = "Hello ";
 
        [DataMember]
        public bool BoolValue
        {
            get { return boolValue; }
            set { boolValue = value; }
        }
 
        [DataMember]
        public string StringValue
        {
            get { return stringValue; }
            set { stringValue = value; }
        }
    }
Enfin bref la pluspart d'entre vous reconnaitront le code par défaut fourni lors de la création d'un projet WCF.

Ensuite dans la partie silverlight je fais ceci :

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public RechercheSouscription()
        {
            InitializeComponent();
            Init_CBO();
        }
        #endregion
 
        private void Init_CBO()
        {
            CommercialServiceReference.CommercialServiceClient service = new AS3C.CommercialServiceReference.CommercialServiceClient();
            service.GetDataCompleted +=new EventHandler<AS3C.CommercialServiceReference.GetDataCompletedEventArgs>(service_GetDataCompleted);
            service.GetDataAsync(10);
            //service.GetRegionsCompleted +=new EventHandler<AS3C.CommercialServiceReference.GetRegionsCompletedEventArgs>(service_GetRegionsCompleted);
            //service.GetRegionsAsync();
        }
        private void service_GetDataCompleted(object sender, CommercialServiceReference.GetDataCompletedEventArgs e)
        {
            this.txt_TEST.Text = e.Result;
        }
D'après ce que j'ai pu lire à droite, à gauche c'est de cette manière qu'il faut procéder.

J'ai bien sûr penser à modifier mon web.config :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
<endpoint address="" binding="basicHttpBinding" contract="AS3C.WFCService.ICommercialService">
Et j'ai en plus ajouter un fichier clientaccesspolicy.xml à la racine de mon projet WCF avec ce contenu :

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
<?xml version="1.0" encoding="utf-8"?>
<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>
Et malgré tout ça, l'application renvoie une erreur :

Une erreur s'est produite en tentant d'effectuer une demande à l'URI 'http://localhost:65038/CommercialService.svc'. Ce problème peut être dû à une tentative d'accès à un service entre domaines sans qu'une stratégie entre domaines appropriée soit en place, ou une stratégie inadaptée aux services SOAP. Il est possible que vous soyez contraint de contacter le propriétaire du service pour publier un fichier de stratégie entre domaines et veiller à ce qu'il autorise l'envoi d'en-têtes HTTP SOAP. Cette erreur peut également être liée à l'utilisation de types internes dans le proxy de service Web sans utiliser l'attribut InternalsVisibleToAttribute. Consultez l'exception interne pour plus de détails.
Détails :
{System.ServiceModel.CommunicationException: Une erreur s'est produite en tentant d'effectuer une demande à l'URI 'http://localhost:65038/CommercialService.svc'. Ce problème peut être dû à une tentative d'accès à un service entre domaines sans qu'une stratégie entre domaines appropriée soit en place, ou une stratégie inadaptée aux services SOAP. Il est possible que vous soyez contraint de contacter le propriétaire du service pour publier un fichier de stratégie entre domaines et veiller à ce qu'il autorise l'envoi d'en-têtes HTTP SOAP. Cette erreur peut également être liée à l'utilisation de types internes dans le proxy de service Web sans utiliser l'attribut InternalsVisibleToAttribute. Consultez l'exception interne pour plus de détails. ---> System.Security.SecurityException ---> System.Security.SecurityException: Erreur de sécurité.
à System.Net.Browser.BrowserHttpWebRequest.InternalEndGetResponse(IAsyncResult asyncResult)
à System.Net.Browser.BrowserHttpWebRequest.<>c__DisplayClass5.<EndGetResponse>b__4(Object sendState)
à System.Net.Browser.AsyncHelper.<>c__DisplayClass2.<BeginOnUI>b__0(Object sendState)
--- Fin de la trace de la pile d'exception interne ---
à System.Net.Browser.AsyncHelper.BeginOnUI(SendOrPostCallback beginMethod, Object state)
à System.Net.Browser.BrowserHttpWebRequest.EndGetResponse(IAsyncResult asyncResult)
à System.ServiceModel.Channels.HttpChannelFactory.HttpRequestChannel.HttpChannelAsyncRequest.CompleteGetResponse(IAsyncResult result)
--- Fin de la trace de la pile d'exception interne ---
à System.ServiceModel.AsyncResult.End[TAsyncResult](IAsyncResult result)
à System.ServiceModel.Channels.ServiceChannel.SendAsyncResult.End(SendAsyncResult result)
à System.ServiceModel.Channels.ServiceChannel.EndCall(String action, Object[] outs, IAsyncResult result)
à System.ServiceModel.ClientBase`1.ChannelBase`1.EndInvoke(String methodName, Object[] args, IAsyncResult result)
à AS3C.CommercialServiceReference.CommercialServiceClient.CommercialServiceClientChannel.EndGetData(IAsyncResult result)
à AS3C.CommercialServiceReference.CommercialServiceClient.AS3C.CommercialServiceReference.ICommercialService.EndGetData(IAsyncResult result)
à AS3C.CommercialServiceReference.CommercialServiceClient.OnEndGetData(IAsyncResult result)
à System.ServiceModel.ClientBase`1.OnAsyncCallCompleted(IAsyncResult result)}
Enfin bref je m'en remet à vos lumières je pense que je dois pas être loin de trouver la solution mais j'avoue qu'en ce moment mes nerfs ont plus envie de balancer ma machine par la fenêtre

Cordialement