Nouvelles Chroniques d'Amethyste

Penser au Sens, pas au Verbe

Programmation des asmx

Poster un commentaire

Programmation des asmx

Cet article est le deuxième d’une série.

https://amethyste16.wordpress.com/2013/05/18/programmer-avec-les-services-2/

Notre premier service

Les services Web sont hébergés dans IIS comme le suggère le nom, on a donc besoin de créer un projet Web vide, appelons le HostAsmx.

J’aime bien poser mes services dans un répertoire dédié, par exemple Services. Dans ce répertoire ajoutez un item Web Service que nous appellerons DemoWebService.asmx.

Vous faites Add/New Item et choisissez Web Service :

a

On arrive à ceci :

z

VS nous a donc créé un fichier asmx plus un fichier de code behind avec l’extension cs. Le fichier asmx est celui-ci, juste une directive de WebService :

 <%@ WebService Language= »C# » CodeBehind= » DemoWebService.asmx.cs » Class= »HostAsmx.Services. DemoWebService  » %>

 On pourrait, je ne le conseille pas, supprimer le code behind et y mettre directement le code C#.

Le code behind ressemble à celui-ci :

e

Nous le reverrons plus loin, notons juste qu’il expose une seule opération : HelloWorld, pour l’instant testons ce service.

Note : une bien meilleure pratique reste tout de même d’héberger le code behind dans une librairie dédiée. Le fichier asmx se contentera de la référencer.

Tester le service

Le plus direct est de faire F5 pour lancer le fichier asmx. On aboutit sur une page similaire à celle-ci :

r

Il y a autant de lien que d’opérations prises en charge dans le code behind, une seule ici. Si je clique sur ce lien j’arrive sur une page de test.

a

L’affichage obtenu en cliquant sur Appeler dépend du mode de sérialisation.

On pourrait aussi réclamer la description du service en cliquant sur le lien correspondant de la première page :

z

Il s’agit d’un fichier au format SOAP qui peut permettre à une application cliente de créer un proxy afin de communiquer avec notre service. En faisant défiler cette page vous retrouverez la description de l’opération HelloWorld.

On obtient ce genre d’information en invoquant le service avec une querystring comportant juste WSDL. Dans mon cas l’url ressemble à ça :

http://localhost:35196/Services/DemoWebService.asmx?WSDL

 Les services asmx activent par défaut le service de découverte, mais nous verrons que pour les services WCF il faut faire l’activation explicitement.

Note : si vous souhaitez déployer le projet sur IIS, plutôt que IIS Express ou Cassini, il faudra lancer VS en mode administrateur.

Consommer le service depuis une page web

Evidemment en pratique ce n’est pas ainsi que l’on consomme un Web Service. On va en principe consommer un Web Service depuis une page web par exemple.

La page appelle le service via un objet spécialisé appelé : un proxy. Un proxy est une classe qui va fournir une abstraction côté client d’une classe serveur. En gros tout se passe comme si le client instancie la classe de service côté serveur et appelle ses méthodes. Dans les coulisses la classe proxy active une plomberie qui va exécuter le code appelé côté serveur.

Reste à créer ce fameux proxy.

 Ajoutons une page appelons la Default.aspx.

Il y a principalement deux façons de créer un proxy : avec Ajax ou avec JQuery. Bon Ok, il y en a d’autres, mais ce sont les deux mieux outillées.

On verra JQuery plus loin, attaquons avec Ajax. Ajax met à notre disposition le composant ScriptManager qui entre autre tâche est capable de créer pour nous un proxy client vers le service et en toute transparence.

Pour en savoir plus sur le ScriptManager :

http://msdn.microsoft.com/fr-fr/magazine/cc163354.aspx

http://www.wrox.com/WileyCDA/Section/Using-the-ASP-NET-AJAX-ScriptManager.id-305492.html

 On configure le ScriptManager ainsi :

    <asp:scriptmanagerrunat= »server »>

        <Services>

            <asp:ServiceReferencePath= »~/Services/DemoWebService.asmx »/>

        </Services>

    </asp:scriptmanager>

 

Et c’est terminé en fait !

Un peu de codeHtml  tout de même, par exemple ceci :

<inputid= »Button1″type= »button »value= »button »onclick= »return onClick();« />

Puis dans une balise script:

function onClick() {

    HostAsmx.Services.DemoWebService.HelloWorld(OnComplete);

    returntrue;

}

 

function OnComplete(args) {

    alert(args);

}

 Notez bien la première ligne dans onClick, c’est ici qu’à lieu l’appel au service Web. Le ScriptManager a créé pour nous, dans les coulisses, un proxy DemoWebService qui expose l’opération HelloWorld. Le code JavaScript  est similaire à celui que l’on pourrait écrire côté serveur, c’est l’intérêt du proxy.

 Si vous testez vous recevez normalement un message d’erreur qui peut être celui-ci:

Erreur d’exécution JavaScript: « HostAsmx » est indéfini

Et oui, pour être appelé via Ajax on doit ajouter un attribut ScriptService à notre service :

e

Comme l’indique la documentation MSDN cet attribut : indique qu’un service Web peut être appelé à partir d’un script.

On ne peut faire plus clair. Pour en savoir plus :

http://www.codeproject.com/Articles/521723/Webservice-and-Scriptservice

 Et cette fois tout fonctionne !

Notons plusieurs détails :

·         On reçoit le retour du service Web non pas directement, mais dans ne méthode de rappel (OnComplete dans notre exemple). L’appel d’un service Web est en effet asynchrone.

