Nouvelles Chroniques d'Amethyste

Penser au Sens, pas au Verbe

Programmation avec un fichier svc

Poster un commentaire

Programmation avec un fichier svc

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

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

Démarrons de la même façon avec un projet web vide appelé par exemple HostSvc (mais on pourrait recycler le projet précédent, svc et asmx cohabitent sans problèmes).

Les services déclarés avec un fichier svc sont également appelé Service WCF. Ils utilisent en effet la plomberie WCF.

Notre premier service

Cette fois nous allons créer un service WCF DemoWcfService. Pour l’instant les choses semblent similaires à ce que nous avons précédemment vu avec les Web Service:

a

Et :

z

Un fichier svc réduit à une seule ligne de directive :

<%@ ServiceHost Language= »C# » Debug= »true » Service= »HostSvc.Services.DemoWcfService » CodeBehind= »DemoWcfService.svc.cs » %>

Cela ressemble pas mal à un fichier asmx, la directive est différente, c’est ServiceHost.

Et puis un code behind avec sa déclaration dans la directive. On pourrait également mettre le code directement dans le fichier svc, mais ce n’est pas considéré comme une bonne pratique.

On remarque également l’apparition d’une interface décorée de divers attributs :

[ServiceContract]

publicinterfaceIDemoWcfService

{

    [OperationContract]

    void DoWork();

}

Le code behind est lui très simple :

publicclassDemoWcfService : IDemoWcfService

{

    publicvoid DoWork()

    {

    }

}

On décortiquera plus loin, commençons par vérifier que tout cela marche, mais je vais transformer un peu le service pour le rendre plus intéressant.

L’opération DoWork retourne une String :

[ServiceContract]

publicinterfaceIDemoWcfService

{

    [OperationContract]

    string DoWork();

}

Et bien sûr :

publicclassDemoWcfService : IDemoWcfService

{

    publicstring DoWork()

    {

        return« Bonjour à qui le lira! »;

    }

}

Tester le service

Microsoft fournit un outil de test des clients WCF relativement rudimentaire : wcftestclient.exe que l’on peut lancer depuis une ligne de commande.

http://msdn.microsoft.com/fr-fr/library/bb552364.aspx

et :

http://a1ashiish-csharp.blogspot.com/2012/01/cnet-how-to-test-wcf-web-service-in.html

Mais je le trouve un peu trop rustique et recommande d’autres outils comme SoapUI ou WCFStorm qui a une interface très intuitive en plus.

Note : OK c’est payant. Et alors ? Dans un bilan on doit aussi se demander ce que ça rapporte. C’est le genre de subtilité que certains ne comprennent pas.

Si l’outil de test de Microsoft daigne démarrer vous obtenez ceci :

e

Pour tester on peut double cliquer sur DoWork() puis le bouton Invoke :

r

L’onglet Xml nous affiche la requête et la réponse reçue.

Bref c’est plutôt cool, ça marche du premier coup !

Note : Si le service de test ne démarre pas, cette lecture peut vous aide :

http://msdn.microsoft.com/en-us/library/bb552363.aspx

Il n’est pas non plus interdit de déployer dans IIS et invoquer :

http://localhost/HostSvc/services/demowcfservice.svc

t

Normalement on doit pouvoir tester une opération avec l’url :

/Services/DemoWcfService.svc/DoWork

Pour que ça marche on doit décorer l’opération avec WebGet :

namespace HostSvc.Services

{

[ServiceContract(Namespace = « DemoWcfService »)]

publicinterfaceIDemoWcfService

{

    [OperationContract, WebGet()]

    string DoWork();

}

}

Note : Il faudra référencer la dll System.ServiceModel.Webb.dll

L’attribut WebGet indique qu’une opération de service peut être appelée par le modèle de programmation REST.

Et on obtient :

u

Si un format JSON ne vous convient pas, on peut sérialiser en Xml avec WebGet.

Consommer le service depuis une page web

Justement écrivons en une. Pour cela on a besoin d’une page web, Default.aspx.

Avant de se lancer dans l’aventure du code client examinons de plus près un détail dans la description du service WCF en cliquant sur le deuxième lien de la page vue tout à l’heure :

y

L’espace de nom n’est pas JavaScript-Very-Cool, on va changer les choses en éditant IDemoWcfService et le modifiant légèrement :

[ServiceContract(Namespace = « DemoWcfService »)]

publicinterfaceIDemoWcfService

{

    [OperationContract]

    string DoWork();

}

Et cette fois la vie est plus rose:

o

Côté client on reprend le même code Htmlque le projet asmx et on pose un ScriptManager :

<asp:scriptmanagerID= »Scriptmanager1″runat= »server »>

    <Services>

        <asp:ServiceReferencePath= »~/Services/DemoWcfService.svc »/>

    </Services>

</asp:scriptmanager>

Les adeptes du copier-coller ferons attention à bien changer le nom du service.

