Les services web et la plate-forme Microsoft .NET
Introduction
Définition
Des problèmes
Une solution
Les trois piliers des services Web
La Découverte
La Description
L'Échange
Récapitulatif
Exemple - La carte de crédit
Création d'un projet WebForm
Algorithme de validation et implantation
Tests
Implantation du service Web
Tester un service Web
Dans cet article, vous trouverez une petite présentation générale des services
Web ainsi qu'une application avec la plate-forme Microsoft .NET. Dans un premier temps,
nous allons donner une définition rapide des services Web. Nous présenterons un
problème et une solution proposée par Microsoft grâce à des standards déjà
existants. Dans une deuxième partie plutôt théorique, nous parlerons des différentes
technologies qui constituent les services Web. Enfin, nous passerons à la pratique
avec un exemple de service Web qui permet de vérifier la validité du numéro d'une
carte de crédit. Nous utiliserons l'environnement Visual Web Developer 2005 Express Edition, un peu d'ASP.NET
pour l'interface et le langage C# pour créer ce service Web.
Introduction
Définition
Un service Web est un ensemble de technologies qui permet à des applications distantes
de communiquer grâce à des messages. On peut prendre l'exemple d'un échange
de données entre une application .NET et une application Java.
Les services
Web représentent l'implantation
d'une architecture nommée SOA (Service Oriented
Architecture ou en français, Architecture Orientée Service), complémentaire
à la Programmation Orientée Objet
(POO). Techniquement, les principaux points forts des SOA sont
la capacité à fournir des briques logicielles réutilisables et à offrir un couplage
lâche à ces dernières.
Contrairement aux technologies existantes telles que DCOM et
.NET Remonting de Microsoft, CORBA, ou RMI de Java, les SOA utilisent des standards, dont XML est la base,
indépendants des plates-formes sous-jacentes.
Des problèmes
Les technologies précédemment citées posent en fait plusieurs problèmes et l'expérience montre bien
qu'elle ne sont pas adaptées aux divers scénarios proposés par le Web. Le premier
problème apparaît dans la dernière ligne du précédent paragraphe: Microsoft et Java,
c'est-à-dire des technologies propriétaires qui ne permettent que l'amélioration
de leurs propres protocoles. Les applications peuvent aussi rencontrer des obstacles
pour communiquer entre elles sur le Web. C'est un second problème. En effet, un
administrateur réseau soucieux de sécurité aura pour habitude d'interdire pratiquement
tout type de communication en réduisant le nombre de ports ouverts au strict minimum.
Ces deux problématiques ainsi que d'autres ont clairement mis en avant le fait qu'il était temps
d'adopter une nouvelle approche.
Une solution
Vous l'avez déjà compris, la concrétisation de cette approche s'appelle les services
Web.
La véritable naissance des services Web ne date que de 2002 avec l'adoption
de cette technologie par le W3C.
Voyons en quoi les services Web constituent
une solution particulièrement intéressante.
- Un service Web permet à des clients de communiquer entre eux indépendamment
des plates-formes utilisées. On parle de services interopérables ou d'interopérabilité
d'une façon générale.
- Un service Web prend en charge les clients qui accèdent au service distant depuis
le Web.
- Un service Web s'appuie sur des normes Internet déjà existantes.
- Un service Web ne dépend pas d'un langage de programmation particulier.
- Un service Web n'est pas couplé à une infrastructure de composants particuliers
(i.e ni installations ni achats particuliers).
Bien que nous soyons très loin de tous penser en terme de services, il faut s'habituer
à ce type de solutions technologiques qui va prendre de plus en plus d'importance dans les années à venir (cf. Windows Communication Foundation dans Windows Vista).
Un service Web est donc un ensemble de technologies qu'il est possible de distinguer
selon trois axes fondamentaux.