·         On pourrait également ajouter une méthode appelée spécifiquement en cas d’échec de la communication avec le service.

·         Ouvrez également le fichier web.config. Vous ne remarquez rien ? C’est normal, il n’y a rien de spécial dedans. C’est une des grandes forces des Web Services, ça fonctionne et c’est tout.

  On ne va pas se quitter tout de suite, essayons de consommer notre service depuis JQuery.

JQuery offre deux méthodes intéressantes : JQuery.ajax() et JQuery.JSON(). On va essayer avec la première.

Je créée donc une page Default2.aspx identique à la première en ce qui concerne le code Html du moins.

<body>

<formid= »form1″runat= »server »>

 

<div>

    <inputid= »Button1″type= »button »value= »button »onclick= »callSvc();« />

</div>

</form>

</body>

Par défaut le service web est appelé en POST, si on préfère GET il suffit de décorer l’opération avec  l’attribut :

[ScriptMethod(UseHttpGet = true)]

 Et dans ce cas on appelle le service ainsi :

function callSvc() {

    $.ajax({

        type: « GET »,

        url: « /Services/DemoWebService.asmx/HelloWorld »,

        data: «  »,

        contentType: « application/json; charset=utf-8 »,

        dataType: « json »,

        success: function (data, status) {

            alert(data.d);

        },

        error: function (request, status, error) {

            alert(request.responseText);

            //alert(status);

            //alert(error);

        }

    });

}

 

Notez que le retour vient de la propriété « d » de data ainsi que la façon dont on appelle la méthode.

Par défaut la sérialisation est JSON comme indiqué dans le script, mais si on préfère XML il suffit de décorer notre méthode ainsi :

 [ScriptMethod(ResponseFormat = ResponseFormat.Xml)]

 

Les détails sont ici :

 http://msdn.microsoft.com/fr-fr/library/system.web.script.services.scriptmethodattribute.aspx

 

 Et le script d’appel devient:

 

function callSvc() {

    $.ajax({

        type: « POST »,

        url: « /Services/DemoWebService.asmx/HelloWorld »,

        data: «  »,

        contentType: « text/xml; charset=utf-8 »,

        success: function (data, status) {

            alert(data.text);

        },

        error: function (request, status, error) {

            alert(request.responseText);

            //alert(status);

            //alert(error);

        }

    });

}

 

Cette fois c’est la propriété « text » de data qui nous intéresse.

Un dernier point. La déclaration de contentType est en pratique facultative, la plomberie JQuery fait une détection automatique.

Consommer le service depuis une application console

Nous allons créer un projet appelé ConsoleClient.

 On doit là aussi créer un proxy. Pour cela on dispose de l’outil svcutil.exe, mais on peut aussi demander à VS de faire le boulot et c’est ce que nous allons faire.

Jusqu’à VS 2008 on disposait du menu Add Web Reference pour créer un proxy vers un service asmx. Ce menu a depuis migré dans une des options de Add Service Reference afin de souligner que Add Web Reference est maintenant une méthode obsolète.

 On choisit ConsoleClient puis dans le menu contextuel du projet Add Service Reference. Cette fenêtre s’ouvre :

t

Cliquer sur Advanced :

y

On clique sur Add Web Reference :

u

Puis enfin Web Service in this Solution. On sélectionnera le service exposé par Hostasmx puis on clique sur Add Reference. On peut aussi modifier le nom du service, nous allons garder localHost.

i

Le projet a été quelque peu modifié.

o

Le paramètre URL Behavior = Dynamic indique que les paramètres de la référence web sont copiés dans le fichier de configuration et non pas codés en dur.

p

Pour tester vous n’avez plus qu’à saisir le code suivant :

localhost.DemoWebService proxy = new localhost.DemoWebService();

string message = proxy.HelloWorld();

 

Console.WriteLine(message);

 Extrêmement simple comme vous le voyez.

Note : Je vois beaucoup de développeurs écrire laborieusement Console.WriteLine….. Sachez qu’il existe un snipet qui fait le boulot, son nom est cw.

 Revoyons le code-behind

Penchons-nous maintenant sur le code behind que revoici :

[WebService(Namespace = « http://tempuri.org/ &raquo;)]

[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]

[System.ComponentModel.ToolboxItem(false)]

// To allow this Web Service to be called from script, using ASP.NET AJAX, uncomment the following line.

[System.Web.Script.Services.ScriptService]

publicclassDemoWebService : WebService

{

 

    [WebMethod]

    publicstring HelloWorld()

    {

        return« Hello World »;

    }

}

La classe WebService offre des possibilités supplémentaires comme l’accès à Session ou Application. Si vous n’en avez pas besoin… il suffit de ne pas la déclarer, elle n’est pas obligatoire.

En fait, n’importe quelle classe décorée de l’attribut WebService et exposant des méthodes publiques décorées de l’attribut WebMethod est un service Web.

Essayer est la meilleure façon de s’en convaincre…

A ces détails près vous constaterez que le code est un code tout à fait normal, la classe DemoWebService pourrait parfaitement être consommée directement.

Publicités

Laisser un commentaire

Entrez vos coordonnées ci-dessous ou cliquez sur une icône pour vous connecter:

Logo WordPress.com

Vous commentez à l'aide de votre compte WordPress.com. Déconnexion / Changer )

Image Twitter

Vous commentez à l'aide de votre compte Twitter. Déconnexion / Changer )

Photo Facebook

Vous commentez à l'aide de votre compte Facebook. Déconnexion / Changer )

Photo Google+

Vous commentez à l'aide de votre compte Google+. Déconnexion / Changer )

Connexion à %s