Web Service

 

EXO web service

·       Coder et déployer un web service simple

·       Dans SilverLight, depuis un bouton, appeler le web service et afficher le résultat.

 

Beaucoup de présentations de Silverlight montrent des gadgets de présentation. Ce n’est pas notre objectif ici. Nous voulons montrer que l’on peut faire des applications complètes en Silverlight. Il faut donc être capable de faire exécuter des traitements à un serveur. Le plus simple et le plus élégant est d’utiliser des web services.

 

Commençons par un service trivial, pour prendre en main la technique.

 

Le service web est très classique :

 

[WebService(Namespace = "http://garraud.eu/")]

[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]

 

public class ServiceCatalogue : System.Web.Services.WebService

{

    public ServiceCatalogue ()

    {

//Supprimez les marques de commentaire dans la ligne suivante //si vous utilisez des composants conçus

 

        //InitializeComponent();

    }// fin constructeur

 

    [WebMethod]

    public string HelloWorld()

    {

        return "Hello World";

    }// fin Hello

}//Fin classe

 

 

L’utilisation dans SilverLight, par contre, n’est pas triviale :

 

  1. Le service web doit être sur le même serveur que le serveur délivrant le .xap ; en effet les cross domain calls sont sujets à des restrictions du point de vue sécurité. (voir plus loin)
  2. SilverLight ne supporte pas le client service web, vous devez utiliser le client WCF.
  3. L’appel du service web doit se faire en mode asynchrone.

 

 

L’assistant peut programmer une classe proxy pour vous, si comme sur ma version express « ajouter une référence de web service » n’est pas disponible, utiliser « ajouter une référence de service. »

 

RefService

 

L’assistant génère toutes les classes utiles au proxy dans l’espace de nom que vous avez choisi, ici ServiceReferenceCatalogue.

 

 

Il génère aussi le fichier de configuration WCF adéquat. :

 (Voir la documentation WCF).

 


Et il faut donc programmer ainsi l’accès au service web depuis Silverlight :

 

       /// <summary>

        /// Appel d'un service web depuis SiverLigth

        /// Le mode asynchrone semble requis

        /// </summary>

 

        private void btnHello_Click(object sender, RoutedEventArgs e)

        {

            //déclarer un proxy sur le service

            ServiceReferenceCatalogue.ServiceCatalogueSoapClient leProxy = new Bdd.ServiceReferenceCatalogue.ServiceCatalogueSoapClient();

 

            //attacher un handler de fin

leProxy.HelloWorldCompleted += new EventHandler<Bdd.ServiceReferenceCatalogue.HelloWorldCompletedEventArgs>(ClicHelloWorldCompleted);

 

            //lancer l'opération

            leProxy.HelloWorldAsync();

        }

 

      // Le handler de fin de service web

      // traite la réponse.

private void ClicHelloWorldCompleted(object sender, Bdd.ServiceReferenceCatalogue.HelloWorldCompletedEventArgs e)

        {

            String result = e.Result.ToString();

            this.txtHello.Text = result;

        }//fin hello click completed

 

Service web ou WCF.

 

Votre service peut être un service web ou un service WCF. Le client silverlight est obligatoirement WCF. En ce qui concerne le serveur, il est conseillé d’utiliser la version « pour silverlight », car elle contient l’annotation.

 

[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]

 

    public class Service1 : IService1

    {

        public void DoWork()

        {

        }

    }

 

D’autre part ce service doit être sur le même serveur que le fichier xap, pas de cross domain call en WCF.

Transmission des exceptions.

 

En WCF, pour que le détail des exceptions soit bien propagé vous devez spécifier dans le web config :

 

<system.serviceModel>

        <behaviors>

            <serviceBehaviors>

                <behavior name="ServiceCalculBehavior">

                    <serviceMetadata httpGetEnabled="true" />

                    <serviceDebug includeExceptionDetailInFaults="true" />

                </behavior>

            </serviceBehaviors>

        </behaviors>

 

 

Cependant pour WCF comme pour WS, le détail de l’exception n’est pas disponible dans Silverlight : on obtient : « not found ». En effet le http possède le code 500 en cas de faute.

 

Pour remédier à ceci il faut demander que http soit géré par silverlight et non pas par le navigateur, en ajoutant, avant l’appel du service,  l’instruction :

 

System.Net.WebRequest.RegisterPrefix

("http://",System.Net.Browser.WebRequestCreator.ClientHttp);

leProxy.DoWorkAsync(val);

 

 

Cross Domains Calls.

 

 

Contrairement à ce qui est conseillé dans l’exercice précédent, il est possible d’appeler un service web qui n’est pas sur le même serveur que le serveur web qui héberge votre site Html-Silverlight. Mais il faut prendre des précautions :

 

  1. Dans

 

PageTest

 

 

Choisir la première option, sinon silverlight refusera l’appel. (Etrange)


  1. Autoriser votre web service à accepter des appels extérieurs, pour cela il faut ajouter à la racine du site offrant le web service :

 

 

<?xml version="1.0" encoding="utf-8"?>

<access-policy>

  <cross-domain-access>

    <policy>

      <allow-from http-request-headers="*">

        <domain uri="*"/>

      </allow-from>

      <grant-to>

        <resource path="/" include-subpaths="true"/>

      </grant-to>

    </policy>

  </cross-domain-access>

</access-policy>

 

 

<?xml version="1.0"?>

<!DOCTYPE cross-domain-policy SYSTEM "http://www.macromedia.com/xml/dtds/cross-domain-policy.dtd">

<cross-domain-policy>

  <allow-http-request-headers-from domain="*" headers="*"/>

</cross-domain-policy>

 

 

Dans les specimens ci-dessus tous les accès sont autorisés.

 

 Dans silverLight 4, ce point a été amélioré.

 

 

Chapitre suivant.