Côté JavaScript, les choses ressemblent à ça :

<script>

    function onClick() {

        var proxy = new DemoWcfService.IDemoWcfService();

        proxy.DoWork(OnComplete);

        returntrue;

    }

 

    function OnComplete(args) {

        alert(args);

    }

</script>

On instancie un proxy. Puisque seul le contrat est porté à la connaissance d’un service Wcf, on a bien IDemoWcfService et non pas DemoWcdService.

Côté client le code est identique au cas des Web Services, on passe par un proxy puis on invoque la méthode du service qui nous intéresse et que le proxy expose.

A ce stade vous constaterez toutefois que ça ne marche pas ! Il manque un truc.

Ça ne marche pas parce que comme toujours avec WCF on doit configurer un point de connexion (endpoint).

On peut donc le faire classiquement directement dans le fichier de configuration, nous verrons comment plus loin.

Les versions récentes de WCF proposent des simplifications.

On peut aussi utiliser une des fabriques (ServiceHostFactory) prédéfinies pour créer pour nous l’environnement nécessaire. C’est ce que nous allons faire en éditant le fichier svc :

<%@ServiceHostLanguage=« C#« Debug=« true« Service=« HostSvc.Services.DemoWcfService« CodeBehind=« DemoWcfService.svc.cs« 

    Factory=« System.ServiceModel.Activation.WebScriptServiceHostFactory« 

    %>

WebScriptServiceHostFactory est un ServiceHostFactory personnalisé qui embarque toutes les configurations nécessaires pour que le service WCF fonctionne dans IIS en ajoutant automatiquement un WebScriptEndpoint au service.

Si vous avez besoin d’en savoir plus :

http://msdn.microsoft.com/fr-fr/library/bb410780.aspx

Dans tous les cas, vous devriez constater que tout fonctionne maintenant.

On pourrait, comme pour les web service, consommer le service en JQuery. Le code est en tout point similaire à celui développé dans la section asmx. POST et sérialization JSON.

Consommer le service depuis une application console

On va réutiliser l’application console créée dans la section sur les web services.

Important : WebScriptServiceHostFactory n’est pas prévu pour ce scénario. Il faudra créer à la main les endpoints comme nous le verrons dans la section qui suit.

Depuis le projet console, on fait Add Service Reference :

p

On change le namespace par défaut et on clique sur Discover/Services in solution :

On sélectionne le service svc :

q

On termine avec OK. Diverses transformations sont apportées par VS. Il apparaît un répertoire Service References :

s

Si vous souhaitez voir le code du proxy, cliquez sur le bouton Show All Files et développez MonserviceWcf puis Reference.svcmap.

d

Ne pas modifier ce code à la main. En cas d’accident on peut le régénérer avec la commande du menu contextuel Update Service Reference.

Notez au passage que le fichier de configuration est inchangé.

On peut à tout moment modifier les caractéristiques de cette référence via le menu contextuel Configure Service Reference:

f

On teste avec le code suivant :

using (var proxy2 = new MonServiceWcf.DemoWcfServiceClient())

{

    string message2 = proxy2.DoWork();

    Console.WriteLine(message2);

}

Notez que la classe proxy a héritée du suffixe Client.

Le fichier de configuration

Son contenu va dépendre de la version de .Net avec laquelle on travaille.

En .Net 4.0 il présente cette allure :

g

En réalité on pourrait parfaitement le supprimer, toute la configuration est faite automatiquement par la factory déclarée dans le fichier svc qui se charge de créer des endpoints par défaut. Dans notre cas le binding est basicHttpBinding. On pourrait donc tout à fait ajouter ceci :

<services>

    <servicename=« HostSvc.Services.DemoWcfService« >

        <endpointaddress=« /Services/DemoWcfService.svc« 

            binding=« basicHttpBinding« 

            contrac</services>

Notez bien l’adresse relative, sinon cela ne marche pas. Cela vient du multipleSiteBindingEnabled qui vaut true.

Cette option nous permet d’héberger plusieurs services avec la même adresse de base avec le même protocole.

Intéressons-nous tout d’abord au behavior.

h

SeviceMetaData fournit des informations relatives à la publication des métas données du service. C’est le service MEX auquel on accède via la commande wsdl de la querystring.

httpGetEnabled indique que l’on peut accéder à MEX via une requête http de verbe GET, c’est-à-dire via cette adresse :

http:/localhost :XXXXX/Services/DemoWcfService.svc?wsdl

Le service MEX est utile pour permettre à un client de découvrir automatiquement les opérations d’un service en fournissant un fichier descriptif au format SOAP.

ServiceDebug spécifie les informations de débogage.

Reste AspNetCompatibilityEnabled. C’est un peu long à expliquer, mais ce très bon article que j’ai bien envie de traduire un de ces jours, le fera pour moi:

http://blogs.msdn.com/b/wenlong/archive/2006/01/23/516041.aspx

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