Les trois piliers des services Web
La Découverte: comment identifier et
localiser les services Web ?
Ce premier pilier propose un annuaire mondial nommé UDDI (Universal Description,
Discovery and Integration) qui permet
aux entreprises d'indexer publiquement leurs services Web (et la documentation technique
qui va avec). Le but est de fournir une documentation technique des services Web
afin que d'autres entreprises "découvrent" ces derniers. Deux entreprises peuvent
ainsi collaborer plus facilement. UDDI est une norme qui repose sur le langage
XML.
UDDI est issue d'une initiative de Microsoft et d'IBM (qui ont ensuite été rejoints
par d'autres acteurs importants tels que SAP ou Oracle). Il existe actuellement
3 versions de la norme UDDI.
La Description: comment exposer les
fonctions des services Web ?
La norme WSDL (Web
Service Description Language)
constitue le second pilier des services Web. WSDL permet de spécifier le format des messages, les protocoles, qui doivent être utilisés et la localisation des différentes
machines qui mettent en oeuvre un service Web. Cette norme est également fondée
sur XML.
En exemple, voici le document
WSDL d'un service Web très simple qui se contente
de renvoyer la somme de deux entiers: Ajouter
Si vous réduisez les sept noeuds fils de l'élément wsdl:definitions,
vous vous rendrez compte de la simplicité
de la structure d'un document WSDL (du point de vue XML) qui se compose de cinq
éléments principaux: le service, les bindings,
les PortTypes, les messages et les types.
|
<types> |
Contient les définitions de types utilisant un système de typage. Les éléments
type permettent de définir des structures de données complexes. WSDL
s'appuie sur XSD
(XML Schema Definition) pour
définir les types échangés, si ce ne sont pas des types simples. |
|
<message> |
Décrit les noms et types d'un ensemble de champs à transmettre. |
|
<portType> |
Décrit un ensemble d'opérations. Chaque opération a zéro ou un message en entrée,
zéro ou plusieurs messages de sorties ou de fautes. |
|
<binding> |
Associe la définition d'un portType à un protocole particulier
(SOAP, HTTP,
MIME, ...). |
|
<service> |
Définit un ensemble de points d'entrée voisins (ports) proposés par le service Web. |
L'étude d'un tel document serait fondamentale pour parfaitement bien
comprendre
de quelle façon un client interagit avec un service Web. Cet article n'est
qu'une présentation générale des services Web. Nous reviendrons donc plus tard sur un approfondissement
de la norme WSDL.
L'Echange: comment échanger les messages
entre les services Web ?
Le dernier pilier est représenté par le protocole SOAP qui permet l'échange d'informations entre le client
et le serveur. SOAP utilise le langage XML pour formater les messages et le
protocole HTTP (le plus souvent) pour les véhiculer. D'autres protocoles tels que
SMTP,
FTP ou POP
peuvent être utilisés. Pour illustrer ce protocole, considérons un service Web qui
contient une méthode Ajouter:
public int Ajouter(int a, int b)
{
return a + b;
}
Voici à quoi ressemble une requête SOAP pour la somme des entiers 6 et 3:
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<Ajouter>
<a>6</a>
<b>3</b>
</Ajouter>
</soap:Body>
</soap:Envelope>
et la réponse SOAP générée par l'application distante:
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<AjouterResponse>
<AjouterResult>9</AjouterResult>
</AjouterResponse>
</soap:Body>
</soap:Envelope>
On ne s'attardera pas sur cette norme qui mérite également qu'on lui consacre
un article complet. Nous pouvons cependant faire quelques commentaires rapides. Dans
le code de la requête, on constate que des éléments Ajouter,
a et
b
ont été créés. Ils correspondent respectivement à notre méthode Ajouter et à ses paramètres.
Dans le code de la requête, nous voyons apparaître l'élément AjouterResult qui contient
le résultat de la méthode
Ajouter.

Récapitulatif
Voici un récapitulatif des principales normes qui fondent les services Web, classées
selon les trois axes précédemment évoqués: la Découverte, la Description et l'Échange.
On remarquera le rôle fondamental que tient le langage XML dans les services Web
!
D'une façon générale, XML est de plus en plus utilisé dans les nouvelles technologies
de l'information puisqu'il représente le début d'une solution à l'un des grands défits posés
par les systèmes d'information: l'interopérabilité.
Exemple - La carte de crédit
Dans cette illustration, nous allons créer un service Web qui permettra de tester
la validité d'une carte de crédit à partir de sa date d'expiration et de son numéro.
Pour tester la date d'expiration nous utiliserons des types .NET et pour tester
la validité de son numéro nous utiliserons un algorithme standard modulo
10.
Voici les différentes étapes que nous allons suivre:
- Création d'un projet WebForm (ASP.NET et C#) classique pour l'interface.
- Description de l'algorithme qui permet de vérifier le numéro de la carte et implantation
dans le projet.
- Création d'un service Web au sein du projet et modification de ce dernier afin de
prendre en compte le service (pas de panique, c'est plus qu'enfantin ;-))
Pour résumer, nous allons créer un premier projet sans service Web. Ensuite, nous
incluerons un service Web dans ce même projet en effectuant les modifications en
conséquence. Pourquoi faire tout ça ?
Le but est de montrer la grande souplesse de la plate-forme .NET: en seulement quelques
clicks vous pouvez refondre très rapidement une application .NET afin d'accéder
à sa logique métier via des services Web.
Dépêchons-nous de voir comment nous devons nous y prendre !

Création d'un projet WebForm
Ouvrons Visual Web Developer et créons un nouveau site Web en choisissant
New Web site... dans le menu File. Une boîte
de dialogue apparaît: sélectionnons un projet de type ASP .NET Web Site,
choisissons Visual C# pour Language et choisissons
un emplacement pour notre application que l'on nommera CarteDeCredit
(exemple de chemin: C:\CarteDeCredit). Cliquons sur OK
!
Par défaut, le projet s'ouvre avec le fichier Default.aspx en mode
Source. Renommons ce fichier en CarteDeCredit.aspx.
Pour cela cliquons sur l'onglet Solution Explorer qui se trouve
sur le partie droite de l'espace de travail, cliquons-droit sur le fichier Default.aspx
et choisissons l'option Rename. Plaçons-nous maintenant dans le
mode Design (onglet en bas, à gauche).
Ouvrons l'onglet ToolBox qui se situe à gauche de l'espace de travail.
Si l'onglet n'apparaît pas, on pourra le trouver dans le menu View
ou, il apparaîtra après avoir réalisé la combinaison CTRL + ALT + X. On pourra cliquer
sur la petite épingle située à droite de la fenêtre ToolBox afin
d'éviter la fermeture automatique du volet. Dans la liste des contrôles standards,
on drag and drop (glisser-déposer) un contrôle TextBox, un contrôle
Calendar, un contrôle Literal et un contrôle
Button.
Après un petit tour de magie, on pourra obtenir ceci:
Après avoir obtenu quelque chose de similaire (ou de totalement différent, c'est
selon les goûts ;-) ), cliquons-droit sur le contrôle TextBox et
descendons jusqu'à l'option Properties du menu. Le volet des propriétés
du TextBox s'ouvre sur le partie droite de l'espace de travail.
Comme nous l'avons fait avec le volet ToolBox, bloquons-le ! Descendons
jusqu'à l'ID du contrôle et remplaçons TextBox1
par code_txtb. Ajoutons également le texte Valider les informations
pour la propriété Text qui se trouve un peu plus haut dans la liste.
De façon analogue, on définira l'ID
du Calendar par validite_calendar, celui du
Literal par carteInvalide_lit et celui du Button
par valider_but.
Nous voilà donc munis d'une magnifique interface :-D

Algorithme de validation et implantation
L'algorithme qui permet
de valider le numéro de la carte est très simple. Il s'agit
de l'algorithme
de Luhn:
- Décomposer le numéro en une série de chiffres.
- En partant du chiffre le plus à droite, multiplier par 2 les chiffres de rang pair.
Si une multiplication donne un nombre, additionner les chiffres de ce nombre (ce
qui revient à soustraire 9 au nombre).
- Additionner ensemble les chiffres précédemment obtenus.
- Tester si la somme est divisible par 10. Si c'est
le cas alors le numéro est valide.
Exemple:
À présent, implantons cet algorithme dans notre projet. Pour cela cliquons, sur
l'onglet Solution Explorer et cliquons sur la petite croix se trouvant à côté de CarteDeCredit.aspx
afin de faire apparaître le fichier CarteDeCredit.aspx.cs. Double-cliquons
sur ce fichier et plaçons la méthode suivante juste après la méthode d'événement
Page_Load:
public bool Valider(string NumeroCarte, DateTime dateExp)
{
// Si la date de validité n'a pas expiré
if (dateExp >= DateTime.Today)
{
int total = 0;
int temp = 0;
char[] chiffres = NumeroCarte.ToCharArray();
// Tester chaque chiffre du numéro entré.
for (int i = 0; i < NumeroCarte.Length; i++)
{
// Si le chiffre est impair, l'ajouter à la somme.
if (((i + 1) % 2) == 0)
{
total += int.Parse(chiffres[i].ToString());
}
// Si le chiffre est pair, le multiplier par 2 et l'ajouter à la somme.
else
{
temp = int.Parse(chiffres[i].ToString()) * 2;
// Si le chiffre est en fait un nombre, ajouter les chiffres qui
// le composent (i.e retrancher 9) et ajouter le tout à la somme.
if (temp > 9)
{
temp = (int)temp - 9;
}
total += temp;
}
}
if ((total % 10) == 0)
{
return true;
}
else
{
return false;
}
}
else
{
return false;
}
}
Cette méthode est assez simple: en paramètre, on passe le numéro de carte sous la
forme d'une chaîne de caractères
NumeroCarte
et la date d'expiration
dateExp sous la forme d'un type DateTime. La méthode renvoie true uniquement si la date
de validité n'a pas expiré et si la somme calculée avec l'algorithme Luhn est divisible
par 10. Elle renvoie
false dans les autres cas.
Cliquons maintenant sur l'onglet CarteDeCredit.aspx pour repasser
en mode Design. Double-cliquons sur le bouton afin de générer
automatiquement la méthode d'événement associée. Voici le code à ajouter dans cette méthode:
protected void valider_but_Click(object sender, EventArgs e)
{
try
{
if ( Valider(code_txtb.Text, validite_calendar.SelectedDate) && (code_txtb.Text != String.Empty))
{
Response.Redirect("succes.htm");
}
else
{
carteInvalide_lit.Text = "Carte de crédit non valide";
}
}
catch (Exception)
{
carteInvalide_lit.Text = "Code non valide";
}
}
Trois cas de figure peuvent se présenter lorsque l'utilisateur clique sur le bouton
pour valider les informations qu'il a entré.
- Si le numéro est valide et si l'utilisateur n'a pas laissé le champ TextBox
vide (sinon
Valider renvoie forcément 1) alors il est redirigé vers
une page lui confirmant que les informations entrées sont valides. Pour cela, on
pourra rajouter un document html en allant dans Solution Explorer,
en cliquant-droit sur le sommet de l'arborescence et en choisissant Add New
Item dans le menu. Choisissons le second type de fichier de la boîte
de dialogue et changeons le nom HTMLPage.htm en succes.htm.
Nous n'irons pas plus loin avec ce document car
ce n'est que de la pure décoration. - Si l'utilisateur saisit un numéro sous un mauvais format (i.e, s'il entre autre
chose que des chiffres) et si la date de validité n'a pas expiré alors le message
d'erreur "Code non valide" s'affiche à l'emplacement du contrôle
Literal. Si la date de validité a expiré, le message d'erreur est
"Carte de crédit non valide".
- Si l'utilisateur laisse le champ TextBox vide, quelle
que soit la date de fin de validité, un message d'erreur "Carte de crédit non
valide" s'affiche.
Nous pourrions compléter cette méthode avec d'autres tests.
Remarque: on pourra afficher les
messages d'erreurs en rouge. Pour cela, on cliquera une seule fois sur le contrôle Literal
en mode Design et on passera en mode Source. Il
suffira d'insérer du style de la façon suivante:
<span style="color:#ff0000"><asp:Literal ID="carteInvalide_lit" runat="server"></asp:Literal></span>

Tests
Nous pouvons maintenant lancer l'application à l'aide du raccourci CTRL + F5
ou F5 tout court pour utiliser le mode débogage (qui n'est pas
utile ici puisque notre code ne contient évidemment pas d'erreurs ;-) )
Voici quelques exemples d'utilisations de l'application :
 |
 |
|
Pas de code entré, pas de date sélectionnée |
La date est valide mais le format du code est incorrect |
 |
 |
|
Le code est correct mais la carte est périmée |
Succès avec le code 123 et la date 5 Février |

Implantation du service Web
Implantation. Quel bien grand mot pour une tâche aussi simple à réaliser !
Il est important de souligner que la plate-forme .NET a justement été conçue pour
faciliter l'interopérabilité des applications dans un milieu hétérogène via
l'exploitation intensive du
standard XML (W3C).
Nous devons commencer par créer un fichier d'extension .asmx.
Comme nous l'aurons facilement deviné, ce type de fichier représente un service Web.
Cliquons-droit dans le volet Solution Explorer et choisissons l'option
Add New Item.... Le type de fichier que nous recherchons se trouve
en deuxième position de la deuxième colonne. Changeons le nom WebService.asmx,
en CarteDeCredit.asmx. Cochons la case Place code in separate
file puis cliquons sur OK.
Par défaut, le fichier contient la méthode suivante:
[WebMethod]
public string HelloWorld() {
return "Hello World";
}
Voici une méthode prête à être exposée par le service Web. Et oui, l'attribut
WebMethod permet à lui seul de
faire la distinction entre une méthode classique et une méthode web
! Attention, la notion d'attribut est quelque chose de très précis dans .NET. Nous
verrons ultérieurement ce qu'est un attribut. Il y a aussi une petite chose à rajouter:
une méthode web doit être publique.
Si vous utilisez plusieurs méthodes dans votre service Web,
chaque méthode doit être déclarée avec un attribut WebMethod.
Nous allons laisser la méthode
HelloWorld dans notre code afin d'illustrer cela. Retournons
dans le fichier CarteDeCredit.aspx.cs et coupons la méthode Valider
que nous devons coller juste après la méthode HelloWorld de notre service
Web. Comme pour
la méthode HelloWorld,
rajoutons un attribut
WebMethod juste au-dessus de la définition de Valider.
Il nous faut à présent ajouter ce que l'on nomme une référence Web
à notre projet. Pour cela, cliquons-droit sur la racine de notre projet dans le
volet Solution Explorer et choisissons l'option Add Web Reference.
La fenêtre suivante s'ouvre:
Cliquons sur Web services in this solution. On a ensuite:
Cliquons sur CarteDeCredit. Comme nous avons laissé la méthode
HelloWorld,
il nous faudra cliquer sur la méthode
Valider à l'écran suivant:
En ce qui concerne le nom de la référence Web (Web Reference name),
il faut laisser le nom localhost qui représente le nom de la machine
qui héberge le service Web. Ce nom indique que nous travaillons sur la machine locale.
D'une façon générale, on remplacera le nom localhost par le nom
de l'ordinateur qui héberge le service Web (ce que nous aurions pu faire ici).
Nous pouvons ensuite cliquer sur le bouton Add Reference (à droite)
pour créer la référence.
On remarquera que la référence que nous venons de créer se constitue d'un document
WSDL (cf. partie précédente), d'un document DISCOMAP
et d'un document DISCO.
Nous devons maintenant
penser au bouton. En effet, un click sur le bouton doit provoquer l'appel de la méthode
Valider de notre service Web. Pour cela, il est nécessaire de
modifier le code relatif à l'événement bouton, i.e la méthode valider_but_Click.
L'idée est simple: nous devons créer une instance de notre service Web et appliquer
à cette instance la méthode
Valider. En fait, nous manipulons notre service Web comme un
véritable type .NET !
Voici donc la nouvelle tête de notre méthode (les changements apparaissent en rouge):
public void valider_but_Click(object sender, EventArgs e)
{
localhost.CarteDeCredit carte = new localhost.CarteDeCredit();
try
{
if (carte.Valider(code_txtb.Text, validite_calendar.SelectedDate) && (code_txtb.Text != String.Empty))
{
Response.Redirect("succes.htm");
}
else
{
carteInvalide_lit.Text = "Carte de crédit non valide";
}
}
catch (Exception)
{
carteInvalide_lit.Text = "Code non valide";
}
}
Il est important de remarquer que notre type (le service Web)
CarteDeCredit doit être instancié sous la forme: [nom_de_l_ordinateur].CarteDeCredit
= new [nom_de_l_ordinateur].CarteDeCredit();
Dans notre cas, le nom de l'ordinateur (sous-entendu le "nom de l'ordinateur qui
héberge l'application") correspond à localhost.
Visual Web Developer nous permet de tester facilement et
rapidement nos applications locales via un serveur web intégré qui sélectionne aléatoirement
un numéro de port (par exemple: http://localhost:2125/CarteDeCredit/).
Nous pouvons nous-même spécifier ce port: cliquer sur le nom de l'application dans
le volet Solution Explorer, cliquer sur le volet Properties
et sélectionner la valeur False pour la propriété Use Dynamic
ports.
C'est terminé ! Il ne reste plus qu'à tester l'application de la même façon que
nous l'avons vu précédemment, i.e: CTRL + F5.
On pourra en savoir plus sur les services Web en allant sur le site des MSDN:
http://msdn.microsoft.com/webservices/webservices/

Tester un service Web
ASP.NET fournit une option très intéressante qui permet de tester un service Web
indépendamment de tout projet.
Pour tester le service Web que nous venons d'implanter, il suffit d'aller dans
Solution Explorer, de cliquer-droit sur le fichier CarteDeCredit.asmx
et de choisir l'option View in Browser.
Le lien Service Description pointe vers le WSDL du service Web.
La liste à bulles représente l'ensemble des méthodes testables du service Web. Cliquons
sur Valider pour obtenir l'écran suivant:
Entrons des informations valides: 123 pour NumeroCarte
et 1/2/2012 pour dateExp. En cliquant sur le bouton
Invoke, on obtient le message XML suivant:
On constate que cette réponse contient un élément correspondant au type
de la méthode Valider (bool). Cet élément est décrit par la valeur true
qui correspond bien au cas où le numéro et la date d'expiration de la carte sont
valides. Par exemple, en gardant la même date et en prenant 1234
pour le numéro, on obtient:
Dimanche 22 Janvier 2006
|