You are on page 1of 183

Facult des Sciences de Monastir Dpartement des Sciences de lInformatique

Notes de cours sur

La technologie .NET
Par : Karim Kalti

SOMMAIRE
Introduction la technologie .NET Le Langage C#.NET Les IHM en .NET Accs aux donnes (ADO.NET) Architectures des applications Web dynamiques ASP.NET Les services Web Les serveurs de mdia (audio et vido streaming) Dveloppement et dploiement d'applications Web multimdia.

V - 3.1

INTRODUCTION AU FRAMEWORK .NET


Qu'est ce que le FrameWork .NET :
D'aprs MicroSoft, le Framework .NET est une nouvelle plate-forme informatique qui simplifie le dveloppement d'applications dans l'environnement fortement distribu d'Internet. (Source MSDN) Principaux objectifs Le Framework .NET est conu pour remplir les objectifs suivants : (Source MSDN) Fournir un environnement cohrent de programmation oriente objet que le code objet soit stock et excut localement, excut localement mais distribu sur Internet ou excut distance. Fournir un environnement qui garantit l'excution scurise de code. Fournir aux programmeurs un environnement cohrent qui permet de dvelopper une grande varit de types d'applications comme les applications Windows, les services Windows, les applications embarques et les applications Web. Gnrer toutes les communications partir des normes d'industries pour s'assurer que le code bas sur le Framework .NET peut s'intgrer n'importe quel autre code. (forte utilisation du XML) L'architecture du FrameWork .NET Le Framework .NET possde une architecture compose de trois principales couches : La CLS qui est une spcification visant garantir l'interoprabilit des langages de programmation en .NET. La bibliothque de classes .NET (API.NET): qui permet de dvelopper des applications .NET La Common Language Runtime (CLR) : qui permet d'excuter les applications .NET

La Common Language Specification (CLS)


La Common Language Specification est une normalisation qui doit tre respect et implment par tout langage de programmation qui se veut capable de crer des applications .NET. Cette spcification s'intresse la normalisation d'un certain nombre de fonctionnalits comme par exemple la manire d'implmenter les types de donnes, les classes, les dlgus, la gestion des vnements, etc ... La CLS a pour objectif de garantir l'interoprabilit entre les langages .NET. En effet, deux langages conformes la CLS peuvent facilement changer des donnes entre eux (ils implmentent au bas niveau de la mme manire ces donnes). Il est possible par exemple de crer une classe dans un langage conforme la CLS qui hrite d'une autre classe dfinie dans un autre langage conforme la CLS.

Karim Kalti

La bibliothque de classes .NET


La bibliothque de classes .NET est une API compltement oriente objet qui offre la possibilit de dvelopper des applications allant des traditionnelles applications ligne de commande ou interface graphique utilisateur (GUI, Graphical User Interface) jusqu'aux applications qui exploitent les dernires innovations fournies par ASP.NET, comme les services Web XML et les Web Forms. La version 1.0 du .NET FrameWork comporte une bibliothque d'environ 9000 classes et 270000 mthodes. Ces classes et leurs mthodes couvrent presque tous les besoins du dveloppement d'applications (Accs aux donnes, programmation rseau, dveloppement d'interfaces graphiques, dveloppement Web, fonctions mathmatiques, manipulation des chanes, des dates ). Ces classes sont regroupes d'une manire thmatique et hirarchique en espaces de noms.

La bibliothque .NET : une API de programmation multi-langages


Langages classiques de programmation Les langages classiques : chaque langage possde sa syntaxe de base (liste de mots-cls plus les rgles d'criture) Un langage est toujours accompagn d'une bibliothque de fonctions. Ces fonctions enrichissement les possibilits du langage. Exemples : fonctions mathmatiques, fonctions de manipulation des chanes de caractres, fonctions graphiques, fonctions systmes, Langage pour programmer avec la bibliothque .NET La bibliothque .NET n'est pas spcifique un langage donn (indpendante des langages). Elle est supporte par plusieurs langages (environ 27 langages d'aprs Microsoft : VB, C++, C#, Java, Jscript, Delphi, Eiffel, Perl, Python, COBOL, ). Les trois langages les plus utilises pour dvelopper en .NET sont VB.NET, C#.NET, et C++.NET. Chaque langage qui supporte la bibliothque .NET (conforme la CLS) peut instancier les classes de cette bibliothque et utiliser ses mthodes.

Exemple : //// VB.NET //// Dim i as Integer i=5 Console.WriteLine(i) //// C++.NET //// int i; i=5; Console::WriteLine(i); //// C#.NET //// int i; i=5; Console.WriteLine(i); Cet exemple montre que chacun des trois langages utilise sa propre syntaxe pour la dclaration des variables, mais les trois font appel la mme mthode .NET pour faire l'affichage bien sr chacun avec ses propres rgles d'criture.

Karim Kalti

Organisation de la bibliothque de classes .NET

La bibliothque .NET est constitue de trois couches de classes offrant trois catgories de services : Premire couche : Base classes Library (BCL) La BCL rassemble des classes permettant d'effectuer les oprations de base telles que la manipulation de chanes de texte, la gestion des entres/sorties, des communications rseaux, des threads, etc.

Deuxime couche : les classes de donnes et XML La deuxime couche est compose de deux bibliothques de classes d'accs aux donnes : La bibliothque ADO.NET, s'levant sur les bases de l'ancien ADO (ActiveX Data Objects) et permettant l'accs sous format XML aux interfaces de bases de donnes SQL Server ODBC, OLEDB, ORACLE, et aux fichiers XML. Une bibliothque de classes permettant de manipuler les donnes XML. On y trouve par exemple les classes XSLT permettant la transformation d'un document XML vers n'importe quel type d'autre document.

Troisime couche : les services Web, les applications Web et les applications Windows La dernire couche, la plus leve, est utilise pour la cration des applications Web et des applications Windows et notamment la partie interface : Les applications Web peuvent se prsenter sous formes de pages Web dynamiques et statiques ou sous forme de services Web. La technologie utilise pour leur cration est l'ASP.NET. Elle utilise pour la ralisation des interfaces de nouveaux composants appels les WebForms. Les applications Windows et particulirement leurs interfaces sont cres l'aide des WinForms.

System.Web
Services Description Discovery Protocols Caching Configuration UI HtmlControls WebControls Form

System.Windows.Forms
Button ListControl MessageBox

System.Drawing
Security SessionState Drawing2D Imaging Printing Text

System.Data
OLEDB Design SQL SQLTypes XSLT XPath

System.Xml
Serialization

System
Collections Configuration Diagnostics Globalization IO Net Reflection Resources Security ServiceProcess Text Threading Runtime InteropServices Remoting Serialization

La bibliothque de classes .NET

Karim Kalti

Les classes de la bibliothque .NET sont organises sous forme d'espaces de noms hirarchiss. Chaque espace de noms peut comporter un ensemble de classes et/ou un ensemble de sous-espaces de noms. L'accs une classe s'effectue l'aide son nom complet. Ce nom complet se compose de la liste hirarchique des espaces de noms plus le nom de la classe en question. Ces noms tant relis entre eux par des points. Exemple : La classe DataSet qui se trouve dans l'espace de noms "System.Data.ADO" se dclare comme "System.Data.ADO.Dataset". La classe Console qui se trouve dans l'espace de noms "System" se dclare comme "System.Console".

Le MSIL
La compilation d'un programme crit en .NET conduit vers la cration d'un fichier excutable (fichier .exe). Cet excutable n'est pas crit en code machine comme les excutables classiques mais avec un langage intermdiaire appel MSIL acronyme de MicroSoft Intermediate Language. L'excution des fichiers compils en MSIL ne peut pas tre directement assure par les services du systme d'exploitation.

L'assemblage
L'assemblage est le fichier exe ou dll produit par la compilation d'un code .NET. Un assemblage contient trois types de donnes : o Le code MSIL qui rsulte de la compilation. o Les mta donnes. o Les ressources.

MSIL dans un assembly Un code .NET peut comporter plusieurs classes. Au moment de la compilation, toutes ces classes sont compiles en MSIL dans un mme assemblage. Les classes d'un mme assemblage doivent avoir un seul point d'entre (Une seule classe parmi celles d'un assemblage doit avoir une mthode qui joue le rle de fonction principale). Il est rappeler que le point d'entre est dfini par la mthode Main pour les applications de type console, par la mthode WinMain pour les applications Windows et par DllMain pour les dll (Dynamic Linked Library).

Karim Kalti

Les mta donnes Les donnes qui accompagnent le code MSIL dans un assemblage sont de deux catgories : Des donnes de description des types : les types sont les classes compiles dans l'assemblage. La description concerne alors les spcifications de ces classes (noms, attributs, mthodes, droits d'accs, interfaces implmentes, ). Ces informations sont gnralement utilises par les EDI pour la compltion de code. L'assembly manifest : Le manifeste contient des informations du genre : o Nom : le nom de l'assemblage. Il sert la rsolution de porte. Il est le mme que celui du fichier de l'assemblage moins l'extension. o Version : la version de l'assemblage. o Culture : permet d'indiquer le type de ressource utiliser en ce qui concerne la culture (langue, criture de droite gauche, type de calendrier ). o Autres assemblages : les assemblages ncessaires l'excution de l'assemblage courant. Ces assemblages sont gnralement des dlls. Les ressources Les ventuelles ressources utilises par l'assemblages : icnes, bitmap,

La Common Language Runtime (CLR)


La Common Language Runtime est un environnement qui assure l'excution des programmes .NET. Elle joue le rle de la machine virtuelle de Java mais pour les programmes crits en .NET. Elle interprte les fichiers excutables compils en MSIL. Elle fournit des services tels que : o La gestion de la mmoire ( travers le Garbage Collector GC). o La gestion des exceptions. o La gestion des threads. o L'interoprabilit entre plusieurs langages. o Le chargement dynamique des modules excuter. o La compilation vers un code machine natif du MSIL et le contrle de l'excution des programmes.

Un programme manag (Managed program) est un programme compil en MSIL, son excution est gre par la CLR. Un programme non manag est un programme compil en code natif. Son excution est directement prise en charge par les services du systme d'exploitation. VB.NET et C#.NET ne permettent de crer que des programmes manags. C++.NET permet de crer des programmes manags et non manags.

Karim Kalti

Avantages de la CLR
Scurit de l'excution des programmes. Grce la gestion des exceptions et la gestion automatique de la mmoire. Interoprabilit de programmes crits dans diffrents langages. Tous les langages qui supportent le .NET compilent vers un mme code intermdiaire Possibilit de faire communiquer des programmes crits dans des langages diffrents.

Portabilit des programmes Etapes de gnration d'un programme excutable : Fichier source (C#.NET) Compilation Fichier source (exemple C++) Compilation + Edition des liens
Excutable spcifique un systme d'exploitation donn et un p donn.

Fichier excutable MSIL

Fichier excutable en code natif (exe)

Interprtation

Interprtation

Interprtation

Excution

CLR Win 2K Excution OS Win 98

CLR Win XP Excution OS Win 2K

CLR Win 98 Excution OS Win XP

OS

Karim Kalti

Au moment de l'excution, la CLR assure entre autres la compilation Just In Time (JIT) du MSIL vers le code natif qui tient compte des services de la plateforme de destination. Il existe plusieurs versions de la CLR, chacune est spcifique une plateforme donne. Ce sont ces versions qui assurent la portabilit des excutables .NET (assemblies) Comparaison entre .net et Java :

.NET
Code source MS Intermediate Langage CLR

JAVA
Code source Bytecode Machine virtuelle (JVM)

La spcification .NET et l'implmentation .NET


.NET FrameWork en tant que spcification est une spcification publique (propose par MS). Il existe deux principales implmentations de cette spcification. o Implmentation propose par MS : destine aux plate-formes 2000,XP, 2003 server. o Projet Mono : implmentation destine tourner sous Linux (CLR pour Linux).

Outils ncessaires pour crire un programme .NET


Au minimum il faut avoir : Pour crire le code : un diteur de texte (exemple : le bloc notes) Pour compiler : le SDK tlchargeable gratuitement (site Microsoft). Le SDK est un Kit comprenant un ensemble d'outils ncessaires pour le dveloppement d'applications : compilateur, outils de dploiement etc. La compilation se fait dans ce cas en ligne de commande. Pour excuter : la CLR : tlchargeable gratuitement (site Microsoft).

Environnement de Dveloppement Intgr pour .NET

Qu'est ce qu'un environnement de Dveloppement Intgr (EDI) Un environnement de dveloppement intgr (EDI) est un outil qui facilite et acclre le dveloppement d'applications. Il intgre les modules ncessaires pour le dveloppement d'applications : o Editeur de code avec coloration syntaxique et compltion de code. o Lancement des processus de compilation et d'excution travers des menus sans passer en mode ligne de commande. o Outils de dboguage ... o Certains environnements de dveloppement intgrent des fonctionnalits de type RAD (Rapid Application Developpment). Ces fonctionnalits permettent de crer d'une manire visuelle une grande partie de l'application ( l'aide d'assistants WYSIWYG) et gnrent automatiquement le code correspondant.

EDI payant Visual Studio.NET (EDI + FrameWork).

EDI gratuit SharpDevelop : pour developper des applications windows et mobiles. (EDI seulement) WebMatrix : pour developper des applications Web. (EDI seulement) 7
Karim Kalti

Ordre d'installation des composants : CLR (si elle n'est pas installe par dfaut sur le systme). IIS. MDAC. .NET FrameWork. EDI.

Pour VisualStudio.NET : l'installation de ces diffrents composants se fait d'une manire automatique.

Karim Kalti

Les bases du langage C#

Caractristiques et nouveauts
C# : se prsente comme la suite des langages C et C++, trs proche de JAVA. Langage compltement orient objet pas de possibilit dcrire des fonctions en dehors des classes, pas de variables globales. Permet lcriture des programmes plus surs et plus stables grce la gestion automatique de la mmoire laide du ramasse miette (garbage collector) et la gestion des exceptions. Nouveauts par rapport au C++ : o Libration automatique des objets. o Disparition des pointeurs. (remplacs par des rfrences). o Disparition du passage d'argument par adresse au profit du passage par rfrence. o Nouvelles manipulations des tableaux. o Nouvelle manire d'crire les boucles. (foreach) o Disparition de l'hritage multiple mais possibilit d'implmenter plusieurs interfaces par une mme classe.

Premier programme
using System ; class Prog { static void Main() { Console.WriteLine(Bonjour); } }

Un programme C# comporte obligatoirement une fonction Main (M majuscule). Main doit tre obligatoirement membre dune classe. Le point virgule la fin de la dfinition dune classe est optionnel (pas en C++). Pou afficher le message bonjour on utilise la mthode WriteLine de la classe Console. La classe Console fait partie de lespace de noms (bibliothque) System. La mthode WriteLine peut tre appele de deux manires : o Spcification du nom complet : System.Console.WriteLine o Spcification du nom relatif

using System ; Console.WriteLine("Bonjour") ;

Les commentaires en C#
Trois types de commentaires peuvent tre utiliss en C# : // /* */ /// Le reste de la ligne est considr comme commentaire. (commentaire ligne) Tout ce qui se situe entre les deux dlimiteurs est considr comme commentaire. (commentaire multi-lignes) Le reste de la ligne est considr comme commentaire servant la documentation automatique du programme. (commentaire de documentation)

Karim Kalti

Les identificateurs en C#
Premier caractre : lettre (y compris celles accentues) ou le underscore _ Distinction entre minuscule et majuscule. Les caractres accentus sont accepts. Un mot rserv du C# peut tre utilis comme identificateur de variable condition quil soit prcd de @. NbLignes, Nbcoles, @int

Exemples didentificateurs :

Les instructions du C#
Une instruction se termine obligatoirement par un point virgule. Une suite d'instructions dlimites par des accolades constitue un bloc. Les blocs dfinissent les zones de validit des variables (porte des variables).

Mots rservs du C#
abstract as base bool break byte case catch char checked class const continue decimal default delegate do double else enum event explicit extern false finally fixed float for foreach goto if implicit in int interface internal is lock long namespace new null object operator out override params private protected public readonly ref return sbyte sealed short sizeof stackalloc static string struct switch this throw true try typeof uint ulong unchecked unsafe ushort using virtual volatile void while

Types de donnes
Les types du C# sont de deux catgories : les types "valeur" et les types "rfrence". Type "valeur" Une variable de type valeur est une variable auto au sens du C++. Elle est alloue sur la pile (stack). Sa dure de vie est gre par le systme (le runtime pour le C#). Type "rfrence" Une variable de type rfrence est une variable dynamique au sens du C++. Une telle variable rfrence un objet allou dans le tas manag. La variable elle mme est alloue sur la pile. La dure de vie de l'objet rfrenc par une telle variable est gre implicitement par le Garbage Collector. Les variables de type rfrence ne peuvent tre accdes que d'une manire indirecte ( travers la rfrence). Elles sont de ce fait moins rapides que les variables de type "valeur".

10

Karim Kalti

La tentative d'accs une rfrence invalide (non initialise par exemple) engendre la leve d'une exception au moment de l'excution. Comparaison de valeurs et comparaison de rfrences Une variable de type "rfrence" contient une rfrence des donnes stockes dans un objet. Deux variables de types rfrences peuvent donc rfrencer les mmes donnes. Dans ce cas, la modification de ces donnes travers l'une de ces deux rfrences affecte automatiquement l'autre rfrence. Une variable de type "valeur" possde sa propre copie des donnes qu'elle stocke. Deux variables de type "valeur" peuvent avoir les mmes donnes mais chacune possde sa propre copie distincte. Dans ce cas la modification de l'une des deux variables n'affecte pas l'autre. Types C# et types .NET Il existe pour la majorit des types natifs du C# des types correspondants en .NET. La majorit des types natifs du C# sont de type "valeur". Les types .NET quant eux, sont dfinis sous forme de classes et sont de ce fait de type "rfrence". (une classe dfinit toujurs un type rfrence en C#) Les types du C# ainsi que leurs types correspondants en .NET sont prsents dans les deux tableaux suivants : Type "valeur" en C# bool byte sbyte char decimal double float int uint long ulong short ushort Type .NET Framework System.Boolean System.Byte System.SByte System.Char System.Decimal System.Double System.Single System.Int32 System.UInt32 System.Int64 System.UInt64 System.Int16 System.UInt16 Type .NET Framework System.Object System.String

Type rfrence en C#
object string

En C/C++ une valeur nulle est value false et une valeur 0 est value true, ce nest plus le cas en C#, true est true et false est false. Le type decimal est utilis pour les oprations financires. Il permet une trs grande prcision mais les oprations avec ce type sont deux fois plus lentes que les types double ou float.

Les variables
Dclaration Type NomVariable; Toute variable doit tre dclare dans un bloc. Elle cesse dexister en dehors de ce bloc, (pas de variable globale). Toute variable de type scalaire natif doit avoir obligatoirement une valeur (le compilateur signale une erreur sinon). En l'absence d'une initialisation explicite les champs d'un objet sont implicitement initialiss par le compilateur (numrique 0 et chane ""). Ce n'est pas le cas pour les variables de type scalaire.

Les constantes en C#
Constante entire : int i = 10 ; Constante de type long (Ajout du suffixe L) : long Constante relle : double k = 20.5; Constante relle simple (ajout du suffixe f) : float

j = 10L ; v = 20.5f;

11

Karim Kalti

Constante relle grande prcision (ajout du suffixe M ou m) : decimal d=1.56M ou Constante caractre (entre deux simples quotes) : char c=A; Constante chane de caractres (entre deux doubles quotes) : string s="bonjour";

1.56m;

Les constantes symboliques en C#


La dclaration des constantes symboliques se fait avec le mot-cl const. Une constante symbolique doit tre obligatoirement initialise. Exemple :
const int n=3 ;

Les tableaux
Les tableaux en C# sont des types "rfrence". Dclaration et allocation Type[] Tab ; // Tab est une rfrence un tableau. Tab = new Type[Taille] ; // Allocation de lespace mmoire du tableau. Lespace mmoire du tableau est allou sur le tas (heap). Exemple :
int [] T ; // Dclaration d'une rfrence un tableau d'entiers. T=new int [3] ; // Cration effective du tableau ou galement : int [] T = new int [3] ;

Initialisation
float[] TF= {2.5f ,0.3f,5.9f} ; ou float[] TF= new float[]{2.5f ,0.3f,5.9f} ; string[] TS={ALI,Salah, Imed};

Les cellules d'un tableau non explicitement initialis sont automatiquement mises 0. Exemple :
int[] TI = new int [3];

// Les cellules de TI sont automatiquement initialises 0

Libration dun tableau La libration dun tableau se fait automatiquement par le ramasse-miettes. Un tableau cesse dexister : o Lorsquon quitte le bloc dans lequel il est dclar. o Lorsquon assigne une nouvelle zone (nouvelle valeur y compris null) la rfrence qui dsigne le tableau. Exemple :
int[] T={10,5,23} ; // dclaration et initialisation , allocation implicite sans new. ... T=new int[]{100,50,65,80} ou galement T=null ; // rallocation automatique de

lespace allou au tableau.

La zone mmoire rserve aux 3 entiers prcdents est libre par le ramasse-miettes. Accs aux cellules dun tableau Syntaxe : Tab[indice] Pour un tableau de n lments, le premier lment a pour indice 0 et le dernier a pour indice n-1. Contrairement C/C++, il nest pas possible daccder un tableau en dehors de ses bornes. Ceci est signal comme une erreur. (leve d'exception)

12

Karim Kalti

Tableau plusieurs dimensions Exemple : Tableau deux dimensions Dclaration : Type[ , ] T = new Type[2,3] ; // 2 lignes et 3 colonnes Initialisation : Type[ , ] T = {{Val1, Val2, Val3},{ Val4, Val5, Val6}}; Accs : T[i,j] Exemple : Tableau 3 dimensions
Type[ , , ] T = new Type[Dim1, Dim2, Dim3]; T[i,j,k] = Valeur ;

Copie de tableaux Exemple 1: Copie de rfrences


int [] T1 = {1,2,3} ; int [] T2 ; // T2 contient la valeur "null". T2=T1 ; // T1 et T2 font rfrence au mme tableau. Si on fait T1[0]=100 ; alors Console.WriteLine(T2[0]) affichera

100 ;

Exemple 2: Copie de rfrences


int [] T1 = {1,2,3} ; int [] T2= new int[100] ; T2=T1;

T2 fait rfrence la zone mmoire contenant le tableau de trois lments. La zone mmoire contenant les 100 cellules est signale " librer". Le ramasse-miettes (Garbage Collector) la librera lorsque un besoin en mmoire se manifestera. Pour faire rellement une copie de tableaux il faut procder comme suit : Utilisation de la mthode CopyTo
int [] T1 = {1,2,3} ; int [] T2= new int[100] ; T2= new int[T1.Lenght] ; // lespace de T1.CopyTo(T2,0) ; // fait la copie partir

100 lments est signal librer . de la cellule 0 ;

Utilisation de la mthode Clone Exemple 1


int [] T1 = {1,2,3} ; int [] T2; T2 = (int[])T1.Clone() ; T[1]=100 ;

Alors le contenu de T1 est : 100,2,3 et le contenu de T2 est : 1,2,3 Exemple 2


int [ , ] T1= {{1,2,3},{10,20,30}} ; int [ , ] T2 ; T2 = (int[ , ]) T1.Clone() ;

Tableaux avec des cellules de types diffrents Il est possible de crer des tableaux ayant des cellules de types diffrents. Le type de base de ces tableaux doit tre le type object. Une cellule de type object peut recevoir une valeur de n'importe quel type. Exemple :
object[] T = new object[3] ; T[0] = 12 ; T[1] = 1.2 ; T[2]= "Bonjour";

Tableaux dchiquets Un tableau dchiquet est un tableau qui possde des composantes de dimensions irrgulires. Par exemple, pour les tableaux deux dimensions on parle de tableau dchiquet si chaque ligne possde un nombre diffrent de colonnes.

13

Karim Kalti

Exemple :
int[][] T ; T= new int[2][] ; T[0] = new int[3] ; T[0][0] =1 ; T[0][1]=2 ; T[0][2]=3 ; T[1] = new int[]{10,20,30,40} ;

Les tableaux dchiquets ne sont pas compatibles avec le .NET (ne sont pas CLS compliant). Ils sont plutt spcifiques au C#.

Oprations de saisie et daffichage en mode console


Affichage en mode console L'affichage en mode console se fait essentiellement l'aide des mthodes Write et WriteLine de la classe Console. La mthode Write affiche une chane de caractres. La mthode WriteLine affiche une chane puis effectue un retour la ligne. Exemples
Console.WriteLine("bon"); Console.WriteLine("jour"); Console.Write("Bon"); Console.WriteLine("jour"); int k =10,i=5,j=6; Console.WriteLine(k); Console.WriteLine("k vaut :" + k); Console.WriteLine("i="+i+"j="+j); Console.WriteLine("i={0} et j = {1}",i,j); Console.WriteLine(i+j); Console.WriteLine("Somme ="+i+j); Console.WriteLine("Somme =" +(i+j)); Console.WriteLine("Somme ={0}",i+j);

Saisie en mode console La saisie en mode console se fait essentiellement l'aide des mthodes Read et ReadLine de la classe Console. La mthode Read() lit un caractre partir du flux standard dentre. La mthode ReadLine() lit une chane partir du flux standard dentre. La valeur retourne est "null" si aucune donne na t saisie (lutilisateur tape directement ENTREE). ReadLine ne peut retourner que des chanes de caractres. Il faut par la suite faire les conversions explicites vers les types de destinations. Ces conversions se font laide de la mthode Parse membre des classes reprsentant les types de base. Exemple :
// Lecture dun entier string s = Console.ReadLine(); int i = Int32.Parse(s); // Lecture dun rel string s = Console.ReadLine(); double d = Double.Parse(s);

Les oprateurs
Oprateurs arithmtiques : + - / % * Pr-Post Incrmentation : ++, -Oprateurs logiques : <, <=, >, >=, = =, !=, !,&&, ||. Autres oprateurs : +=, -=, *=

Structures de contrle
Similarits par rapport au C++ if.. else : (identique qu'en C++)

14

Karim Kalti

switch : globalement, la mme syntaxe qu'en C++. Il existe toutefois deux diffrences : o La valeur tester peut tre, en plus des types entiers, de type string. o Il y a une diffrence au niveau du passage dun "case" un autre en cas dabsence de "break". for, while et do..while : (identique qu'en C++) Les instructions break, continue et goto : (identique qu'en C++) Diffrences par rapport au C++ Essentiellement au niveau de lvaluation des expressions :
C++ : if(i) C# : if(i!=0) C++ : if(!i) C# : if(i==0)

Nouvelle boucle : foreach Permet de parcourir les tableaux et les collections. Syntaxe :
Type[] Tab = new Type [Taille] ; foreach (Type Var in Tab) Bloc dinstructions

Remarque : Cette boucle ne peut tre utilise que pour lire les valeurs des lments d'un tableau. Elle ne permet pas d'effectuer des modifications du contenu d'un tableau. Exemple :
int [] TI = new int[]{15,30,45,60} ; foreach (int i in TI) Console.WriteLine(i); string[] TS={ "ALI", "SALAH","KAMEL"}; foreach(string s in TS) Console.WriteLine(s);

Les fonctions
Dclaration : Syntaxe : Globalement comme en C++. Pas de fichiers denttes contenant les dclarations des fonctions. Passage de paramtres : Pas de passage par adresse. Passage par valeur : comme en C++. Passage par rfrence : il existe une diffrence syntaxique par rapport au C++. Les tableaux et les objets sont toujours passs par rfrence. Les paramtres possdant les autres types (int, float, string, , struct) peuvent tre passs par valeur ou par rfrence.

Passage par valeur


using System ; class Prog { // Fonction prenant comme paramtres deux entiers et retournant un entier static int Somme(int a, int b) {return a+b;} // Fonction prenant comme paramtre un tableau et ne retournant aucune valeur static void AfficherTab(int[] T) { foreach (int i in T) { Console.Write(i+" "); } } // Fonction retournant un tableau static int[] CrerTableau() { int[] T= new int[]{1,2,3}; return T;

15

Karim Kalti

} static void Main( ) {int a = 3; int b = 7; Console.WriteLine("Somme de a et b:"+Somme(a,b)); Console.WriteLine("Contenu du tableau"); AfficherTab(CrerTableau()); } }

Passage par rfrence Il remplace le passage par adresse du C++. Si le paramtre passer la fonction est de type "valeur" alors le passage de sa rfrence se fait l'aide du mot-cl ref comme suit : Dclaration : void f(ref Appel : f(ref Param) ; Exemple :
using System; class Prog { static void Permuter(ref int x, ref int y) { int temp; temp = x; x=y; y=temp; } static void AfficherValeurs(int a, int b) { Console.WriteLine("a :"+a); Console.WriteLine("b :"+b); } static void Main() { int a =5; int b =6; Permuter(ref a, ref b); AfficherValeurs(a,b); } } Type Param) ;

Une variable ayant un type rfrence (Exemple : tableau, objet d'une classe, ) passe par dfaut par rfrence lorsqu'elle est transmise comme paramtre une fonction. Le mot-cl ref n'est pas utilis dans ce cas. Passage darguments non initialiss Un argument pass l'aide du mot-cl ref doit tre obligatoirement initialis. En d'autres mots, il doit avoir ncessairement une valeur au moment de sa transmission la fonction lors de l'appel de cette dernire. Toutefois, plusieurs situations en programmation ncessitent l'utilisation d'arguments sans valeurs initiales. C'est le cas par exemple des fonctions qui ont besoin de retourner plusieurs valeurs. Ces valeurs ne peuvent pas tre renvoyes toutes par return. Elles peuvent plutt tre places dans des arguments qui sont passes par rfrence la fonction. Le passage d'arguments non initialises ne peut pas se faire avec ref. Il est fait plutt avec le mot-cl out. Un argument de type out est un paramtre qui passe par rfrence sans ncessiter toutefois d'tre initialis au moment de sa transmission. Un argument de type out est initialis par la fonction appele. Syntaxe : Dclaration : Type Fct(out TypeParam NomParam) Appel : Fct(out NomArgument) Exemple 1:
using System; class Prog { static void CalculerTriple(int x, out int triple) { triple = 3*x;} static void Main() { int x = 5;

16

Karim Kalti

int t; CalculerTriple(x,out t); Console.WrilteLine("le triple est : " + t); } }

Le paramtre triple n'a pas de valeur au moment de l'appel de la mthode CalculerTriple. Il prend sa valeur l'intrieur de cette dernire. C'est pourquoi il est pass l'aide de out. Exemple 2: Saisie d'un tableau
using System; class Prog { static void Saisie(out int[] Tab) { Tab = new int[3]; Tab[0]=21; Tab[1]=85; Tab[2]=5; }

static void Main() { int[] Tab; Saisie(out Tab); .... .... } }

Remarques : Une proprit de classe ne peut pas tre passe comme un argument de type ref ou de type out. La surcharge de mthodes est possible si les signatures de deux mthodes diffrent seulement par un ref ou seulement par un out. La surcharge n'est pas valide pour deux mthodes dont les signatures diffrent par ref et par out. Exemples: // Exemple de surcharge correcte car les deux signatures diffrent seulement par out
void f(int i){ } void f(out int i){ }

// Exemple de surcharge incorrecte car les deux signatures ne peuvent pas se distinguer par ref et out.
void g(ref int i){ } void g(out int i){ }

Les structures
Les structures constituent un moyen de construction de types personnaliss. Une structure permet de regrouper plusieurs champs dans une mme entit. Une structure est toujours de type valeur. Dclaration struct NomStructure { ModificateurAcces type1 champ1; ModificateurAcces type2 champ2; ModificateurAcces type3 champ3; } ModificateurAcces dsigne le modificateur de droit d'accs (public, private, internal). L'utilisation d'un point virgule la fin de la dclaration d'une structure est optionnelle. Exemple :
struct Pers { public string Nom; public int Age; }

17

Karim Kalti

Dclaration d'une variable de type structure Syntaxe : NomStructure NomVar; NomVar est une variable de type valeur. Exemple :
Pers P;

Accs aux champs Lorsqu'un champ d'une structure est publique alors il peut tre accd comme suit : NomVar.Champ; Exemple :
P.Nom = "Toto"; P.Age = 20;

Constructeur d'une structure Une structure peut avoir 0, un ou plusieurs constructeurs. Une structure ne peut pas avoir un constructeur par dfaut explicitement dfini. Le seul constructeur par dfaut accept est celui implicite. Ce dernier est automatiquement gnr mme si la structure comporte des constructeurs paramtrs explicitement dfinis. Le constructeur par dfaut d'une structure initialise automatiquement les champs numrique 0 et les champs de type chanes "". Un constructeur paramtr d'une structure doit obligatoirement initialiser tous les champs de la structure. (une initialisation partielle engendre une erreur). Exemple 1 :
struct Pers { public string Nom; public int Age; Pers(){Nom = Toto;Age=20;} // Erreur }

Exemple 2 :
struct Pers { public string Nom; public int Age; Pers(string N){Nom = N;} // Erreur }

Une structure ne peut pas hriter d'une classe ou d'une structure. Les variables structures peuvent galement tre dclares l'aide de new comme suit : Syntaxe : NomStructure NomVar = new NomStructure(); Exemple :
Pers P = new Pers();

Mais mme avec cette syntaxe, P reste une variable de type valeur. Cette syntaxe permet tout simplement d'appeler explicitement les constructeurs paramtrs chose qui n'est pas possible avec la premire criture.

Mthodes d'une structure Une structure peut avoir des mthodes. Ces dernires sont dclares l'intrieure de la structure.

Exemple :
using System; struct Pers { public string Nom; public int Age; public Pers(string N, int A){ Nom=N; Age=A;} public void Afficher() { Console.WriteLine("Nom :"+Nom+" Age : "+Age);} } class Prog { static void Main() { Pers P = new Pers("Ali",20); P.Afficher(); }

18

Karim Kalti

Remarque : En C#, tous les types de donnes scalaires tels que int, float, double, sont implments sous forme de structures intgres. Exemple :
int int int int i = 5; j = new int(5); // initialisation de j 5. k = new int(); // initialisation automatique de k zro. L; // L n'est pas initialis.

Les numrations
Une numration est un outil permettant de construire un type ayant un ensemble fini de valeurs. Une numration dfinit toujours un type valeur. Dclaration : enum NomEnumeration {Valeur1, Valeur2, , ValeurN};

Les valeurs d'une numration sont codes comme des entiers de type int. Dans ce cadre Valeur1 vaut par dfaut 0, Valeur2 vaut 1 et ainsi de suite. Il est possible d'attribuer d'une manire explicite d'autres constantes entires aux valeurs d'une numration comme suit : enum NomEnumeration {Valeur1=20, Valeur2=65, , ValeurN}; Accs aux valeurs d'une numration Syntaxe : NomEnumration.Valeur Dclaration d'une variable de type numration Syntaxe : NomEnumration Var; Affectation de valeur Syntaxe : Var = NomEnumration.Valeur; Une variable numration est toujours de type "valeur". Exemple :
using System; enum Couleur {Rouge, Orang, Vert}; class Prog { static void Message(Couleur Feu) { switch (Feu) { case Couleur.Vert : Console.WriteLine("Vous pouvez passer"); break; case Couleur.Orang : Console.WriteLine("Prparez vous vous arrter"); break; case Couleur.Rouge : Console.WriteLine("Arrtez immdiatement"); break; } } static void Main() { Couleur Feu; Feu = Couleur.Vert; Message(Feu); } }

19

Karim Kalti

La conversion de donnes
Conversion implicite Certaines conversions sont effectues implicitement par le compilateur car de par leur sens et les types qu'elles font intervenir elles ne peuvent jamais engendrer des erreurs ou des pertes de donnes. Exemple:
int a=5; long b=a;

Conversion explicite Certaines conversions peuvent ne pas tre sres. Il incombe alors au programmeur de les faire explicitement s'il en a besoin. Ces conversions ne mnent pas toujours vers un rsultat correct. Syntaxe : Type1 Var1; Type2 Var2 = (Type2) Var1; Exemple :
long a=5; int b= (int)a;

Si a est dans la plage de valeur du type int alors la conversion est accepte. En cas de dpassement de capacit, la conversion sera refuse et une exception de type System.OverflowException sera leve. Conversion entre types "rfrence" Pour les objets la conversion n'est dfinie qu'entre un objet parent et un objet enfant. Elle se fait : D'une manire implicite d'un objet enfant vers un objet parent. Elle doit tre effectue d'une manire explicite dans le sens contraire (parent-enfant). Aucune vrification n'est effectue au moment de la compilation. Si une perte de donnes peut tre cause alors la conversion est annule et une exception de type System.InvalidCastException est leve. Syntaxe : TypeParent Var1; TypeEnfant Var2 = (TypeEnfant) Var1;

Le boxing et le unboxing
Le boxing Le boxing consiste convertir une variable de type "valeur" en une rfrence de type System.Object. Le boxing peut se faire d'une manire implicite ou explicite: Syntaxe : TypeValeur Var; Object box = Var; // Boxing implicite Object box = (Object) Var; // Boxing explicite Exemple1 :
int i =123; Object box =(object)i; // boxing explicite

Ou galement d'une manire implicite


Object box = i;

Exemple 2 : Un des prototypes de WriteLine est le suivant : void WriteLine(Object); L'appel suivant de cette mthode est rendu possible grce au boxing implicite :
int n=5; Console.WriteLine(n); // boxing de int dans object

20

Karim Kalti

Le unboxing Le unboxing est l'opration inverse du boxing. Il consiste convertir une rfrence de type System.Object vers une variable de type "valeur". Le unboxing ne peut se faire que d'une manire explicite. Syntaxe :
Object box; TypeValeur Var = (TypeValeur) box; // La conversion n'est pas toujours possible

Exemple :
i = (int) box;

Remarque : Le compilateur C# assure des oprations de boxing et de unboxing implicites entre les types "valeur" intgrs (natifs) et les classes qui leur correspondent en .NET. Ainsi par exemple : Une mthode qui prend comme paramtre formel Int32 peut accepter un paramtre effectif de type int (boxing implicite). Une mthode qui prend un paramtre formel de type int peut accepter un paramtre effectif de type Int32 (unboxing implicite).

21

Karim Kalti

Quelques classes usuelles du FrameWork.NET


La classe String
Cette classe permet de stocker et de grer les chanes de caractres. Caractristique d'une chane. Chaque caractre est cod sur deux octets. La gestion de la fin de la chane est une affaire interne (transparente % l'utilisateur, pas de zro de fin de chane). Constante chane de caractres Une constante chane de caractres se prsente comme une suite de caractres place entre deux double-quotes. Exemple : "abcd". Oprateurs et chanes de caractres La majorit des oprateurs (=, ==, !=) ont t redfinis pour travailler avec les chanes la manire des types "valeur" malgr que string soit un type "rfrence". Copie de chanes L'oprateur = effectue une copie du contenu des chanes et non une copie de rfrences. Exemple :
string s1 ="ABC"; string s2; s2=s1; s1="XYZ"; // s2 contient ABC alors que S1 contient XYZ.

Comparaison de chanes L'oprateur == effectue une comparaison des contenus des chanes et non une comparaison de rfrences

Exemple :
string s1="Bonjour", s2="Hello"; if(s1==s2)... if(s1==bonjour)

Extraction d'un caractre L'oprateur [] permet d'extraire un caractre de la chane mais il n'agit qu'en lecture : Exemple :
string s= "bonjour"; char c=S[0]; // C contient 'B' s[0] = 'X'; // erreur de syntaxe

Concatnation de chanes Les oprateurs + et += permettent de faire des concatnations de chanes Exemple :
string s, s1 = "Bon", s2 ="jour"; s = s1+s2; s+=" Monsieur"; // Bonjour monsieur

22

Karim Kalti

Exemples de mthodes de la classe String Mthode


int IndexOf(char c)

int IndexOf(char c, int pos) int IndexOf(string s) int IndexOf(string s,int Pos) String Insert(int pos, string s) String ToUpper() String ToLower()

Signification Renvoie la position du caractre c dans la chane qui porte l'opration.( 0 pour la premire position et 1si c n'a pas t trouv) Mme chose que la version prcdente sauf que la recherche commence partir de la position pos. Recherche la position de la chane s. Recherche la chane s partir de la position pos. Insre la chane s dans la chane appelante et ce partir de la position pos. Convertit la chane en majuscule. Convertit la chane en minuscule.

Classe Array
Cette classe reprsente les tableaux en .NET. Tout tableau cr avec la syntaxe du C# se comporte comme un objet de type Array. Quelques Proprits Length : Nombre total d'lments, toutes dimensions confondues. Rank : Nombre de dimensions. Exemple :
int[] t1 = {1,2,3}; // Length = 3 rank = 1 int [ , ] t2 = {{1,2,3},{10,20,30}}; // Length = 6 rank = 2 int [][] t3 = new int[2][]; // Length = 2 Rank = 1 t3[0]= new int[]{1,2,3}; t3[1] = new int[]{10,20,30,40}; // t3.Length vaut 2, t3[0].Length vaut 3, t3[1].Length vaut 4

Quelques mthodes Mthode


void copyTo(Array t, int pos)

int IndexOf(Array t, object o)

Signification Copie tout le tableau sur lequel porte l'opration dans le tableau pass en argument partir de la position pos. (Il existe d'autres surdfinitions de cette mthode). Mthode statique qui renvoie l'indice de la premire occurrence du second argument dans le tableau t ou 1 si o n'a pas t trouv. (Il existe d'autres surdfinitions de cette mthode).
string[] ts={"Ali", "salah", "salem", "mehdi"}; n = Array.IndexOf("Salah"); // n=1

Mthode statique qui inverse la squence d'lments dans le tableau


void reverse(array) void Sort(array) int [] ts ={10,20,30}; Array.reverse(ts); // 30 , 20 , 10

int Binarysearch(Array, Objet)

Mthode statique qui trie un tableau une dimension Mthode statique qui recherche un objet dans un tableau. Elle renvoie l'emplacement de l'objet dans le tableau ou une valeur ngative si l'objet n'a pas t trouv. Le tableau doit tre tri car c'est la technique de recherche dichotomique qui est utilise. Renvoie le nombre d'lments suivant une dimension spcifique.
int[ , ] M = new int[3,6]; for(int i = 0;i<M.GetLength(0);i++){ for(int j = 0;j<M.GetLength(0);j++){ M[i][j] = i+j; }}

int GetLength(int Dimension)

23

Karim Kalti

Autres classes intressantes

La classe Math Elle renferme toutes les fonctions mathmatiques. Exemple : fonction de calcul de la valeur absolue
int i; i = Int32.Parse(Console.ReadLine()); Console.WriteLine("Valeur absolue de i :"+ Math.Abs(i));

Il existe galement d'autres classes qui peuvent s'avrer utiles comme : La classe ArrayList : pour la gestion des tableaux dynamiques. La classe DateTime : pour la gestion de la date et l'heure. Etc

24

Karim Kalti

Proprits et Indexeurs
Les proprits
Une proprit est un champ public particulier, qui est gnralement associ un champ priv de la classe et qui permet de dfinir les droits d'accs en lecture et en criture ce champ priv. La dfinition de ces droits d'accs est faite travers deux mthodes spciales associes la proprit. Ces mthodes, appeles accesseurs, sont les mthodes get et set. Accesseur get Cette mthode rend la proprit accessible en lecture. Elle retourne la valeur du champ auquel est associe la proprit. La mthode get est automatiquement excute lors de la lecture de la proprit. Accesseur set Cette mthode rend la proprit accessible en criture. Elle affecte une valeur au champ associ la proprit. La mthode set est automatiquement excute lors de l'affectation d'une valeur la proprit.

get

private type champ

public type proprit set

Syntaxe :
public type proprit{ get{return champ ;} set{champ = value;} }

value est un mot-cl du C# qui contient la valeur affecte la proprit. Exemple :


int public prop1{ get{return champ ;} set{champ = value; } }

Remarque : Si laccesseur get est absent alors la proprit est en criture seule. Si laccesseur set est absent alors la proprit est en lecture seule. Exemple :
..... private int champ; public int prop1{ get {return champ*10;} set {champ = value + 5 ;} } ..... prop1 = 14 ; // Champ contient alors 19 int X = prop1; // X vaut 190

Outre la protection des champs, les accesseurs servent galement automatiser les oprations usuelles appliques aux champs. L'exemple suivant illustre ceci.

25

Karim Kalti

Exemple :
using System ; namespace ProjProp { class clA { private double prixTTC ; private double Taxe = 1.12; public double prix { get {return Math.Round(PrixTTC);} set {PrixTTC = value*Taxe;} } } class Class { static void Main(){ clA Obj = new clA(); double val = 55; System.Console.WriteLine("Valeur entre:"+val); Obj.prix = val ; System.Console.WriteLine ("Valeur stocke:"+PrixTTC); val = Obj.prix ; System.Console.WriteLine ("valeur arrondie:"+val) ; System.Console.ReadLine ( ); } } }

Proprits de classes et proprits dobjets Comme c'est le cas pour les champs classiques, il est possible de dclarer des proprits de classe et des proprits d'instance. Une proprit de classe est dclare l'aide du mot-cl static. Une proprit statique ne peut tre associe qu' un champ statique. Exemple de proprit de classe:
using System ; namespace ProjProp { class Class { static private double PrixTTC ; static private double Taxe = 1.12 ; static public double prix { get {return Math.Round(PrixTTC);} set {PrixTTC = value * Taxe;} } static void Main(){ double val = 55 ; System.Console.WriteLine("Valeur entre:"+val ); prix = val ; System.Console.WriteLine ("Valeur stocke:"+PrixTTC); val = prix ; System.Console.WriteLine ("valeur arrondie:"+val) ; System.Console.ReadLine(); } } }

Masquage de proprits Il est possible de masquer une proprit par une autre la manire des mthodes et ce l'aide du mot rserv new. Exemple :
using System; class clA { private double PrixTTC ; private double Taxe = 1.12 ; public double prix { // proprit de la classe mre get { return Math.Round(PrixTTC);} set { PrixTTC = value * Taxe;} } }

26

Karim Kalti

class clB : clA { private double prixLocal ; public new double prix { // masquage de la proprit de la classe mre get {return Math.Round(prixLocal);} set { prixLocal = value * 1.05 ; } } } class Class { static void Main(){ clA Obj = new clA(); double val = 55 ; System.Console.WriteLine("Valeur entre obj1:"+val); Obj.prix = val ; val = Obj.prix ; System .Console.WriteLine ("valeur arrondie obj1:"+val); System .Console.WriteLine ("--------------------"); clB Obj2 = new clB ( ); val = 55 ; System .Console.WriteLine ("Valeur entre Obj2:"+val ); Obj2.prix = val ; val = Obj2.prix ; System .Console.WriteLine ("valeur arrondie Obj2:"+val ) ; } }

Remarque : Les proprits peuvent galement tre virtuelles et redfinies dans les classes drives.

Les indexeurs
Les indexeurs constituent un moyen permettant d'accder aux objets la manire des tableaux. Un indexeur est dclar avec le mot-cl this. Il possde deux mthodes get et set comme les proprits. Exemple 1 : Dfinition d'un indexeur
class clA { private int[] champ; public clA(){champ = new int [5]}; public int this [int index]{ get { return champ[ index ] ; } set { champ[ index ] = value ; } }

Exemple 2 : Utilisation d'un indexeur


clA Obj = new clA( ); for (int i =0; i<5; i++ ) Obj[i] = i*10 ; int x = Obj[ 2 ] ; // x = 20 int y = Obj[ 3 ] ; // y = 30 ...

Remarque : Lindex utilis par l'indexeur peut tre de nimporte quel type. Plusieurs indexeurs peuvent tre dfinies pour une mme classe. Ils doivent se distinguer obligatoirement par leurs signatures. Exemple :
using System; class Pre { string[] Enfants; public void SesEnfants(string[] E) { Enfants = new string[E.Length]; for(int i=0;i<Enfants.Length;i++) Enfants[i]=E[i]; }

27

Karim Kalti

public string this[int n] { get{ return Enfants[n];} set{ Enfants[n] = value;} } public int this[string Nom] { get{ for(int i=0;i<Enfants.Length;i++) if(Enfants[i]==Nom) return i; return -1; } } } class Prog { public static void Main() { Pre Ammar = new Pre(); String[] Noms = {"Salah","Ali","Mehdi"} Ammar.SesEnfants(Noms); Console.WriteLine(Ammar[1]); Console.WriteLine(Ammar["Salah"]); Ammar[0]="Salem"; Console.WriteLine(Ammar[0]); } }

28

Karim Kalti

Dlgus et vnements

Rappel C/C++
En C/C++, le nom d'une fonction, utilis seul, dsigne ladresse en mmoire o sont stockes les instructions de cette fonction. De ce fait, il est possible de dclarer des pointeurs sur les fonctions et d'initialiser ces pointeurs. La dclaration d'un pointeur sur une fonction se fait comme suit : Type (*pf)(arg1, , argn) Exemple :
int (*pf)(int i double j)

pf est un pointeur qui peut pointer sur toute fonction qui prend comme paramtres un entier et un double et qui retourne un entier. Soit la fonction : int f (int K, double L) ; Si on initialise pf avec f : pf = f Alors lappel de f peut tre fait travers pf : int i = f(5,7.8) est quivalent int i = (*pf)(5,7.8)

La notion de dlgu
En C#, les pointeurs sur les fonctions sont implments l'aide des dlgus. Un dlgu est un objet particulier qui peut rfrencer (pointer vers) une ou plusieurs mthodes. Comme les pointeurs sur les fonctions, un dlgu doit tre dfini pour un prototype donn de mthodes. Il peut par la suite rfrencer nimporte quelle mthode ayant ce prototype. La mthode rfrence peut changer en cours de lexcution du programme. Lappel de la mthode peut se faire dans ce cas travers le dlgu. Dclaration dun type dlgu Pour pouvoir dclarer un dlgu, il faut dfinir auparavant le modle (prototype) des mthodes qui peuvent tre rfrences par ce dlgu. Ce modle de mthodes dfinit ce que l'on appelle un type dlgu. La dfinition d'un type dlgu se fait l'aide du mot-cl delegate comme suit : delegate TypeRetour TypeDlqu(type1 arg1,..., typeN argN) Instanciation dun objet de type dlgu Une fois le type dlgu dfini, il devient possible de crer des dlgus de ce type. Cette cration se fait comme suit : Typedlgu Deleg = new Typedlgu(NomMthode) Deleg est un dlgu qui peut rfrencer des mthodes ayant le prototype donn dans la dclaration de TypeDlgu. NomMthode dsigne ici le nom de la mthode qui sera rfrence par Deleg. Lappel de la mthode NomMthode peut se faire travers Deleg.

Exemple:
delegate string Dlgu(int x); class ClasseA { static string Fonc1(int x) { return (x*10).ToString(); }

29

Karim Kalti

static string Fonc2(int x) {return (x*100).ToString();} static void Main(){ string s = Fonc1(50); // appel de fonction classique System.Console.WriteLine("Fonc1(50) = " + s ); s = Fonc2(50); // appel de fonction classique System.Console.WriteLine("Fonc2(50) = " + s ); System.Console.WriteLine ("dlgu rfrence Fonc1 :"); Dlgu FoncDeleg = new Dlgu (Fonc1) ; s = FoncDeleg(50); // appel au dlgu qui appelle la fonction System.Console.WriteLine ("FoncDeleg(50) = " + s ); System.Console.WriteLine ("dlgu rfrence maintenant Fonc2 :"); FoncDeleg = new Dlgu ( Fonc2 ) ; // on change d'objet rfrenc (de fonction) s = FoncDeleg ( 50 ); // appel au dlgu qui appelle la fonction System.Console.WriteLine ("FoncDeleg(50) = "+s); System.Console.ReadLine ( ); } }

Remarque : Il est noter quil est tout fait possible de crer un dlgu faisant rfrence une mthode dinstance. Cette cration se fait comme suit : 1- Dclarer une classe contenant une mthode publique :
class clA { public int meth1(char x) { .... } }

2- Dclarer un type dlgation :


delegate int Deleg( char x ) ;

3- Instancier un objet de la classe clA :


clA ObjA = new clA ( ) ;

4- Instancier partir de la classe Deleg un dlgu :


Deleg FoncDeleg = new Deleg(ObjA.meth1);

Dlgu multicast
En C/C++, la fonction pointe par un pointeur peut tre variable et peut donc changer durant lexcution du programme. Toutefois, un instant donn, le pointeur ne peut pointer que sur une seule fonction. Par rapport ceci, en C#, un dlgu peut faire rfrence un instant donn plusieurs fonctions en mme temps. Ce type de dlgu est appel dlgu multicast. Les mthodes rfrences par un dlgu multicast doivent avoir le mme prototype. Elles peuvent tre des mthodes de classes ou des mthodes dinstances. Lajout dune rfrence un dlgu multicast se fait laide de loprateur dadition += comme suit : NomDlgu += new TypeDlgation(NomMthode); Exemple :
delegate int Dlgu(char x); class ClasseA { public int champ; public int meth100 ( char x ) { System.Console.WriteLine ("Excution de meth100('"+x+"')"); return x+100 ; } public int meth101 ( char x ) { System.Console.WriteLine ("Excution de meth101('"+x+"')"); return x+101 ; } public int meth102 ( char x ) { System.Console.WriteLine ("Excution de meth102('"+x+"')"); return x+102 ; } public static int meth103 ( char x ) { System.Console.WriteLine ("Excution de meth103('"+x+"')"); return x+103 ; }} class Prog { static void Main ( ) { ClasseA ObjA = new ClasseA( ); //-- instanciation du dlgu avec ajout de 4 mthodes : Dlgu FoncDeleg = new Dlgu( ObjA.meth100 ) ;

30

Karim Kalti

FoncDeleg += new Dlgu ( ObjA.meth101 ) ; FoncDeleg += new Dlgu ( ObjA.meth102 ) ; FoncDeleg += new Dlgu ( ClasseA.meth103 ) ; //--la mthode meth103 est en tte de liste : //--Appel du dlgu sur le paramtre effectif 'a' : ObjA.champ = FoncDeleg('a') ; //code ascii 'a' = 97 System.Console.WriteLine ( " valeur du champ : "+ObjA.champ) ; }}}

Rsultat de lexcution du programme :


Excution Excution Excution Excution valeur du de meth100('a') de meth101('a') de meth102('a') de meth103('a') champ : 200

Suppression d'une rfrence une mthode dans un dlgu multicast : Il est possible de supprimer une rfrence une mthode laide de loprateur -= comme suit : NomDlgu -= new TypeDlgation(NomMthode); Exemple :
FoncDelg -= new dlgu (ClasseA.meth103) ;

Les vnements
Les vnements permettent de capturer une action dans un programme. Ils jouent un rle trs important dans les programmes tournant sous windows (utilisant les contrles graphiques de windows : bouttons, formulaires, menus). Les vnements dfinissent un style de programmation part entire appel programmation vnementielle. Lorsquun vnement a lieu, il doit tre intercept (par la machine virtuelle CLR dans les programmes manags et par Windows dans les programmes Win32). Le programme doit ragir galement cet vnement et entreprendre les actions ncessaires. Implmentation dun mcanisme de dtection et de gestion dvnements. Pour raliser une gestion des vnements en .Net, il faut procder comme suit : Dfinir le type des vnements dtecter. Dfinir un module de dtection (MD) de ce type d'vnements appel galement source dvnements. Dfinir un module de traitement des vnements (MT) appel galement gestionnaire dvnements. Lorsquun vnement est dtect par le MD ; ce dernier doit connatre le MT capable de traiter cet vnement. Pour cela le MT doit tre connu par le MD pour que ce dernier puisse linformer. On dit que le MT doit tre dans la liste de notification du MD. La liste de notification dun MD peut comporter un ou plusieurs MT. Un MT peut se retirer de la liste de notification dun MD sil ne veut plus traiter les vnements dtects par ce dernier. Le traitement dun vnement par le MT se fait en ralit travers une fonction FT de ce dernier ayant le mme prototype que lvnement. Le MD doit tre capable dappeler les FT de nimporte quel MT faisant partie de sa liste de notification. Pour cela il doit disposer dun dlgu qui peut faire rfrence ces FT. Dclaration du type de lvnement (dlgu) 1- Dfinition du type de dlgation public delegate TypeRetour TypeEvenement(Liste d'arguments); 2- Dclaration de lvnement laide du mot-cl event. public event TypeEvenement NomEvenement; Normalisation des vnements en .NET pour dclarer lvnement il est possible dutiliser un dlgu ayant nimporte quel prototype, suivant les besoins du programme bien sr. Toutefois le .Net recommande dutiliser lun des deux prototypes normaliss suivants : delegate void TypeDelegation(Object sender, EventArgs e) delegate void TypeDelegation(Object sender, MonEventArgs e)

31

Karim Kalti

o : sender dsigne lobjet source de lvnement. e dsigne un objet contenant les paramtres de lvnement. e peut ne pas contenir d'informations. Dans ce cas il est de type EventArgs. EventArgs est la classe de base des classes qui peuvent contenir les informations associes aux vnements. Elle comporte quelques fonctions utilitaires telles que le test dgalit entre objets, la conversion de donnes vers le type string, etc. e peut comporter des informations personnalises. Dans ce cas e doit tre un objet driv de la classe EventArgs (exemple MonEventArgs). Les champs ajouts lors de la drivation contiennent normalement les donnes personnalises de lvnement. Autres recommandations : Le nom du type de dlgation doit se terminer par EventHandler. Le nom de la mthode qui dclenche lvnement doit tre de la forme OnNomEvenement. Cette mthode est gnralement dclar comme protge. Le lancement de lvnement se fait travers une mthode publique qui appelle la mthode protge de dclenchement de lvnement. Etapes pour la mise en place dun vnement avec informations personnalises 1- Une classe d'informations personnalises sur l'vnement. 2- Une dclaration du type dlgation normalise (nom qui se termine par EventHandler). 3- Une dclaration d'une rfrence NomEvenement du type dlgation normalise spcifie event. 4- Une mthode protge OnNomEvenement qui dclenche l'vnement NomEvenement. 5- Une mthode publique qui lance l'vnement par appel de la mthode OnNomEvenement. 6- Un ou plusieurs gestionnaires de l'vnement NomEvenement. 7- Abonner ces gestionnaires au dlgu NomEvenement. 8- Consommer l'vnement NomEvenement. Droulement des tapes travers un exemple :
using System; //1) une classe d'informations sur l'vnement public class ExamenEventArgs { public string DateExamen; public ExamenEventArgs( string S){ DateExamen = S;} } // 2) une dclaration du type dlgation public delegate void EvenementExamen(Object sender, ExamenEventArgs e); public class MD { // 3) une dclaration d'une rfrence NomEvenement du type de dlgation public event EvenementExamen Examen; // 4) une mthode protge qui dclenche l'vnement NomEvenement protected void OnExamen (Object sender, ExamenEventArgs e) { if (Examen!=null) Examen(sender,e); } // 5) une mthode publique qui lance l'vnement par appel de la // mthode NomEvenement public void LancerEvenement() { ExamenEventArgs e = new ExamenEventArgs("15-01-05"); OnExamen(this, e); } } class MT { // 6) un ou plusieurs gestionnaires de l'vnement NomEvenement static void Message(Object sender, ExamenEventArgs e) { Console.WriteLine("Attention l'examen s'approche"); Console.WriteLine("la date de l'examen est: " + e.DateExamen); }

32

Karim Kalti

// 7) abonner ces gestionnaires au dlgu NomEvenement public MT(MD md) { md. Examen+= new EvenementExamen(Message); } } class Prog { static void Main() { MD md = new MD(); MT mt = new MT(md); // 8) consommer l'vnement md.LancerEvenement(); } }

Complment sur les vnements


Un vnement est un message envoy par un objet pour signaler l'occurrence d'une action. Cette action peut tre cause par une interaction avec l'utilisateur (gnralement travers les interfaces graphiques comme par exemple le clic de la souris). Elle peut tre galement dclenche par la logique d'excution du programme. L'objet qui dclenche l'vnement est appel "source de l'vnement" ou galement metteur de l'vnement (event sender). L'objet qui capture l'vnement et qui le traite est appel "gestionnaire de l'vnement" (event handler) ou galement rcepteur de l'vnement (event receiver). La classe qui met un vnement ne connat pas l'objet ou la mthode qui va traiter cet vnement. Un intermdiaire entre l'metteur et le rcepteur est alors ncessaire. Cet intermdiaire n'est autre qu'un dlgu qui rfrence le rcepteur. L'appel de ce dlgu par l'metteur va engendrer par consquent l'excution du rcepteur. Diffrence entre un dlgu et un vnement Les vnements sont implments en .NET sous forme de dlgus. Toutefois, par rapport un dlgu classique, un vnement possde quelques restrictions supplmentaires notamment en ce qui concerne l'accs et l'invocation. Diffrence au niveau de l'invocation : Mme s'il est dclar en tant que membre public, un vnement ne peut tre invoqu que de l'intrieur de sa classe. Ce n'est pas le cas des dlgus qui se comportent avec les modificateurs d'accs la manire des champs classiques. La seule invocation possible d'un vnement de l'extrieur d'une classe est une invocation indirecte qui passe par l'utilisation d'une mthode publique de cette classe qui invoque en interne l'vnement. Exemple :
delegate void TypeEvent(int i); class X { // Dclaration de l'vnement public event TypeEvent MyEvent; // Mthode publique qui invoque l'vnement public void InvokeEvent() { if(MyEvent!=null) MyEvent(); } } class MainClass { // Fonction de traitement de l'vnement static void FT() { Console.WriteLine(" Traitement de l'vnement); }

33

Karim Kalti

public static void Main() { X x = new X(); // Inscription de la fonction de traitement x.MyEvent+= new TypeEvent(FT); // Invocation indirecte de l'vnement x.InvokeEvent(); } }

Pour pouvoir invoquer un vnement partir d'une classe drive, il suffit de dclarer une mthode protge dans la classe de base qui invoque en interne l'vnement. (il s'agit toujours d'une invocation indirecte) Mme si la mthode protge est dfinie comme virtuelle et qu'elle est redfinie dans la classe drive, alors la redfinition ne pourra pas invoquer directement l'vnement. Tout ce qu'elle peut faire c'est l'appel de sa version protge de la classe de base.

Exemple :
class Y:X { protected override void InvokeEvent() { // MyEvent(); ERROR base.InvokeEvent(); }

Le mot-cl event permet donc de crer un dlgu dont les droits d'invocation sont plus restreints que ceux d'un dlgu classique. En effet, par dfaut, le droit d'invocation d'un vnement est restreint l'intrieur de la classe dans laquelle est dclare cet vnement. Ensuite, c'est le propritaire de cette classe qui peut tendre ou non ce droit d'invocation aux utilisateurs de la classe en dfinissant ou non une mthode (publique ou protge) d'invocation indirecte. A la lumire de ce qui vient d'tre susmentionn la question suivante se pose : pourquoi dclare-t-on un vnement public s'il ne peut pas tre invoqu de l'extrieur ? La rponse cette question rside dans le fait qu'un vnement a besoin de rfrencer une (ou plusieurs) mthode(s) pour qu'il puisse tre trait. Cette opration se fait travers l'inscription de la (des) fonction(s) de traitement auprs de l'vnement. L'inscription se fait de l'extrieur de la classe qui contient l'vnement (par un objet externe) ce qui oblige par consquent l'vnement tre accessible de l'extrieur donc public. Diffrence au niveau de l'accs Accs un dlgu Un dlgu classique est accessible de plusieurs manires : Deleg = new TypeDelegation(NomMethode) pour un dlgu unicast ou pour inscrire une premire fonction auprs d'un dlgu multicast. Deleg+= new TypeDelegation(NomMethode) pour ajouter une inscription un dlgu multicast qui rfrence dj au moins une fonction. L'instruction Deleg = new TypeDelegation(NomMethode) applique un dlgu qui rfrence dj une (ou plusieurs) mthode(s) engendre la suppression de toutes ces mthodes de la liste de notification du dlgu. Le mme effet est obtenu avec l'instruction : Deleg = null; La suppression d'un gestionnaire de la liste de notification d'un dlgu multicast se fait l'aide de -=. Accs un vnement A la diffrence d'un dlgu, un vnement n'accepte que les accs l'aide des oprateurs += et -=. Cette restriction permet d'introduire un niveau de scurit supplmentaire. En effet, de par sa dfinition un vnement doit tre capable de dclencher une ou plusieurs actions (Exemple : un accident peut dclencher un appel au SAMU et un autre appel la police). Techniquement cela se traduit par le fait qu'un vnement doit tre capable d'accepter les inscriptions indpendantes de plusieurs gestionnaires d'vnements (fonctions de traitement). Toutefois, si par erreur une inscription se fait l'aide de l'oprateur = alors que d'autres gestionnaires sont dj inscrits alors ces derniers seront tout simplement limins de la liste de notification. Pour viter ce risque et pour donner plus de scurit et d'indpendance au processus d'inscription, le .NET n'autorise un gestionnaire s'inscrire auprs d'un vnement qu' l'aide de l'oprateur += (ceci est valable mme pour l'inscription du premier gestionnaire). De mme la dsinscription ne peut tre ralise qu'avec l'oprateur -= et elle touche un seul gestionnaire la fois. Ainsi, si un vnement est sollicit par plusieurs gestionnaires, alors chaque gestionnaire

34

Karim Kalti

ne pourra agir que sur sa propre fonction de traitement sans risquer de toucher les fonctions des autres gestionnaires. Remarque : Une telle restriction permet par exemple de garantir aux composants logiciels que leurs utilisateurs (gnralement les programmes qui intgrent ces composants) ne peuvent pas engendrer (par erreur ou par malveillance) en ajoutant un traitement personnalis un vnement la suppression d'un ventuel traitement prdfini, intgr par dfaut, et indispensable pour le bon fonctionnement de ces composants.

35

Karim Kalti

Les classes
Dclaration
Une classe dfinit un nouveau type de donnes. Une classe peut comporter : o des attributs, des proprits et des indexeurs. o des mthodes, des dlgus et des vnements. Une classe est dfinie avec le mot rserv class. Le point virgule aprs la dclaration dune classe est optionnel. Exemple :
class Pers { string Nom ; string Prenom; int Age; }

Instanciation des classes (Les objets)


Cration C# ne permet que la dclaration dynamique dobjets : pas de dclaration dinstance de type auto (au sens du C++). Tout objet est une rfrence. Syntaxe :

NomClasse RefObjet; // Dclaration d'une rfrence un objet RefObjet = new ConstructeurNomClasse(<arguments>); // instanciation
Les deux instructions prcdentes peuvent tre regroupes en une seule comme suit :

NomClasse RefObjet = new ConstructeurNomClasse(<arguments>);

Exemple :
Pers p ; // p est une rfrence un objet de type Pers p = new Pers( ) ; // Instanciation // Les parenthses sont requises mme si le constructeur est absent ou nadmet pas // darguments.

Libration Elle se fait dune manire automatique par le GC. La libration se fait si : o On quitte le bloc o l'objet a t dclar. o On affecte l'objet la rfrence d'une nouvelle instance de la classe ou si on lui affecte la rfrence "null".

Droits d'accs aux membres d'une classe


Les droits d'accs un membre d'une classe en C# sont dfinies l'aide des mots-cls suivant : o public : toutes les mthodes (du mme assemblage ou non) peuvent accder ce champ ou appeler cette mthode. o private : seules les mthodes de la classe peuvent accder ce champ ou appeler cette mthode. o protected : seules les mthodes de la classe et des classes drives (du mme assemblage ou non) peuvent accder ce champ ou appeler cette mthode. o internal : seules les mthodes du mme assemblage peuvent accder ce champ ou appeler cette mthode.

36

Karim Kalti

Les droits d'accs en C# doivent tre dfinis individuellement pour chaque membre de la classe. Si aucun droit d'accs n'est explicitement spcifi devant un membre, alors ce dernier sera considr par dfaut comme tant priv.

Valeur initiale d'un champ


L'initialisation d'un champ d'une classe se fait au moment de la dfinition de cette dernire. (cf le champ TotalPoints de la classe Jeu). Exemple
class Jeu { int TotalPoints = 100; int PointsPerdus; int PointsGagns; }

Le champ TotalPoints est explicitement initialis 100. Pour toute nouvelle instance de la classe Jeu, ce champ vaudra 100. Un champ non explicitement initialis prend la valeur 0 s'il est numrique, false s'il est boolen, espace s'il est caractre et chane vide s'il est de type chane. La valeur du champ peut tre modifie tout moment durant l'excution.

Les champs constants


Il est possible de dfinir des champs constants l'aide des mots-cls const et readonly. Un champ dfini par const reprsente une constante de classe. Il prend la mme valeur constante pour toutes les instances de sa classe. Un champ const doit tre initialis au moment de la dfinition de la classe. Un champ dfini par readonly reprsente une constante d'instance. Il prend une valeur constante spcifique pour chaque instance de la classe. Un champ readonly est initialis par le constructeur. Une fois initialis, un champ constant (dfini par const ou readonly) ne peut plus changer de valeur.

Les mthodes
Le corps d'une mthode doit se trouver dans la dfinition de la classe. (pas de possibilit de dfinition des mthodes l'extrieur de la classe comme en C++). Il n'y a pas de fichiers d'enttes (fichiers .h). L'emplacement de la dfinition d'une classe ou d'une mthode n'a pas d'importance par rapport au lieu de son appel. Exemple :
using System; class Pers { public string Nom; public int age; public void Affiche() {Console.WriteLine(Nom+"("+Age+")");} } class Prog { static void Main() { Pers p = new Pers(); P.Nom ="Ali"; P.Age=20; P.Affiche(); }}

La surcharge de mthodes
Plusieurs mthodes d'une classe peuvent porter le mme nom. Elles doivent cependant se distinguer par leurs signatures (nombre, ordre et types des paramtres). Ces mthodes sont dites surcharges. Deux mthodes surcharges ne peuvent pas se distinguer seulement par le type de leurs valeurs de retour.

37

Karim Kalti

Exemple :
class Pers { string Nom="Moi"; int Age = 20; public void Modifier(string N){Nom=N;} public void Modifier(int A){Age=A;} public void Modifier(string N, int A){Nom=N;Age=A;} } class Prog { static void Main() { Pers P = new Pers(); P.Modifier("Ali"); P.Modifier("Salah",25); } }

Accs aux membres d'une classe


Accs de l'intrieur de la classe Les champs et les mthodes d'une classe sont directement accessibles de l'intrieur d'une classe (indpendamment des droits d'accs). La manipulation des champs et l'appel des mthodes dans ce cas peuvent se faire directement travers leurs noms sans ncessiter aucune qualification supplmentaire. Accs de l'extrieur de la classe L'accs aux champs et aux mthodes d'une classe de l'extrieur n'est possible que pour les membres publics. Cet accs se fait gnralement partir d'une instance de la classe l'aide de l'oprateur " . ". NomObjet.Attribut NomObjet.Methode(<arguments>)

Le mot rserv this


Le mot rserv this sert rfrencer l'objet en cours d'utilisation. Exemple d'utilisation : (Arguments de mthodes ayant les mmes noms que les champs)
public void Modifier(string Nom, int Age) {this.Nom=Nom;this.Age=Age;}

Les constructeurs
Les constructeurs possdent globalement les mmes caractristiques qu'en C++. Une classe peut comporter un ou plusieurs constructeurs. Dans le cas d'existence de plusieurs constructeurs ces derniers doivent respecter les rgles de surcharge de mthodes. Ils doivent porter le mme nom que celui de la classe. Ils peuvent admettre 0, un ou plusieurs paramtres. Ils ne renvoient rien. Leur dclaration explicite n'est pas obligatoire. En cas d'absence de dclaration explicite d'un constructeur, un constructeur par dfaut est automatiquement gnr pour la classe. En cas de prsence d'au moins un constructeur explicitement dfini, alors aucun constructeur par dfaut n'est gnr. Exemple 1 : Utilisation du constructeur par dfaut
Class NomClasse { } objet = new NomClasse(); // Appel du constructeur par dfaut

38

Karim Kalti

Exemple 2 : Classe avec constructeurs paramtrs


class Pers { string Nom; int Age; public Pers(string N) {Nom=N;Age=20;} public Pers(string N, int A) {Nom=N;Age=A;} public void Afficher() {Console.WriteLine(Nom+"("+Age+")");} } class Prog { static void Main() { Pers P1 = new Pers("Ali"); Pers P2 = new Pers("Mehdi",23); P1.Afficher(); P2.Afficher(); }}

Liste d'initialiseurs Une liste d'initialiseurs permet l'appel d'un constructeur d'une classe par un autre constructeur de la mme classe. Une liste d'initialiseurs commence par le symbole : suivi de this et d'une liste d'arguments dfinie par la signature du constructeur appel. Exemple :
class Text { int a; int b; string str; public Text(): this(0, 0, null) {} public Text(int x, int y): this(x, y, null) {} public Text(int x, int y, string s) { a=x; b=y; str=s; } }

Destructeur
La notion de destructeur existe en C# bien qu'elle ne soit pas aussi utile qu'en C++. Un destructeur possde le mme nom que celui de la classe, prcd par ~. Un destructeur n'accepte aucun paramtre. Un destructeur n'accepte aucun modificateur d'accs (public private, ). Un destructeur en C# ne peut pas tre explicitement appel (pas d'instruction delete). Les destructeurs en C# ne sont pas dterministes comme en C++ : o En C++ le destructeur est automatiquement appel quand l'objet quitte sa zone de validit. o En C# le destructeur devient "appelable" pour un objet lorsque il n'existe plus de rfrence cet objet dans le programme. Toutefois on ne peut pas connatre exactement le moment de l'appel effectif du destructeur. Cet appel est en effet gr par le Garbage Collector. Il est effectu lorsqu'un besoin en mmoire se manifeste.

Exemple :
class Pers { string Nom; int Age; public Pers(string N) {// code du constructeur} ~Pers() {// code du destructeur} ... }

39

Karim Kalti

La mthode Dispose .NET met la disposition des programmeurs une mthode pouvant tre appele automatiquement lorsque la fin de la zone de validit d'un objet est atteinte. Cette mthode est appele Dispose. Il est possible de mettre dans Dispose le code destin tre plac dans le destructeur (libration des ressources). Pour qu'une classe garantisse au runtime que la mthode Dispose qu'elle implmente est celle devant tre appele la fin de la zone de validit de l'objet (mthode du .NET), cette classe doit implmenter l'interface IDisposable du .NET. Le prototype de Dispose est le suivant :
void Dispose() ;

Une classe doit implmenter IDisposable comme ceci :


class Pers : IDisposable { ... ... ... public void Dispose() { // mettre ici le code de libration des ressources } ... ... ... }

Il est noter que la zone de validit dont il est question ici n'est pas automatiquement dtermine par le systme (en se basant sur les limites du bloc de dclaration comme c'est le cas en C++). Elle doit plutt tre dfinie explicitement par le programmeur l'aide de using comme suit :
Pers p = new Pers() ; using (p) // Definition de la zone de validit { ... ... } // fin de la zone de validit pour p

Il est galement possible de crer des zones de validit pour plusieurs objets :
Pers p = new Pers() ; Animal a = new animal(); using (p) using (a) { }

Les mthodes a.Dispose et p.Dispose seront automatiquement invoques (dans le sens inverse des using : a avant p) lorsque lexcution atteint laccolade fermante. Dispose peut tre : o explicitement appele : NomObjet.Dispose( ); o implicitement appele : en utilisant les zones de validit.

La mthode Finalize La mthode Finalize joue en .NET le mme rle jou par les destructeurs en C#. Cette mthode est automatiquement excute lorsqu'un objet est pris en charge par le GC. Finalize est une mthode de la classe Object, classe de base du .NET. Tout objet possde donc par dfaut une telle mthode. Comme pour les destructeurs, on met dans Finalize le code de libration des ressources. Finalize ne peut pas tre explicitement appele. Le moment d'appel de Finalize n'est pas dterministe. Cet appel tant dcid et fait par le GC lorsqu'un besoin en mmoire se manifeste. En .NET Finalize assure un mcanisme de destruction mme pour les langages qui ne supportent pas en natif un tel mcanisme (absence de la notion de destructeur au sens du C++ ou du C#).

40

Karim Kalti

Les tableaux dobjets


Les tableaux d'objets prsentent des diffrences par rapport au C++. En C#, le constructeur de la classe doit tre explicitement appel pour chaque lment (objet) du tableau. En effet les tableaux d'objets tels qu'ils sont dclars en C# sont des tableaux de rfrences. Chaque rfrence doit donc tre initialise par une instance de la classe. Il est possible d'appeler n'importe quel constructeur (paramtr ou non) pour initialiser les tableaux d'objets. Syntaxe :
NomClasse[] Tab; // Dclaration du tableau Tab = new NomClasse[Taille]; // Allocation du tableau for(int i = 0; i <Taille; i++) // instanciation des lments du tableau. Tab[i] = new NomClasse(<arguments>);

Exemple :
Pers[] TP ; TP = new Pers[10] ; for(int i = 0; i <TP.Length ; i++) TP[i] = new Pers();

Membres statiques
Les champs et les mthodes dune classe peuvent tre qualifis de statiques. Les champs et les mthodes statiques existent sans ncessit dinstanciation de la classe. Le mot-cl static est utilis pour qualifier un champ ou une mthode de statique. Exemple :
class X { public public public public } int a ; // champ non statique static int b ; // champ statique void f(){} // mthode non statique static void g(){b++;} // mthode statique

Les champs statiques Un champ statique (appel galement champ de classe) : est accessible indpendamment de tout objet de la classe. Il existe mme si aucun objet de la classe na encore t cr. est partag par tous les objets de la classe. est accessible partir du nom de la classe : NomClasse.Champ; (Exemple : X.b) n'est pas accessible partir d'un objet : Obj.ChampStatique // erreur peut tre initialis et manipul par une mthode de la classe comme nimporte quel champ. Les mthodes statiques Une mthode statique (appele galement mthode de classe) : Peut tre appele en spcifiant directement le nom de la classe suivi du nom de la mthode. NomClasse.Methode(arguments) (Exemple : X.g() ;). Contrairement au C++, elle ne peut pas tre appele partir dun objet : Obj.MethodeStatique // erreur Ne peut accder quaux champs statiques de sa classe. Ne peut appeler que les mthodes statiques (de sa classe ou dune autre classe). Une mthode non statique (appele galement mthode d'instance) peut accder la fois aux champs statiques et non statiques. Elle peut appeler galement les mthodes statiques et non statiques.

Constructeur statique Un constructeur statique est un constructeur qui ne peut initialiser que les membres statiques d'une classe. Un constructeur statique ne possde jamais d'arguments. Un constructeur statique n'accepte pas les modificateurs d'accs (public, private, ).

41

Karim Kalti

Syntaxe : class X { static X() { } } Un constructeur statique ne peut pas tre appel explicitement. Un constructeur statique est appel implicitement suite l'instanciation d'un objet de la classe (il prcde l'appel du constructeur d'instance) ou lorsqu'un membre statique de la classe est appel. Exemple :
using System; class A { public static int i; public int j; static A() { Console.WriteLine("Constructeur statique"); i=5; } public A(int v) { Console.WriteLine("Constructeur d'instance"); j=v; } public A(int v1, int v2) { Console.WriteLine("Constructeur d'instance"); i=v1; j=v2; } public void Afficher() { Console.WriteLine("i vaut :"+i); Console.WriteLine("j vaut :"+j); } } class Prog { static void Main() { A a1 = new A(3); a1.Afficher(); // i = 5 et j=3 A a2 = new A(4,9); a2.Afficher(); // i = 4 et j=9 } }

Hritage de composition et imbrication de classes


Une classe peut contenir comme membre un objet dune autre classe. On parle dans ce cas dhritage de composition. Une classe peut tre dclare dans une autre classe. Elle ne peut alors tre utilise qu lintrieur de cette classe. On parle dans ce cas de classes imbriques. Exemple :
class A { public class B { int chpr; public int chpu; public B(int arg){chpre =arg; chpu = 10*arg;} public int getchpr(){return chpr;} } B prB; public B puB; public A(int arg) { prB = new B(2*arg); puB = new B(10*arg); } public int getchprB() {return prb.getchpr();} }

42

Karim Kalti

Un objet de la classe B ne peut pas tre cr en dehors de la classe A. B est un objet local A. La partie publique de B peut tre accde par le membre public de A.
A a = new A(5) ; int n = a.getchprB(); // Ok car getchprB est publique. n= a.puB.chpu; // Ok car puB et chpu sont publiques

Les objets privs de B restent privs pour A :


a.pub.chpr a.prb.chpu

// nest pas accessible. // erreur car prb est priv

Hritage
Globalement similaire au C++. Pas dhritage multiple. Syntaxe : class ClasseDrive : ClasseDeBase { } Exemple : Hritage
class Pers { protected string Nom ; protected int Age; public Pers(string N, int A){ Nom = N; Age = A;} public void Afficher( ) { Console.WriteLine(Nom+ "(" + Age + ")");} } class Tunisien : Pers { string ville; public Tunisien(String N, int A, string V) : base (N,A) { Ville = V; } public new void Afficher() { Console.WriteLine(Nom+" Ag de " + Age + " ans (" + Ville+")"); } }

Appel du constructeur de la classe de base L'appel du constructeur de la classe de base se fait l'aide du mot-cl base. Lorsqu'il est utilis dans une classe drive, ce mot-cl permet de rfrencer la classe de base (classe mre). L'appel du constructeur de la classe de base peut tre omis. Dans ce cas c'est le constructeur par dfaut qui est appel. Si la classe de base possde un constructeur avec paramtres et si le constructeur par dfaut n'est pas explicitement dfini alors une erreur sera signale par le compilateur. Redfinition de mthode Il est possible de redfinir une mthode d'une classe de base dans une classe drive. Dans ce cas, la redfinition est gnralement prcde du mot-cl new. le new est optionnel, il sert gnralement amliorer la lisibilit du code en indiquant qu'il s'agit bien de la redfinition d'une mthode. Tout appel d'une mthode redfinie partir d'une instance de la classe drive va engendrer l'utilisation de la version dfinie dans la classe drive. Exemple 1 :
Tunisien T = new Tunisien ("Ali",20,"Monastir"); T.Afficher();

T est un objet de la classe Tunisien. L'instruction T.Afficher( ) va engendrer l'appel de la mthode Afficher de la classe Tunisien. Cette mthode cache la mthode Afficher de la classe Pers.

43

Karim Kalti

Exemple 2 : Considrons le code suivant :


class Prog { static void Main() { Pers p1, p3; Tunisien p2; p1=new Pers("Ali",20); p1.Afficher(); p2 = new Tunisien ("Salah",22,"Monastir"); p2.Afficher(); p3 = new Tunisien ("Salem",25,"Sousse"); p3.Afficher(); } }

Pour P1 : c'est la mthode Afficher de la classe Pers qui est appele. Pour P2 : c'est la mthode Afficher de la classe Tunisien qui est appele. Afficher de Tunisien cache dans ce cas Afficher de Pers. Si Afficher de Tunisien n'tait pas dfinie, a serait Afficher de Pers qui aurait t appele. P3 = new Tunisien( ) est possible car tout objet Tunisien est de type Pers. P3.Afficher( ) excute la mthode Afficher de Pers car P3 a t dclare en tant que tel. Le compilateur se base dans ce cas sur la dfinition stricte. Les fonctions virtuelles Pour tenir compte du vritable type de P3 au moment de l'excution de P3.Afficher( ), il faut qualifier Afficher de virtual dans la classe de base et de override dans la classe drive.
class Pers { protected string Nom ; protected int Age; public Pers(string N, int A){ Nom = N; Age = A;} public virtual void Afficher( ) { Console.WriteLine(Nom+ "(" + Age + ")"); } class Tunisien : Pers { string Ville; public Tunisien(String N, int A, string V) : base (N,A) {Ville = V;} public override void Afficher() {Console.WriteLine(Nom+" Ag de " + Age + " ans (" + Ville+")");} } Pers p3; p3 = new Tunisien ("Salem",25,"Sousse"); p3.Afficher(); // Salem ag de 25 ans (Sousse)

Appel des mthodes caches par la redfinition Il est possible d'appeler une mthode d'une classe mre dans une classe fille mme si cette mthode a t redfinie dans la classe fille. Pour cela il suffit de faire prcder le nom de cette mthode par une rfrence la classe mre. Cette rfrence est obtenue l'aide du mot-cl base. Exemple : La mthode Afficher de Tunisien cache celle de Pers. Mais rien n'empche d'appeler cette dernire dans la classe Tunisien. Il suffit de faire prcder le nom de cette mthode par base.
Exemple : base.Afficher();

Redfinition de champs Il est possible de dfinir dans une classe drive un champ qui porte le mme nom qu'un champ de la classe de base. Pour distinguer entre les deux, il est possible d'crire : This.NomChamp : pour dsigner le nom du champ de la classe courante (classe drive). base.NomChamp : pour dsigner le nom du champ de la classe de base. Remarque : Il n'est pas possible de chaner l'utilisation de "base" pour accder aux membres d'une classe grand-mre.
Exemple : base.base.Affiche() // erreur

44

Karim Kalti

Identification du vritable objet instanci Il est possible de connatre le vritable type d'un objet instanci et ce l'aide du mot-cl "is". Exemple :
class Pers { public void Mariage(Pers Conjoint) { if(Conjoint is Tunisien) Console.WriteLine("Mariage avec compatriote"); else Console.WriteLine("Mariage avec tranger"); } } class Tunisien : Pers { string ville; public Tunisien(String N, int A, string V) : base (N,A) {Ville = V;} public override void Afficher() {Console.WriteLine(Nom+" Ag de " + Age + " ans (" + Ville+")");} } class Prog { static void Main() { Tunisien T = new Tunisien("Ammar",50,"Nabeul"); Pers P1 = new Tunisien ("Salma",45,"Kairouan"); Pers P2 = new Pers("Carla",45); T.Mariage(P1); // Mariage avec compatriote T.Mariage(P2); // Mariage avec tranger } }

Oprations applicables aux objets


La copie d'objets Une affectation directe entre deux objets effectue en ralit une copie de rfrences et non une copie d'instances. Exemple 1 :
Pers P1,P2; P1 = new Pers("Ali",20); P2= P1;

Dans l'exemple 1, c'est une copie de rfrence qui a t effectue et non une copie d'objet. P1 et P2 font rfrence donc au mme objet. Pour effectuer une vritable copie d'objets il faut que la classe en question implmente la mthode Clone de l'interface IClonable. La mthode Clone possde le prototype suivant : public object Clone() Exemple 2 :
class Pers : IClonable { ... public object Clone() {return new Pers(Nom, Age);} }} ... p2=(Pers)p1.Clone();

Pers implmente l'interface IClonable. Elle propose en effet une dfinition de la mthode Clone dans laquelle est mis le code effectuant la copie explicite. La comparaison d'objets Une comparaison globale d'objets effectue en ralit une comparaison de rfrences et non une comparaison d'instances. Pour effectuer une vritable comparaison, il faut comparer les deux objets champ par champ. Exemple :
Pers P1,P2; ... P2==P1; est une

comparaison de rfrences d'objets.

45

Karim Kalti

Les protections
Protection des classes Le seul qualificatif qui peut tre utilis avec les classes est public. Ainsi, si la classe est prcde de : public : alors il est possible de crer partout un objet de la classe. rien du tout : alors il est possible de crer un objet de la classe mais seulement dans le mme assemblage. Protection des membres Les membres d'une classe peuvent utiliser les qualificatifs suivants : public : signifie que toutes les mthodes (du mme assemblage ou non) peuvent accder ce champ ou appeler cette mthode. private : signifie que seules les mthodes de la classe ont accs un tel champ ou une telle mthode. Le fait domettre le qualificatif revient spcifier private. protected : signifie que seules les mthodes de la classe et des classes drives (du mme assemblage ou non) ont accs un tel champ ou une telle mthode. internal : signifie que seules les mthodes du mme assemblage ont accs un tel champ ou peuvent appeler une telle mthode. Interdiction de drivation Il est possible d'interdire toute drivation partir d'une classe et ce l'aide du qualificatif sealed. Exemple :
sealed class Tunisien : Pers { ... }

Avec l'utilisation de sealed il devient impossible de driver partir de la classe Tunisien.

Les classes abstraites


Une classe abstraite est une classe qui possde une ou plusieurs mthodes qui ne sont pas implmentes. Une classe abstraite est dfinie avec le mot-cl abstract comme suit : Syntaxe : abstarct class NomClasse { } Une classe abstraite ne peut pas tre instancie. Une classe abstraite est utilise gnralement pour faire des drivations. Les classes drives qui sont compltement implmentes peuvent tre instancies. Exemple :
abstract class Forme { int Surface; void CalculerSurface(); // pas d'implmentation } class Rectangle : Forme { int x1, int y1; int x2; int y2; void CalculerSurface(){ } } class Circle : Forme { int cx; int cy; int Rayon void CalculerSurface(){ } }

46

Karim Kalti

La classe Forme possde une mthode de calcul de la surface, mais cette mthode ne peut tre implmente que dans les classes drives (car il faut connatre la nature de la forme pour savoir comment calculer la surface).

Les interfaces
Dfinition Une interface est une classe qui ne comporte que des mthodes sans implmentation. On trouve seulement les prototypes de ces fonctions (il faut mettre les noms des paramtres formels). Les membres dune interface ne peuvent tre que des mthodes, des indexeurs, des proprits ou des vnements. Une interface ne peut pas comporter des champs. Une interface ne comporte pas des qualificatifs de protection (public, private,.). Le nom dune interface commence par I. Une interface est dfinie avec le mot-cl interface comme suit : interface NomInterface { Methode1(<Liste d'arguments>); ......... Methode2(<Liste d'arguments>); } Utilit des interfaces Une interface dfinie une sorte de cahier de charge concernant un certain comportement (ensemble d'oprations). Chaque classe qui implmente une interface garantit ses utilisateurs qu'elle est capable d'assurer les oprations dfinies par l'interface. Interface et drivation Il est possible de driver des classes partir dune interface. Si la classe drive propose des dfinitions aux mthodes de l'interface alors le processus de drivation s'appelle implmentation. L'implmentation d'une interface par une classe drive peut tre complte ou partielle. Une classe drive d'une interface n'est instanciable que si elle propose une implmentation complte de l'interface. Les mthodes implmentes dans les classes drives acceptent les qualificatifs de protection. Une interface peut driver dune autre interface (drivation sans aucune implmentation). Exemple : implmentation d'une interface par une classe
interface IB { void f1(int a); void f2(); } class X : IB { ... void f1(int a){...} void f2(){...} }

Implmentation de plusieurs interfaces Une classe ne peut driver que d'une seule autre classe. Elle peut par contre implmenter plusieurs interfaces en mme temps. Exemple : Soient IB et IC deux interfaces
class X : IB, IC { ... // champs et mthodes de X void f1(int a){...} // corps de mthodes de IB void f2(){...} // corps de mthodes de IB void g1(){...} // corps de mthodes de IC. }

47

Karim Kalti

Une classe drive peut avoir comme classes de base une classe et des interfaces. Dans ce cas, dans la dfinition de la classe drive, la classe de base doit tre liste en premier lieu. Exemple :
class ClassA: BaseClass, Iface1, Iface2 { // les membres de la classe }

Ambigut dimplmentation de plusieurs interfaces Deux interfaces peuvent comporter des mthodes portant le mme nom. Une classe qui implmente ces deux interfaces en mme temps doit alors rsoudre le problme dambigut dappel de telles mthodes. Exemple :
interface IB { void f(); void g(); } interface IC { double f(int a); void h(); }

Soit A une classe qui implmente IB et IC. Limplmentation de la mthode f doit alors tre associe chaque fois une rfrence de linterface laquelle elle se rapporte.
class A : IB, IC { void IB.f(){...} double IC.f(int a){...} }

Pour appeler ces fonctions il faut crire comme suit :


A a = new A(); IB rib = a; rib.f(); // Excution de f de IB applique a IC ric= a; double d=ric.f(5); //Excution de f de IC applique a.

48

Karim Kalti

Les exceptions
Les exceptions sont des erreurs qui ont lieu au moment de l'excution des programmes (pas au moment de la compilation) et qui ont pour cause une situation inattendue (exemple : tentative de lecture d'un fichier qui n'existe plus ou qui est dplac). Ancienne technique de gestion des erreurs d'excution Avec les langages qui ne supportent pas la gestion des exceptions (exemple C), le traitement des erreurs se fait gnralement en faisant des tests sur les valeurs de retour des fonctions. Ces dernires retournent le plus souvent des codes indiquant le type de l'erreur. Ces codes ne comportent pas des informations supplmentaires sur les causes et les paramtres des erreurs. En plus cette technique devient fastidieuse dans le cas d'appels imbriqus de fonctions (le gestion des erreurs complique le code surtout au niveau des fonctions internes). Avantage de la gestion d'exceptions Les mcanismes de gestion des exceptions permettent d'viter ces problmes : Il devient ainsi possible de grer un seul niveau les exceptions, mme celles engendres par des fonctions internes (Possibilit de centralisation de la gestion en des points prcis). Il est galement possible d'avoir plus d'informations sur les causes des erreurs. Les erreurs ne sont plus dcrites par des codes mais par des objets qui drivent tous d'une classe de base appele Exception et qui sont spcifiques chacun un type d'erreur bien prcis. Chaque objet comporte des informations qui dcrivent l'erreur. Familles d'exceptions Il existe deux grandes familles d'exceptions : Les exceptions gnres par le systme (runtime exception) comme les divisions par zro, l'accs un tableau en dehors de ses bornes, l'accs un fichier absent Les exceptions gnres par les applications. Ces exceptions sont gnralement de type smantique et dpendent du contexte de l'application. Comme exemple de ces exceptions, il est possible de citer la saisie d'une valeur trop leve pour l'age (250). C'est au programmeur de dfinir dans ce cas ce type d'exceptions. Gestion des exceptions La programmation oriente objet offre une solution structure de gestion d'erreurs sous la forme de bloc try et catch. L'ide est de sparer physiquement les instructions essentielles du programme qui grent son droulement normal des instructions de gestion d'erreurs. Le bloc try contient les instructions qui sont susceptibles d'engendrer une erreur. Le bloc catch contient le code de gestion d'erreurs. Syntaxe : try { // Bloc d'instructions du programme } catch(ClasseException e) { // Bloc de gestion des erreurs } Les accolades dans les blocs de try et de catch sont obligatoires mme si ces derniers comportent une seule instruction. Le type de ClasseException doit tre la classe System.Exception ou une classe qui drive de cette dernire. La porte de l'identificateur e est limite au bloc catch. Il est gnralement utilis pour rcuprer les informations sur l'erreur partir des attributs de ClasseException. S'il n'est pas fait usage de e dans le bloc catch alors cet identificateur peut tre omis. catch(ClasseException) { // Bloc de gestion des erreurs }

49

Karim Kalti

Droulement de l'excution Le programme entre dans le bloc de try comme si cette dernire instruction n'existait pas. Il commence alors l'excution squentielle des instructions de ce bloc. Ds qu'une erreur est dtecte par le systme ou par une mthode (qui lve une exception) un objet de la classe ClasseException est cr et le programme quitte le bloc try et rentre tout aussi automatiquement dans le bloc catch. Exemple :
using System; class Prog { static void Main() { int a = 5,b = 0,c; try { Console.WriteLine("Avant division"); c=a/b; Console.WriteLine("Aprs division c vaut "+c); } catch(Exception) {Console.WriteLine("Erreur sur opration arithmtique");} } }

Blocs catch multiples Le bloc de try peut comporter plusieurs instructions. Chaque instruction peut lever une ou plusieurs exceptions. Il est possible d'associer un tel bloc plusieurs blocs catch qui interceptent chacun un type d'exception particulier. En cas d'erreur le contrle passe au premier bloc catch. Si cette erreur correspond l'argument de ce premier bloc catch alors l'erreur est traite par ce bloc. Dans le cas contraire le catch suivant est inspect et ainsi de suite. Ds qu'une erreur est traite par un catch les catchs suivants ne sont plus envisags. Exemple :
using System; class Prog { static void Main() { int a = 5,b = 0,c; int[] T = new int[3]; try { Console.WriteLine("Donner un nombre"); c= Int32.Parse(Console.ReadLine()); Console.WriteLine("Avant division et accs au tableau"); T[c]=a/b; Console.WriteLine("Aprs division T["+c+"] vaut "+T[c]); } catch(ArithmeticException) {Console.WriteLine("Erreur sur opration arithmtique");} catch(IndexOutOfRangeException) {Console.WriteLine("Accs au tableau en dehors de ses bornes");} catch(Exception) {Console.WriteLine("Erreur");} Console.WriteLine("Aprs le traitement des erreurs"); } }

Commentaires Trois blocs catch sont associs au try. Le premier bloc gre les erreurs arithmtiques. La classe ArithmeticException est la classe de base de ce type d'erreurs. Voici la liste des classes exceptions qui en drivent :
System.ArithmeticException System.DivideByZeroException (Division par zero) System.NotFiniteNumberException (Valeur relle infinie ou valeur non numrique pour un rel) System.OverflowException (Dpassement de capacit)

Le deuxime bloc gre les erreurs d'accs un tableau en dehors de ses bornes.

50

Karim Kalti

Le troisime bloc gre les autres exceptions pouvant ventuellement avoir lieu. En effet Exception est la classe de base de toutes les exceptions. Donc toute exception ayant chapp aux deux premiers blocs sera obligatoirement intercepte par ce troisime bloc. Remarque : L'ordre des catchs est important surtout si leurs arguments sont des objets qui drivent les uns des autres. Par exemple si les blocs catchs de l'exemple prcdents taient organiss comme ceci :
catch(Exception) {Console.WriteLine("Erreur");} catch(ArithmeticException) // Bloc jamais excut {Console.WriteLine("Erreur sur opration arithmtique");} catch(IndexOutOfRangeException) // Bloc jamais excut {Console.WriteLine("Accs au tableau en dehors de ses bornes");}

Alors les deux derniers blocs ne pourraient jamais tre excuts car toute erreur est de type Exception (toutes les exceptions de type systme ou application drivent de System.Exception). Toute erreur serait de ce fait toujours traite par le premier bloc. Le bloc finally En plus des bloc try et catch, il est possible d'utiliser un troisime bloc optionnel dfini par finally. Les instructions de ce bloc sont toujours excutes quel que soit le droulement de l'excution dans le bloc try (erreur ou pas d'erreur). Le bloc finally est gnralement utilis pour assurer la libration des ressources (fermeture de fichiers, ) et ce en cas de leve d'une exception. Remarque : Un seul bloc finally peut tre associ un bloc try. Les accolades sont obligatoires mme si le bloc comporte une seule instruction. Mcanisme complet de gestion d'exceptions La syntaxe complte d'un mcanisme de gestion d'exception est : try { // Bloc d'instructions du programme } catch(ClasseException e) { // Bloc de gestion de l'erreur } finally { // Bloc toujours excut }

Exemple :
using System; class Prog { static void Main() { try { Console.WriteLine("Dbut du try du Main"); f(); Console.WriteLine("Fin du try du Main"); } catch(Exception) { Console.WriteLine("Erreur"); } }

51

Karim Kalti

static void f() { int a = 5,b,c; int[] T = new int[3]; ... // code de saisie de b et c try {Console.WriteLine("Dbut du try de f"); T[b] = a/c; Console.WriteLine("Fin du try de f"); } finally {Console.WriteLine("finally de f);} } }

Exemples de rsultats d'excution :


Si b= 1 et c=1 Dbut du try du Main Dbut du try de f Fin du try de f Finally de f Fin du try de Main Si b =1 et c=0 Dbut du try du Main Dbut du try de f Finally de f Erreur Si b =5 et c=1 Dbut du try du Main Dbut du try de f Finally de f Erreur

Remarque : Propagation du mcanisme d'interception L'exemple prcdent montre qu'il est possible de ne pas intercepter une erreur la source (absence de catch dans le try de f). En effet suite la gnration d'une exception dans un bloc try, le runtime commence chercher un bloc catch capable de la traiter (en se basant sur le type de l'exception). S'il ne trouve pas un tel bloc dans la fonction appele, la recherche se propage vers la fonction appelante. Ce processus de propagation continu : Jusqu' ce que un catch appropri soit trouv, auquel cas le runtime considre que l'exception t intercepte et il reprend l'excution du programme partir du corps du bloc catch. Jusqu' ce que la fonction Main soit atteinte sans trouver un catch appropri. Dans ce cas le runtime met fin l'excution du programme. Dfinition d'exceptions personnalises En plus des exceptions "systme" qui sont prdfinies, il est possible au programmeur de dfinir ses propres exceptions. Ces dernires sont gnralement d'ordre smantique et dpendent de ce fait du contexte de l'application dveloppe. C'est pourquoi elles sont dites exceptions de type "application". La dfinition d'une exception personnalise passe par la dfinition d'une classe qui drive obligatoirement de la classe Exception. Il suffit gnralement de faire une simple drivation sans ajouter de membres supplmentaires. Il est galement possible d'inclure des attributs supplmentaires qui donneraient des informations utiles quant l'erreur. Leve d'exceptions Contrairement aux exceptions prdfinies o c'est le runtime qui lve automatiquement l'exception, pour les exceptions personnalises cette tche est la charge du programmeur. Elle est assure par l'instruction throw qui prend en argument un objet de la classe reprsentant l'exception. Exemple 1 :
if(minute<1 || minute >=60) { string Erreur = minute + "n'est pas une minute valide"; throw new InvalidTimeException(Erreur); // Partie jamais atteinte }

Exemple 2 :
using System; class MyException : Exception { public MyException(string msg) : base(msg) {} }

52

Karim Kalti

class Prog { static void f(int i) { if(i>10) throw new MyException(i+" est une valeur trop grande"); Console.WriteLine("Fin de la mthode f"); } static void Main() { int i=20; try { f(i); } catch(MyException e) { Console.WriteLine(e.Message); } } }

Principaux membres de la classe System.Exceptions Constructeurs Exception() Constructeur par dfaut Exception(string msg) Constructeur qui initialise l'attribut Message de la classe Exception. Proprits Nom Type Signification HelpLink string Nom de la page Web d'aide associe l'exception. Message string Message d'explication Source string Nom de l'objet ou de l'application ayant gnr l'erreur.

Classes d'exceptions usuelles en C# (ref MSDN) Classe de base pour les exceptions qui se produisent pendant des oprations arithmtiques, telles que
System.DivideByZeroException et System.OverflowException. System.ArrayTypeMismatchException

System.ArithmeticException

System.DivideByZeroException

System.IndexOutOfRangeException

System.InvalidCastException

System.NullReferenceException System.OutOfMemoryException

System.StackOverflowException

System.TypeInitializationException

Leve lorsqu'un stockage dans un tableau choue car le type rel de l'lment stock est incompatible avec le type rel du tableau. Leve l'occasion d'une tentative de division d'une valeur intgrale par zro. Leve lors d'une tentative d'indexation d'un tableau via un index qui est infrieur zro ou en dehors des limites du tableau. Leve lorsqu'une conversion explicite d'une interface ou d'un type de base vers des types drivs choue au moment de l'excution. Leve lorsqu'une rfrence null est utilise d'une manire qui rend obligatoire l'objet rfrenc. Leve par l'chec d'une tentative d'allocation de mmoire (via new). Leve lorsque la pile d'excution est puise par un trop grand nombre d'appels de mthode en attente ; c'est gnralement le signe d'une rcurrence trs profonde ou non lie. Leve lorsqu'un constructeur statique lve une exception, alors qu'il n'existe aucune clause catch pouvant l'intercepter.

53

Karim Kalti

Les IHM en C#
Introduction
Les Interfaces Homme-Machine (IHM) permettent de dvelopper des programmes informatiques dans lesquelles l'interaction entre l'utilisateur et le systme se fait dans un cadre convivial bas essentiellement sur des composants visuels. Le systme d'exploitation Windows donne une bonne illustration de ces interfaces et de leurs composants (Exemples : Fentres, Boites de dialogue, menus, boutons, boutons radio, cases cocher, etc.). En utilisant le .NetFrameWork, il est possible de dvelopper des applications disposant de telles interfaces.

Classes des composants visuels en .NET


Avec le .NetFramework, chaque composant visuel, appel galement contrle, est reprsent par une classe. Ainsi, et titre d'exemple, la classe Button reprsente les boutons, la classe Form reprsente les fentres, etc. Toutes les classes reprsentant les composants visuels font partie de l'espace de noms System.Windows.Forms. Elles drivent toutes de la classe Control. Chaque composant visuel possde : o Un ensemble de caractristiques (Exemple : emplacement, taille, couleur, ). Ces caractristiques sont codes comme des proprits de la classe qui reprsente le composant. Certaines de ces proprits sont en lecture seule, d'autres sont en lecture et en criture. o Un ensemble d'actions qui peuvent lui tre appliques. Ces actions sont codes sous forme de mthodes de la classe qui reprsente le contrle. (Exemple d'actions : la mthode Close de la classe Form permet de fermer une fentre). o Un ensemble d'vnements qu'il peut traiter. Ces vnements sont signals l'aide de messages envoys par Windows. Les fonctions de traitement de ces vnements sont codes sous forme de mthodes de la classe qui reprsente le composant. Ces mthodes doivent tre ajoutes aux dlgus responsables de la gestion des vnements.

La classe Form
Cette classe reprsente une fentre. Hirarchie :
System.Object System.MarshalByRefObject System.ComponentModel.Component System.Windows.Forms.Control System.Windows.Forms.ScrollableControl System.Windows.Forms.ContainerControl System.Windows.Forms.Form

Constructeur : public Form();

54

Karim Kalti

Quelques proprits : Proprit


AllowDrop

Type
bool

Description
Si vrai, la fentre pourra jouer le rle de destination dans une opration Drag&Drop. Si la valeur est true alors des barres de dfilement (scrollbar) sont automatiquement affiches lorsque la fentre devient trop rduite pour que tous les composants soient visibles. Si la valeur est false alors les barres de dfilement ne sont jamais affiches. Couleur d'arrire plan de la fentre. Image de fond de la fentre. Il est possible de spcifier une image au format bmp, gif, jpg ou ico. Cette image sera greffe dans l'excutable du programme. L'image ainsi spcifie est rpte autant de fois que ncessaire pour remplir toute la fentre. Forme que prend le curseur de la souris lorsqu'il survole la fentre. Couleur d'affichage du texte. Position du coin suprieur gauche de la fentre. Nom du menu associ la fentre Taille de la fentre. Size reprsente deux champs: Width et Height. Ces champs sont exprims en nombre de pixels. Reprsente le texte qui sera affich dans la barre de titre de la fentre. Nom interne de la fentre.

AutoScroll BackColor BackGroundImage Cursor ForeColor Location Menu Size Text Name

bool enum Color

enum Cursors enum Color Objet Point Objet MainMenu Objet Size String String

Quelques mthodes : Mthode


void BringToFront() Void Close() Void Show( ) Amne la fentre l'avant-plan. Ferme la fentre Fait apparatre la fentre.

Description

Quelques vnements : Evnement


BackColorChanged (hrit de Control) Click (hrit de Control) Closed Closing GotFocus (hrit de Control) LostFocus (hrit de Control) KeyDown (hrit de Control) KeyPress (hrit de Control) KeyUp (hrit de Control) Load

Description
Se produit lorsque la valeur de la proprit BackColor change. Se produit suite un clic sur le contrle (la fentre dans ce cas). Se produit lorsque le formulaire est ferm. Se produit pendant la fermeture du formulaire. Se produit lorsque le contrle reoit le focus. Se produit lorsque le contrle perd le focus. Se produit lorsqu'une touche est enfonce alors que le contrle a le focus. Se produit lorsqu'une touche est enfonce alors que le contrle a le focus. Se produit lorsqu'une touche est relche alors que le contrle a le focus. Se produit avant le premier affichage d'un formulaire.

Programme 1 using System; using System.Windows.Forms; namespace ApplicationTest { public class Exemple { static void Main( ) { Form fiche = new Form( ); fiche.Text="Exemple de Form"; fiche.BackColor=System.Drawing.Color.RosyBrown; fiche.Show( ); } } }

Rsultat : la fentre disparat aussi vite qu'elle est apparue.

55

Karim Kalti

Explication des tapes de l'excution : Ligne d'instruction du programme { Form MaFentre = new Form( ); MaFentre.Show(); } Que fait le CLR Initialisation de l'excution de la mthode main Instanciation d'une fentre nomme MaFentre Affichage de MaFentre. Terminaison du processus.

La mthode Show de la classe Form affiche la fentre. Cet affichage va persister durant l'excution du Main. Ds que l'accolade fermante du Main est atteinte, le programme se termine et la fentre disparat en mme temps. La fugacit de l'affichage de l'exemple prcdent est due en fait l'absence d'instructions aprs la mthode Show. Pour remdier cela, il est possible d'ajouter une instruction qui bloque l'excution (Exemple : Console.Read();)
static void Main() { char a; Form MaFentre = new Form(); MaFentre.Show(); a=Console.Read(); }

Le blocage de l'excution avec la mthode Read, mme s'il rsout le problme de la fugacit de l'affichage reste inappropri pour le dveloppement d'application avec IHM. En effet, dans ce cas, et tout juste aprs l'instruction MaFentre.Show(), le programme passe directement l'instruction a=Console.Read()et attend la saisie d'un caractre. Toute autre action peut bloquer son excution et il devient dans ce cas difficile d'interagir avec la Fentre. Pour viter ce problme, il vaut mieux utiliser une boucle l'intrieur du Main dont le rle sera d'intercepter les vnements engendrs par le systme ou par l'interaction de l'utilisateur avec l'application. Cette boucle permettra entre autres d'viter d'atteindre la fin de l'application tant qu'un message d'arrt n'a pas t intercept. Elle assurera par la mme occasion une persistance de l'affichage des interfaces graphiques. Le .NET framework implmente une telle boucle et ce dans la classe Application. Le lancement de cette boucle se fait l'aide de la mthode Run. Exemple :
static void Main() { Form MaFentre = new Form(); MaFentre.Show(); Application.Run(); }

La mthode Run excute une boucle de messages d'application sur le thread en cours (processus associ l'application en cours d'excution). La structure de la boucle peut tre vue comme suit : tantque non ArrtSysteme faire si vnement alors Construire Message ; si Message ArrtSysteme alors Reconnatre le composant auquel est destin ce Message; Distribuer ce Message fsi fsi ftant

Autres surcharges de Run La mthode Run possde deux autres surcharges. La surcharge la plus utilise est celle qui prend en argument un objet de la classe Form et qui l'affiche. Cet objet reprsente gnralement la fentre principale de l'application. Prototype : public static void Run(Form);

56

Karim Kalti

Deuxime programme :
Programme 2 using System; using System.Windows.Forms; namespace Application { class PremierWinProg { static void Main() { Form MaFentre = new Form(); Application.Run(MaFentre); } } }

Rsultat de l'excution du programme 2 :

Remarques : Une seule boucle de messages est gnralement associe une application. Elle est lance avec la mthode Run. La surcharge la plus utilise de Run est celle qui prend en argument la fentre principale de l'application. Si l'application contient d'autres fentres, alors leur affichage sera fait travers leurs propres mthodes Show et non travers Application.Run comme c'est le cas pour la fentre principale.

Utilisation d'un RAD pour la gnration du code : Les environnements de dveloppement en C#.NET permettent de dvelopper de grandes parties des applications l'aide des assistants visuels. Ils gnrent galement d'une manire automatique le code correspondant aux parties ainsi dveloppes. Le programme suivant reprsente le code gnr pour un projet minimal affichant seulement un formulaire vide.
Programme 3 using System; using System.Windows.Forms; namespace DefaultNamespace { public class MainForm : System.Windows.Forms.Form { public MainForm() { InitializeComponent(); } public static void Main() {Application.Run(new MainForm());} private void InitializeComponent() {// Form1 this.ClientSize= new System.Drawing.Size(292, 266); this.Text = "MainForm"; this.Name = "MainForm"; } } }

57

Karim Kalti

Commentaires : La mthode InitialiazeComponent contient tout le code ncessaire linitialisation du formulaire et ventuellement ses composants. Cette mthode est gnre par le RAD. Elle est par la suite appele dans le constructeur de la fentre de base de lapplication. Il est possible dajouter dautres instructions dinitialisation dans la mthode InitailizeComponent ou directement dans le constructeur de la fentre.

La classe Button
Cette classe reprsente les boutons de commande. Hirarchie :
System.Object System.MarshalByRefObject System.ComponentModel.Component System.Windows.Forms.Control System.Windows.Forms.ButtonBase System.Windows.Forms.Button

Constructeur : public Button();

Quelques proprits : Proprit


BackColor Cursor Enabled (hrit de Control) Font (hrit de Control) FlatStyle ForeColor Image Location Name TabIndex (hrit de Control) TabStop (hrit de Control) Size Text Visible (hrit de Control)

Type
enum Color enum Cursors bool Font enum FlatStyle enum Color Image Point String int bool Size String bool

Description
Couleur d'arrire plan du bouton. Forme que prend le curseur de la souris lorsqu'il survole le bouton. Obtient ou dfinit une valeur indiquant si un contrle peut rpondre une interaction utilisateur. Obtient ou dfinit la police du texte affich par le contrle. Obtient ou dfinit le style deux dimensions (flat) du contrle bouton. Couleur d'affichage du texte. Image d'avant plan. Position du coin suprieur gauche du bouton. Nom interne du bouton. Obtient ou dfinit l'ordre de tabulation du contrle dans son conteneur. Obtient ou dfinit une valeur indiquant si l'utilisateur peut octroyer le focus ce contrle l'aide de la touche TAB. Taille du bouton. Size reprsente deux champs: Width et Height. Ces champs sont exprims en nombre de pixels. Reprsente le texte qui sera affich sur le bouton. Obtient ou dfinit une valeur indiquant si le contrle est affich.

Quelques mthodes : Mthode


void void Void Void Hide() scale(float,float) select() Show( )

Description
Masque le bouton l'utilisateur. Dimensionne le contrle et ses contrles enfants. Surcharge. Active un contrle. Affiche le bouton l'utilisateur.

58

Karim Kalti

Quelques vnements : Evnement


BackColorChanged (hrit de Control) Click (hrit de Control) GotFocus (hrit de Control) LostFocus (hrit de Control) KeyDown (hrit de Control) KeyPress (hrit de Control) KeyUp (hrit de Control)
Programme 4 using System; using System.Drawing; using System.Collections; using System.ComponentModel; using System.Windows.Forms; namespace WindowsApplication3 { public class Form1 : System.Windows.Forms.Form {private System.Windows.Forms.Button button1; public Form1() {InitializeComponent();} #region Windows Form Designer generated code private void InitializeComponent() { this.button1 = new System.Windows.Forms.Button(); this.SuspendLayout(); // button1 this.button1.Location = new System.Drawing.Point(70,40); this.button1.Name = "button1"; this.button1.Size = new System.Drawing.Size(64, 24); this.button1.TabIndex = 0; this.button1.Text = "Message"; // Form1 this.ClientSize = new System.Drawing.Size(200, 100); this.Controls.Add(this.button1); this.Name = "Form1"; this.Text = "Form1"; this.ResumeLayout(false); } #endregion static void Main() {Application.Run(new Form1());} } }

Description
Se produit lorsque la valeur de la proprit BackColor change. Se produit suite un clic sur le contrle. Se produit lorsque le contrle reoit le focus. Se produit lorsque le contrle perd le focus. Se produit lorsqu'une touche est enfonce alors que le contrle a le focus. Se produit lorsqu'une touche est enfonce alors que le contrle a le focus. Se produit lorsqu'une touche est relche alors que le contrle a le focus.

Rsultat de l'excution du programme 4 :

59

Karim Kalti

La classe Label
Cette classe reprsente une zone d'affichage de texte. Les contrles Label sont gnralement utiliss pour fournir un texte descriptif un contrle. Par exemple, il est possible d'utiliser Label pour ajouter un texte descriptif un contrle TextBox afin d'informer l'utilisateur du type des donnes attendues dans le contrle. Le contrle Label peut galement tre utilis pour ajouter un texte descriptif un Form afin de fournir des informations utiles l'utilisateur. Par exemple, il est possible d'ajouter un Label au dbut d'un Form qui fournit des instructions l'utilisateur sur la faon de faire entrer des donns dans les contrles du formulaire. Le contrle Label peut galement tre utilis pour afficher des informations sur l'tat d'une application au moment de l'excution. Hirarchie :
System.Object System.MarshalByRefObject System.ComponentModel.Component System.Windows.Forms.Control System.Windows.Forms.Label

Constructeur : public Label();

Quelques proprits : Proprit


BackColor BorderStyle Cursor Enabled Font FlatStyle ForeColor Image Location Name TabIndex TabStop Size Text Visible

Type
enum Color enum BorderStyle enum Cursors bool Font enum FlatStyle enum Color Image Point string int bool Size string bool

Description
Couleur d'arrire plan du Label. Obtient ou dfinit le style de bordure du Label. Forme que prend le curseur de la souris lorsqu'il survole le Label. Obtient ou dfinit une valeur indiquant si le Label peut rpondre une interaction avec l'utilisateur. Obtient ou dfinit la police du texte affich par le Label. Obtient ou dfinit le style deux dimensions (flat) du contrle Label. Couleur d'affichage du texte. Image d'avant plan. Position du coin suprieur gauche du contrle Label Nom interne du Label. Obtient ou dfinit l'ordre de tabulation du contrle dans son conteneur. Obtient ou dfinit une valeur indiquant si l'utilisateur peut octroyer le focus ce contrle l'aide de la touche TAB. Taille du contrle Label. Size reprsente deux champs: Width et Height. Ces champs sont exprims en nombre de pixels. Reprsente le texte qui sera affich par le Label. Obtient ou dfinit une valeur indiquant si le contrle Label est affich.

Quelques mthodes : Mthode


void void Void Void Hide() scale(float,float) select() Show( )

Description
Masque le label l'utilisateur. Surcharge. Dimensionne le contrle Label et ses contrles enfants. Surcharge. Active un contrle Label. Affiche le contrle Label l'utilisateur.

Quelques vnements : Un label peut traiter la majorit des vnements associs la classe contrle. Toutefois, sur le plan pratique il est trs rare de grer ces vnements.

60

Karim Kalti

La classe TextBox
Le contrle TextBox reprsente les zones d'dition. Il permet d'entrer du texte dans une application. Il a t enrichi de fonctionnalits absentes du contrle zone de texte Windows standard, dont la modification multiligne et le masquage des caractres d'un mot de passe.

Hirarchie :
System.Object System.MarshalByRefObject System.ComponentModel.Component System.Windows.Forms.Control System.Windows.Forms.TextBoxBase System.Windows.Forms.TextBox

Constructeur : public TextBox();

Quelques proprits : Proprit


AcceptsReturn BackColor BorderStyle Cursor Enabled Font ForeColor Location Name MaxLength Multiline PasswordChar ReadOnly RightToLeft TabIndex TabStop Size Text Visible

Type
bool enum Color enum BorderStyle enum Cursors bool Objet Font enum Color Point string int bool char bool bool int bool Objet Size string bool

Description
Obtient ou dfinit une valeur indiquant si le fait d'appuyer sur la touche ENTRE dans un contrle TextBox multiligne entrane la cration d'une nouvelle ligne de texte dans le contrle ou bien l'activation du bouton par dfaut sur le formulaire. Couleur d'arrire plan du contrle TextBox. Obtient ou dfinit le type des bordures du contrle zone de texte. Forme que prend le curseur de la souris lorsqu'il survole le contrle TextBox. Obtient ou dfinit une valeur indiquant si un contrle peut rpondre une interaction utilisateur. Obtient ou dfinit la police du texte affich par le contrle TextBox. Couleur d'affichage du texte. Position du coin suprieur gauche du contrle TextBox. Nom interne du contrle TextBox. Obtient ou dfinit le nombre maximal de caractres que l'utilisateur peut taper dans le contrle zone de texte. Obtient ou dfinit une valeur indiquant si ce contrle est un contrle zone de texte multiligne. Obtient ou dfinit le caractre servant masquer les caractres d'un mot de passe dans un contrle TextBox monoligne. Obtient ou dfinit une valeur indiquant si le texte de la zone de texte est en lecture seule. Obtient ou dfinit une valeur indiquant si les lments du contrle sont aligns pour prendre en charge les paramtres rgionaux utilisant des polices de droite gauche (comme l'arabe). Obtient ou dfinit l'ordre de tabulation du contrle dans son conteneur. Obtient ou dfinit une valeur indiquant si l'utilisateur peut octroyer le focus ce contrle l'aide de la touche TAB. Taille du contrle TextBox. Size reprsente deux champs: Width et Height. Ces champs sont exprims en nombre de pixels. Reprsente le texte qui sera affich par le contrle TextBox. Obtient ou dfinit une valeur indiquant si le contrle est affich.

61

Karim Kalti

Quelques mthodes : Mthode


void Clear(); void Copy(); void Cut(); void Paste(); void Undo() void Select(int start,int length) void SelectAll() void Hide() void Show( )

Description
Efface tout le texte du contrle zone de texte. Copie la slection active dans la zone de texte vers le Presse-papiers. Dplace la slection active entre la zone de texte et le Presse-papiers. Remplace la slection active de la zone de texte par le contenu du Presse-papiers. Annule la dernire modification apporte dans la zone de texte. Slectionne le texte qui commence depuis le caractre d'indice start et qui s'tend sur length caractre. Slectionne tout le texte du contrle. Masque la zone de texte l'utilisateur. Affiche le contrle TextBox l'utilisateur.

Exemple d'criture du contenu d'un Label Label Lb = new Label(); Lb.text = "Premier message"; Exemple de lecture du contenu dune zone ddition TextBox TB = new TextBox(); String s = TB.text ; Exemple montrant comment vider le contenu dune zone ddition TB.text = ""; ou TB.Clear() ;
Programme 5 : Exemple d'utilisation des contrles TextBox et Label using using using using using System; System.Drawing; System.Collections; System.ComponentModel; System.Windows.Forms;

public class Form1 : System.Windows.Forms.Form {private System.Windows.Forms.Label label1; private System.Windows.Forms.TextBox textBox1; public Form1() {InitializeComponent();} private void InitializeComponent() {this.label1 = new System.Windows.Forms.Label(); this.textBox1=new System.Windows.Forms.TextBox(); this.SuspendLayout(); // label1 this.label1.Location = new System.Drawing.Point(24, 24); this.label1.Name = "label1"; this.label1.Size = new System.Drawing.Size(72, 24); this.label1.TabIndex = 0; this.label1.Text = "Nom"; // textBox1 this.textBox1.Location =new System.Drawing.Point(88, 24); this.textBox1.Name = "textBox1"; this.textBox1.Size = new System.Drawing.Size(112, 20); this.textBox1.TabIndex = 1; this.textBox1.Text = ""; // Form1 this.ClientSize = new System.Drawing.Size(250, 100); this.Controls.Add(this.textBox1); this.Controls.Add(this.label1); this.Name = "Form1"; this.Text = "Form1"; this.ResumeLayout(false); } static void Main() {Application.Run(new Form1());} }

62

Karim Kalti

Rsultat de l'excution du programme 5 :

La classe CheckBox
Cette classe reprsente un contrle case cocher. Ce contrle permet de prsenter l'utilisateur la possibilit de slectionner ou non un choix. Une case cocher est gnralement accompagne d'un texte expliquant le choix faire. Un contrle case cocher peut avoir trois tats : non coch, coch, estomp. Un contrle case cocher peut tre utilis seul ou en groupe. Il est possible de regrouper thmatiquement des cases cocher dans un GroupBox. Ceci permet de faciliter leur manipulation (dplacement et positionnement) et permet l'utilisateur de faire des choix (non exclusifs) concernant le thme du groupe. Hirarchie :
System.Object System.MarshalByRefObject System.ComponentModel.Component System.Windows.Forms.Control System.Windows.Forms.ButtonBase System.Windows.Forms.CheckBox

Constructeur : public

CheckBox();

Quelques proprits : Proprit Type


Appearance enum Appearance bool bool enum CheckState

Description
Indique l'apparence de la case cocher. Les valeurs possibles de l'numration Appearance sont : Button (la case prend la forme d'un petit bouton) et Normal (la case prend sa forme normale). Indique si la case change automatiquement d'tat suite un clic sur la case. Si AutoCheck vaut false, c'est alors au programmeur de grer l'tat de la case en traitant l'vnement Click. Indique l'tat (coch ou non) d'une case deux tats. Pour les contrles trois tats la proprit Checked retourne true pour les deux tats Checked et Intermediate. Etat d'une case trois tats. CheckState prend l'une des trois valeurs suivantes de l'numration CheckState (Checked, Unchecked, Indeterminate). Indeterminate correspond une case estompe (grise ). Indique si la case est deux ou trois tats : false : correspond une case deux tats. Elle peut tre coche (Checked) ou non coche (Unchecked). Cet tat est contrl par la proprit Checked. true : correspond une case trois tats. (coch, non coch, estomp). Cet tat est contrl par la proprit CheckState. Libell de la case. Le caractre & sert spcifier un acclrateur. ALT+Acclrateur permet de changer l'tat de la case. Obtient ou dfinit une valeur indiquant si le contrle peut rpondre une interaction utilisateur. Position du coin suprieur gauche du contrle case cocher. Nom interne du contrle case cocher. Obtient ou dfinit l'ordre de tabulation du contrle dans son conteneur. Obtient ou dfinit une valeur indiquant si l'utilisateur peut octroyer le focus ce contrle l'aide de la touche TAB. Obtient ou dfinit une valeur indiquant si le contrle est affich.

AutoCheck Checked CheckState

ThreeState

bool

Text Enabled Location Name TabIndex TabStop Visible

string bool Point string int bool bool

63

Karim Kalti

Quelques mthodes : Mthode


void Hide() Void Show( ) Masque le contrle l'utilisateur. Affiche le contrle l'utilisateur.

Description

Quelques vnements : Evnement


Click (hrit de Control) CheckedChanged CheckedStateChanged

Description
Se produit suite un clic sur le contrle. Il est gnralement gr lorsque la proprit AutoChek est gale false. Se produit suite au changement d'tat d'une case deux tats. Se produit suite au changement d'tat d'une case trois tats.

Exemple d'interface comportant des cases cocher

Exemple 1 : Code de cration du contrle CheckBox "Service 1"


// Dans la liste des attributs du formulaire il faut ajouter private System.Windows.Forms.CheckBox checkBox1; // Dans le code d'initialisation du formulaire il faut mettre this.checkBox1 = new System.Windows.Forms.CheckBox(); this.checkBox1.Location = new System.Drawing.Point(48, 32); this.checkBox1.Name = "checkBox1"; this.checkBox1.Size = new System.Drawing.Size(176, 16); this.checkBox1.TabIndex = 1; this.checkBox1.Text = " Service 1";

Exemple 2 : Code de traitement d'un clic sur le contrle CheckBox "Service 1" Pour un contrle trois tats :
private void checkBox1_Click(object sender, System.EventArgs e) { switch(checkBox1.CheckState) { case CheckState.Checked: // Mettre ici le code pour l'tat checked. break; case CheckState.Unchecked: // Mettre ici le code pour l'tat unchecked. break; case CheckState.Indeterminate: // Mettre ici le code pour l'tat intermediate. break; } }

64

Karim Kalti

La classe RadioButton
La classe RadioButton reprsente un contrle bouton radio. Les contrles boutons radio reprsentent un ensemble de choix mutuellement exclusifs. Ils s'utilisent essentiellement en groupe et permettent alors l'utilisateur de slectionner une option parmi plusieurs. Le contrle bouton possde quelques exceptions prs les mmes caractristiques que le contrle case cocher, toutefois : o Dans un groupe de boutons radio, une et une seule option peut tre slectionne alors que dans un groupe de cases cocher, il est possible de slectionner autant d'options que voulues. o Un contrle bouton radio ne possde que deux tats possibles (Checked et Unchecked). Il n'a pas comme pour les cases cocher un tat estomp.

Hirarchie :
System.Object System.MarshalByRefObject System.ComponentModel.Component System.Windows.Forms.Control System.Windows.Forms.ButtonBase System.Windows.Forms.RadioButton

Constructeur : public Quelques proprits : Proprit


Appearance

RadioButton();

Type
Enum Appearance bool bool string bool Point string int bool bool

Description
Indique l'apparence de la case cocher. Les valeurs possibles de l'numration Appearance sont : Button (la case prend la forme d'un petit bouton) et Normal (la case prend sa forme normale). Indique si le bouton radio change automatiquement d'tat suite un clic. Si AutoCheck vaut false, c'est alors au programmeur de grer l'tat de la case en traitant l'vnement Click. Indique l'tat (coch ou non) du bouton. Libell du bouton radio. Le caractre & sert spcifier un acclrateur. ALT+Acclrateur permet de changer l'tat du bouton. Obtient ou dfinit une valeur indiquant si le contrle peut rpondre une interaction utilisateur. Position du coin suprieur gauche du contrle bouton radio. Nom interne du contrle bouton radio. Obtient ou dfinit l'ordre de tabulation du contrle dans son conteneur. Obtient ou dfinit une valeur indiquant si l'utilisateur peut octroyer le focus ce contrle l'aide de la touche TAB. Obtient ou dfinit une valeur indiquant si le contrle est affich.

AutoCheck Checked Text Enabled Location Name TabIndex TabStop Visible

Quelques mthodes : Mthode


void Hide() Void Show( ) Masque le contrle l'utilisateur. Affiche le contrle l'utilisateur.

Description

Quelques vnements : Avec le contrle bouton radio, seul l'vnement CheckedChanged prsente de l'intrt. Il est signal lorsqu'un bouton radio change d'tat. Evnement
Click (hrit de Control) CheckedChanged

Description
Se produit suite un clic sur le contrle. Il est gnralement gr lorsque la proprit AutoCheck vaut false. Se produit suite au changement d'tat du bouton radio.

65

Karim Kalti

La classe GroupBox
Cette classe reprsente un contrle groupe. Ce contrle est un conteneur qui permet de regrouper logiquement un ensemble de contrles de n'importe quel type. Les groupes sont gnralement utiliss pour regrouper des contrles de type "bouton radio". Les boutons radio d'un groupe sont mutuellement exclusifs. Des boutons radio appartenant un mme formulaire mais faisant partie de deux groupes diffrents fonctionnent de manire compltement indpendante. Hirarchie :
System.Object System.MarshalByRefObject System.ComponentModel.Component System.Windows.Forms.Control System.Windows.Forms.GroupBox

Constructeur : public

GroupBox()

Quelques proprits : Outre les proprits hrites des classes de base et prsentes dans les paragraphes prcdents : Texte, Enabled, Location, Name, TabIndex, TabStop, Visible, etc, le contrle GroupBox possde une autre proprit intressante qui est Controls. Proprit
Controls

Type
ControlCollection

Description
C'est une collection qui comporte les contrles contenus dans le groupe.

Remarque : Comme toute collection, ControlCollection possde les mthodes usuelles Add, AddRange, Remove, RemoveAt, Cleat, Contains, IndexOf.

Quelques mthodes : Mthode


void Hide() Void Show( ) Masque le contrle l'utilisateur. Affiche le contrle l'utilisateur.

Description

Quelques vnements : Le GroupBox gre les vnements grs par les classes de base (click, etc), toutefois la gestion des vnements au niveau de ce contrle reste rare sur le plan pratique.

Exemple d'interface comportant des boutons radio

66

Karim Kalti

Exemple 1 : Code de cration du groupe "Options" et du bouton radio "Option 1"


// Dans la liste des attributs du formulaire il faut ajouter // un groupebox et le contrle radioButton 1. private System.Windows.Forms.GroupBox groupBox1; private System.Windows.Forms.RadioButton radioButton1; // Dans le code d'initialisation du formulaire il faut mettre // Code de cration du groupe box this.groupBox1 = new System.Windows.Forms.GroupBox(); this.groupBox1.Location = new System.Drawing.Point(16, 24); this.groupBox1.Name = "groupBox1"; this.groupBox1.Size = new System.Drawing.Size(224, 72); this.groupBox1.TabIndex = 6; this.groupBox1.TabStop = false; this.groupBox1.Text = "Options"; // Code de cration du bouton radio this.radioButton1 = new System.Windows.Forms.RadioButton(); this.radioButton1.Location = new System.Drawing.Point(24, 16); this.radioButton1.Name = "radioButton1"; this.radioButton1.Size = new System.Drawing.Size(72, 16); this.radioButton1.TabIndex = 0; this.radioButton1.Text = "Option 1"; // Ajout du bouton radio la liste des contrles du groupe this.groupBox1.Controls.Add(this.radioButton1);

Exemple 2 : Dtermination du bouton radio slectionn dans un groupe


RadioButton rb = null; for(int i=0,i<groupBox1.Controls.Count;i++) { rb=(RadioButton) groupBox1.Controls[i]; // On sort ds qu'on trouve le bouton slectionn if(rb.Checked) break; }

La classe ListBox
Cette classe reprsente une bote de liste d'articles. Ce contrle sert oprer une slection d'un ou de plusieurs articles partir de la liste. Hirarchie :
System.Object System.MarshalByRefObject System.ComponentModel.Component System.Windows.Forms.Control System.Windows.Forms.ListControl System.Windows.Forms.ListBox

Constructeur : public Quelques proprits :

ListBox();

Proprit
BorderStyle

Type
enum BorderStyle

Description
Type de contour. Les valeurs possibles sont None (aucun contour), FixedSingle (Contour form d'une simple ligne), Fixed3D (contour avec effet de relief). Indique la manire d'affichage de la liste. Les valeurs possibles de cette proprit sont : Normal (Affichage automatique, tous les articles ayant la mme hauteur), OwnerDrawFixed (bote de liste dont tous les articles ont la mme taille), OwnerDrawVariable (bote de liste dont tous les articles non pas la mme taille cause de l'utilisation de police de caractre diffrente par exemple). Indique si une barre de dfilement horizontale doit tre automatiquement ajoute si ncessaire. Hauteur d'un article. Par dfaut, la hauteur d'un article est de 13 pixels. Cette valeur est utilise dans le cas ou DrawMode prend la valeur OwnerDrawFixed.

DrawMode

enum DrawMode

HorizontalScrollBar ItemHeight

bool int

67

Karim Kalti

Items ScrollAlwaysVisible

Collection de Items bool enum SelectionMode bool

Collection de libells d'articles. La valeur true force la barre de dfilement verticale tre affiche mme si tous les articles sont visibles. Mode de slection des articles. Les valeurs possibles sont : One (un seul article peut tre slectionn), None (aucun article ne peut tre slectionn), MultiSimple (Chaque clic slectionne un article supplmentaire), MultiExtended (slection multiple par les combinaisons avec MAJ et CTRL). Indique si les articles de la bote de liste doivent tre tris par ordre alphabtique.

SelectionMode

Sorted

Quelques proprits runtime : Proprit


SelectedIndex SelectedIndices SelectedItem SelectedItems

Type
int SelectedIndex Collection Object SelectedObject Collection

Description
Index de l'article slectionn. (0 pour le premier). La valeur -1 indique qu'aucun article n'est slectionn. Collection d'indices des articles slectionns. Article slectionn. Cet article peut tre de n'importe quel type, il est toutefois dans la majorit des cas de type string. Collection d'articles slectionns.

Quelques mthodes : Mthode


void ClearSelected() int FindString(string) bool GetSelected(int Index) void SetSelected(int Index, bool Value)

Description
Dslectionne tous les articles slectionns. Renvoie l'index du premier article qui commence par la chane passe en argument. Indique si l'article dont l'index est pass en argument est slectionn ou non. Slectionne (Value=true) ou dslectionne (Value=false) l'article dont l'index est pass en argument.

Quelques vnements : Les vnements les plus souvent traits par les botes de liste sont : Click et DoubleClick : pour dtecter un clic ou un double-clic sur un article. KeyPress : gnralement pour dtecter une frappe de ENTREE sur un article slectionn. SelectedIndexChanged : pour dtecter le passage d'un article l'autre (par clic sur un article ou par les touches de direction du clavier).

Exemple d'interface comportant une bote de liste

68

Karim Kalti

Exemple 1 : Code de cration de la liste


// Dans la liste des attributs du formulaire il faut ajouter private System.Windows.Forms.ListBox listBox1; // Dans le code d'initialisation du formulaire il faut mettre this.listBox1 = new System.Windows.Forms.ListBox(); this.listBox1.Items.AddRange(new object[] {"Sousse","Monastir","Mahdia","Kairouan"}); this.listBox1.Location = new System.Drawing.Point(40, 32); this.listBox1.Name = "listBox1"; this.listBox1.Size = new System.Drawing.Size(120, 43); this.listBox1.TabIndex = 7;

Exemple 2 : L'exemple suivant suppose l'existence de deux listes listBox1 et listBox2. Suite la slection d'un article dans la premire liste, le programme le rcupre et cherche sa prsence dans la deuxime liste. Si cet article est prsent alors il sera galement slectionn dans la deuxime liste, sinon un message indiquant sont absence sera affich.
private void listBox1_SelectedIndexChanged(object sender, System.EventArgs e) { string ArticleCourant = listBox1.SelectedItem.ToString(); int index = listBox2.FindString(ArticleCourant); if(index == -1) MessageBox.Show("l'article est absent de la liste 2"); else listBox2.SetSelected(index,true); }

69

Karim Kalti

IHM et gestion des vnements


Les vnements jouent un rle trs important dans les applications utilisant les IHM. Ils influent en effet sur l'organisation du code dans de telles applications. Ainsi, et la diffrence des applications de type console dans lesquelles la fonction principale (main) dtermine le droulement de l'excution du programme vu qu'elle contient les appels explicites aux fonctions constituant l'application, dans les applications utilisant les IHM l'criture du code suit une autre organisation qui est plutt oriente vnement (Programmation vnementielle). Dans une telle organisation, le rle de la fonction Main se rduit l'invocation de la boucle de dtection des vnements et de dispatching des messages rsultant, vers les contrles composant l'IHM. Il n'y a plus donc d'appels explicites des fonctions constituant l'application dans le Main. Ces dernires sont plutt codes sous forme de fonctions de traitement des vnements intercepts. titre d'exemple, si on veut effectuer une action A suite au clic sur un bouton B, il suffit de mettre le code correspondant A dans une fonction F et de signaler F comme tant une fonction de traitement de l'vnement Click associ B. Pour pouvoir faire de la programmation vnementielle en .NET, il faut connatre : La liste des vnements pouvant tre intercepts. Le type dlgu associ chaque type d'vnements et ce afin de pouvoir traiter ces derniers.

Les vnements lis la souris


Les vnements lis la souris sont nombreux. Parmi les vnements les plus importants de cette catgorie il est possible de citer : MouseDown : signale un enfoncement du bouton de la souris. MouseUp : relachement du bouton de la souris. MouseMove : Dplacement de la souris. MouseEnter : Entre de survol. MouseLeave : Sortie de survol MouseHover : la souris marque un court temps darrt.

Il existe galement deux autres vnements trs frquemment utiliss qui sont Click et DoubleClick. La diffrence entre ces deux vnements d'une part et MouseDown ainsi que MouseUp d'autre part rside essentiellement dans les informations qui accompagnent l'occurrence de ces vnements.

L'vnement Click
Cet vnement a lieu lorsqu'un clic survient sur un contrle. Le contrle peut tre un objet de n'importe quel classe drive de la classe Control du .NetFrameWork (Exemple : Form, Button, TextBox, Label,). Evnement : public event EventHandler Click; Type dlgu : public delegate void EventHandler(Object sender, EventArgs e);

Exemple de traitement de l'vnement Click associ un bouton


Programme 1 using System; using System.Drawing; using System.Collections; using System.ComponentModel; using System.Windows.Forms; namespace WindowsApplication3 { public class Form1 : System.Windows.Forms.Form {private System.Windows.Forms.Button button1; public Form1() {InitializeComponent();} #region Windows Form Designer generated code private void InitializeComponent() { this.button1 = new System.Windows.Forms.Button();

70

Karim Kalti

this.SuspendLayout(); // button1 this.button1.Location = new System.Drawing.Point(96,40); this.button1.Name = "button1"; this.button1.Size = new System.Drawing.Size(64, 24); this.button1.TabIndex = 0; this.button1.Text = "Message"; this.button1.Click+=new EventHandler(this.FTButton); // Form1 this.ClientSize = new System.Drawing.Size(292, 266); this.Controls.Add(this.button1); this.Name = "Form1"; this.Text = "Form1"; this.ResumeLayout(false); } #endregion void FTButton(Object sender, EventArgs e) {if(this.button1.Text=="Message1") this.button1.Text="Message2"; else this.button1.Text="Message1"; } static void Main() {Application.Run(new Form1());} }} Programme 2 : une autre criture du programme 1 namespace WindowsApplication3 { public class MyBt : Button { public MyBt() {// button1 this.Location = new System.Drawing.Point(96, 40); this.Name = "button1"; this.Size = new System.Drawing.Size(64, 24); this.TabIndex = 0; this.Text = "button1"; this.Click+= new EventHandler(this.FTButton); } void FTButton(Object sender, EventArgs e) { if(this.Text=="Message1") this.Text="Message2"; else this.Text="Message1"; }} public class Form1 : System.Windows.Forms.Form {private MyBt button1; public Form1() {InitializeComponent();} #region Windows Form Designer generated code private void InitializeComponent() { this.button1 = new MyBt(); this.SuspendLayout(); // Form1 this.ClientSize = new System.Drawing.Size(292, 266); this.Controls.Add(this.button1); this.Name = "Form1"; this.Text = "Form1"; this.ResumeLayout(false); } #endregion static void Main() {Application.Run(new Form1());} }}

Programme 3 : Traitement de deux vnements par une seule fonction public class Form2 : System.Windows.Forms.Form {private System.Windows.Forms.Button button1; private System.Windows.Forms.Button button2; public Form2() {InitializeComponent();} private void InitializeComponent()

71

Karim Kalti

{this.button1 = new System.Windows.Forms.Button(); this.button2 = new System.Windows.Forms.Button(); this.SuspendLayout(); // button1 this.button1.Location = new System.Drawing.Point(48, 48); this.button1.Name = "button1"; this.button1.Size = new System.Drawing.Size(80, 24); this.button1.TabIndex = 0; this.button1.Text = "button1"; this.button1.Click+=new EventHandler(this.FT); // button2 this.button2.Location=new System.Drawing.Point(144, 48); this.button2.Name = "button2"; this.button2.Size = new System.Drawing.Size(80, 24); this.button2.TabIndex = 1; this.button2.Text = "button2"; this.button2.Click+=new EventHandler(this.FT); // Form2 this.ClientSize = new System.Drawing.Size(272, 117); this.Controls.Add(this.button2); this.Controls.Add(this.button1); this.Name = "Form2"; this.Text = "Form2"; this.ResumeLayout(false); } void FT(Object sender, EventArgs e) { if(sender == this.button1) this.Text="Bouton1 est cliqu"; if(sender == this.button2) this.Text="Bouton2 est cliqu"; }}

L'vnement DoubleClick
Cet vnement a lieu lorsqu'un double clic survient sur un contrle. La dcision relative la distinction entre un double clic et deux clics successifs est faite par le systme d'exploitation. Cette dcision se base sur le temps qui spare les deux clics. Ce paramtre peut tre rgl travers le panneau de configuration de Windows. Evnement : public event EventHandler DoubleClick; Type dlgu : public delegate void EventHandler(Object sender,

EventArgs e);

Remarque : Si un contrle est capable de grer la fois les vnements Click et DoubleClick (exemple Form) alors un double clic sur ce contrle va dclencher automatiquement et dans l'ordre l'vnement Click suivi de l'vnement DoubleClick.

Les vnements MouseEnter, MouseLeave et MouseHover


Evnement : public event EventHandler MouseEnter; Evnement : public event EventHandler MouseLeave; Evnement : public event EventHandler MouseHover; Type dlgu : Ces trois vnements utilisent tous le mme type de dlgation public delegate void EventHandler(Object sender, EventArgs e);

Les vnements MouseDown, MouseUp et MouseMove


Evnement : public event MouseEventHandler MouseDown; Evnement : public event MouseEventHandler MouseUp; Evnement : public event MouseEventHandler MouseMove; Type dlgu : Ces trois vnements utilisent tous le mme type de dlgation public delegate void MouseEventHandler(Object sender, MouseEventArgs e);

72

Karim Kalti

La classe MouseEventArgs : Hirarchie:


System.Object System.EventArgs System.Windows.Forms.MouseEventArgs

Spcification: Proprit Button Clicks Delta X Y Type Enum MouseButtons int int int int Description Indique quel bouton de la souris est enfonc. Les valeurs possibles de lnumration MouseButtons sont {Left, Midle, None, Right,} Indique le nombre de fois le bouton de la souris a t appuy puis relch. Nombre de dtente sur la molette (si la souris en possde une) Coordonn X par rapprot laire client. Laxe des x est orient de gauche vers la droite partir du coin suprieur gauche. Coordonn Y. Laxe des y est orient du haut vers le bas partir du coin suprieur gauche.

Exemple : Affichage des coordonnes de la souris suite l'appui sur l'un de ses boutons (la souris survole un formulaire).
// this rfrence le formulaire this.MouseDown += new System.Windows.Forms.MouseEventHandler(this.FT); // FT est une mthode de la classe qui reprsente le formulaire void FT(object sender, System.Windows.Forms.MouseEventArgs e) { MessageBox.Show("X: "+e.X+", Y :"+e.Y); }

Les vnements lis au clavier


Le focus : Dans une interface graphique, le contrle qui est slectionn est dit le contrle qui a le focus. Le focus peut tre pass dun contrle graphique un autre laide de la touche TAB ou des touches MAJ+TAB. Si la proprit TabStop dun contrle vaut true, alors il y a arrt sur le composant lors du passage du focus. Lordre de rception du focus par les contrles est dfini par la proprit TabIndex de chaque contrle. Un vnement engendr par le clavier est automatiquement envoy par Windows au contrle ayant le focus. Trois types dvnements sont lis au clavier : o KeyDown : signal lors de lenfoncement dune touche du clavier. Cet vnement peut tre dclench par nimporte quelle touche. o KeyUp : signal lors du relchement dune touche. Il peut tre dclench par n'importe quelle touche. o KeyPress : signal lors dune frappe dune touche correspondant un caractre (alphanumrique). Lors de la dtection de lun de ces vnements par Windows, ce dernier excute automatiquement le dlgu qui lui correspond. A titre d'exemple, lors de la dtection de l vnement KeyDown, Windows lance automatiquement le dlgu KeyDown du contrle ayant le focus.

Les vnements KeyDown et KeyUp


Evnement : public event KeyEventHandler KeyDown; Evnement : public event KeyEventHandler KeyUp; Type dlgu : public delegate void KeyEventHandler(object sender, KeyEventArgs e);

73

Karim Kalti

La classe KeyEventArgs : Hirarchie:


System.Object System.EventArgs System.Windows.Forms.KeyEventArgs

Spcification : Proprit Alt Control Handled Shift KeyCode Valeur true, false true, false true, false true, false Enum Keys Description Indique si la touche Alt est enfonce Indique si la touche Ctrl est enfonce Indique que lvnement a t trait Indique si la touche Maj est enfonce Une des valeurs de lnumration Keys

Pour avoir la spcification complte de la classe KeyEventArgs, il faut consulter la documentation du .NetFramework Exemples de valeurs de l'numration Keys Les touches de F1 F24 correspondent Keys.Fi (exemple : la valeur Keys.F5 correspond la touche F5). Les valeurs Keys.D0 jusqu Keys.D9 correspondent aux touches numriques. Les valeurs Keys.A jusqu' Keys.Z correspondent aux touches alphabtiques. Keys possde d'autres valeurs qui correspondent aux touches spciales du clavier. Comme exemple de ces valeurs, il est possible de citer : Keys.Back, Keys.Cancel, Keys.Home, Keys.End, Keys.Del, etc.

La liste complte des valeurs de l'numration Keys peut tre consulte dans la documentation du .NetFrameWork. Exemple : Manipulation du paramtre e dans une fonction de traitement d'un vnement KeyUp ou KeyDown Si on veut vrifier si lutilisateur a appuy en mme temps sur la touche MAJ et sur le bouton de dplacement vers la gauche, alors la condition de test doit tre comme suit :
void FT(object sender, System.Windows.Forms.KeyEventArgs e) { if(e.Shift== true && e.KeyCode==Keys.Left) { // Mettre le code de traitement ici } }

Exemple d'inscription dune fonction de traitement auprs du gestionnaire d'un vnement KeyUp This.KeyUp += new System.Windows.Forms.KeyEventHandler(FT) Remarque : Aucune distinction nest faite entre les minuscules et les majuscules par les vnements KeyUp et KeyDown : e.KeyCode==Keys.A est vraie pour 'A' et 'a'. Pour intercepter les vnements au niveau de la fentre il faut que la proprit KeyPreview de cette fentre soit mise true.

Lvnement KeyPress
Evnement : public event KeyPressEventHandler KeyPress; Type dlgu :
public delegate void KeyPressEventHandler(Object sender, KeyPressEventArgs e);

74

Karim Kalti

La classe KeyPressEventArgs : Hirarchie:


System.Object System.EventArgs System.Windows.Forms.KeyPressEventArgs

Spcification: Proprit Handled KeyChar

Valeur true, false char

Description Indique que lvnement a t trait Caractre tap au clavier

Exemple : Si on veut tester si le caractre tap est alors la condition de test doit tre la suivante : if(e.KeyChar == '')

Remarques : I'vnement KeyPress fait la distinction entre minuscule et majuscule. Gnralement les vnements KeyUp et KeyDown sont utiliss pour dtecter les touches de direction, les touches de fonctions et les touches spciales du clavier comme par exemple Del, Back, KeyPress est utilis pour traiter les vnements lis aux touches alphanumriques.

75

Karim Kalti

Les menus

Exemple de menu

La classe MainMenu
Un menu en .NET est reprsent par le contrle MainMenu. Ce contrle reprsente en ralit la structure qui contient le menu. En mode programmation, ce contrle est cr travers la classe qui porte le mme nom "MainMenu".

Hirarchie de la classe :
System.Object System.MarshalByRefObject System.ComponentModel.Component System.Windows.Forms.Menu System.Windows.Forms.MainMenu

Quelques proprits : Proprit Container (hrit de Component) Handle IsParent MdiListItem MenuItems Description Obtient une rfrence au conteneur du composant. Obtient une valeur qui reprsente le handle de la fentre contenant le menu. Obtient une valeur indiquant si ce menu contient des lments de menu. Le MainMenu joue dans ce cas le rle de parent pour ces lments de menu. Cette proprit est en lecture seule. Obtient une valeur qui indique le MenuItem utilis pour afficher une liste de formulaires enfants MDI. Obtient une valeur qui indique la collection d'objets MenuItem associe au menu.

La classe MenuItem
Un Menu est gnralement compos d'un ensemble de contrles appels lments de menu. Chaque lment de menu est reprsent par la classe MenuItem. Hirarchie de la classe :
System.Object System.MarshalByRefObject System.ComponentModel.Component System.Windows.Forms.Menu System.Windows.Forms.MenuItem

76

Karim Kalti

Quelques proprits : Proprit Valeur Desciption Obtient ou dfinit une valeur qui indique si MenuItem est plac sur une nouvelle ligne (pour un lment de menu ajout un objet MainMenu) ou dans une nouvelle colonne (pour un lment de sous-menu ou un lment de menu affich dans ContextMenu). Obtient ou dfinit une valeur qui indique si l'lment est plac sur une nouvelle ligne (pour un lment de menu ajout un objet MainMenu) ou dans une nouvelle colonne (pour un lment de menu ou un lment de sous-menu affich dans un ContextMenu). Obtient ou dfinit une valeur qui indique si une coche apparat en regard du texte de l'lment de menu. Obtient le IContainer qui contient Component. Obtient ou dfinit une valeur indiquant si l'lment est l'lment de menu par dfaut. Obtient ou dfinit une valeur qui indique si l'lment de menu est activ. Obtient une valeur qui reprsente le handle de fentre pour le menu. Obtient ou dfinit une valeur qui indique la position de l'lment de menu dans son menu parent. Substitu. Obtient une valeur qui indique si l'lment de menu contient des lments de menu enfants. (sous menu) Obtient ou dfinit une valeur qui indique si l'lment de menu va tre rempli avec une liste des fentres enfants MDI (interface multidocument) affiches dans le formulaire associ. Obtient une valeur qui indique le MenuItem utilis pour afficher une liste de formulaires enfants MDI. Obtient une valeur qui indique la collection d'objets MenuItem associe au menu. Obtient ou dfinit une valeur qui indique la position relative de l'lment de menu lorsqu'il est fusionn avec un autre. Obtient ou dfinit une valeur qui indique le comportement de l'lment de menu lorsque son menu est fusionn avec un autre. Obtient une valeur qui indique le caractre mnmonique associ cet lment de menu. Obtient ou dfinit une valeur qui indique si l'lment de menu est dessin par le code que vous fournissez ou par Windows. Obtient une valeur indiquant le menu qui contient cet lment de menu. Obtient ou dfinit une valeur qui indique si le MenuItem affiche une case d'option au lieu d'une coche lorsqu'il est activ. Obtient ou dfinit une valeur qui indique la touche de raccourci associe l'lment de menu. Obtient ou dfinit une valeur qui indique si la touche de raccourci associe l'lment de menu est affiche en regard de la lgende de l'lment de menu. Obtient ou dfinit le ISite de Component. Obtient ou dfinit une valeur qui indique la lgende de l'lment de menu. Obtient ou dfinit une valeur qui indique si l'lment de menu est visible.

BarBreak

Break

Checked Container (hrit de Component) DefaultItem Enabled Handle (hrit de Menu) Index IsParent MdiList MdiListItem (hrit de Menu) MenuItems (hrit de Menu) MergeOrder MergeType Mnemonic OwnerDraw Parent RadioCheck Shortcut ShowShortcut Site (hrit de Component) Text Visible

T/F

T/F

int

T/F Enum Shortcut T/F

string

77

Karim Kalti

Pour qu'un menu principal (MainMenu) soit affich sur un formulaire (Form), il faut qu'il soit affect la proprit Menu du formulaire. Pour qu'un lment de menu (MenuItem) soit affich dans un menu principal (MainMenu), il faut qu'il soit ajout la liste des MenuItems du menu principal. Le menu principal joue dans ce cas le rle de parent ou de conteneur pour l'lment de menu. Un lment de menu (MenuItem) peut jouer galement le rle de parent pour un sous-menu compos lui aussi de plusieurs lments de menu. Pour que ce menu soit affich, il faut que ses lments soient ajouts la liste des MenuItems de l'lment parent.

Exemple 1:
// Mthode membre de la classe qui reprsente le formulaire public void CreateMyMainMenu() { // Cration d'un MainMenu vide. MainMenu mainMenu1 = new MainMenu(); MenuItem menuItem1 = new MenuItem(); MenuItem menuItem2 = new MenuItem(); menuItem1.Text = "File"; menuItem2.Text = "Edit"; // Ajout de deux lments de menu au menu principal. mainMenu1.MenuItems.Add(menuItem1); mainMenu1.MenuItems.Add(menuItem2); // Attachement du menu principal au formulaire. // this rfrence le formulaire this.Menu = mainMenu1; } private void InitializeComponent() { //L'appel de CreateMyMainMenu CreateMyMainMenu(); }

Rsultat de l'exemple 1

Exemple 2:
// Mthode membre de la classe qui reprsente le formulaire public void CreateMyMenu() { MainMenu mainMenu1 = new MainMenu(); MenuItem menuItem1 = new MenuItem(); MenuItem menuItem2 = new MenuItem(); MenuItem menuItem3 = new MenuItem(); MenuItem menuItem4 = new MenuItem(); menuItem1.Text = "&Edit"; menuItem2.Text = "Font Size"; menuItem3.Text = "Small"; menuItem3.Checked = true; menuItem3.Shortcut = Shortcut.CtrlS; menuItem4.Text = "Large"; menuItem4.Shortcut = Shortcut.CtrlL; menuItem4.Index = 1; menuItem2.MenuItems.Add(menuItem3); menuItem2.MenuItems.Add(menuItem4); menuItem1.MenuItems.Add(menuItem2); mainMenu1.MenuItems.Add(menuItem1); this.Menu = mainMenu1; }

Rsultat de l'exemple 2

78

Karim Kalti

Quelques vnements intercepts par les lments de menu


L'vnement Click : Evnement : public event EventHandler Click; Type dlgu : public delegate void EventHandler(object sender,

EventArgs e);

Exemple de gestion de l'vnement Click


public void CreateMyMenu() { MainMenu mainMenu1 = new MainMenu(); MenuItem topMenuItem = new MenuItem(); MenuItem menuItem1 = new MenuItem(); topMenuItem.Text = "&File"; menuItem1.Text = "&Open"; topMenuItem.MenuItems.Add(menuItem1); mainMenu1.MenuItems.Add(topMenuItem); menuItem1.Click += new System.EventHandler(this.menuItem1_Click); this.Menu=mainMenu1; } private void menuItem1_Click(object sender, System.EventArgs e) { // Instanciation d'une bote d'ouverture de fichier. OpenFileDialog fd = new OpenFileDialog(); fd.DefaultExt = "*.*"; fd.ShowDialog(); }

Traitement de plusieurs vnements de Click par une seule fonction


MenuItem m = (MenuItem)sender; if(m.text=="Ouvrir) {// Code du menu ouvrir } if(m.text=="Enregistrer) {// Code du menu Enregistrer }

L'vnement PopUp Cet vnement se produit avant l'affichage de la liste des lments de menu d'un lment de menu. Cet vnement est gnralement utilis pour faire des modifications des paramtres du menu (activation, dsactivation,) suivant les donnes du programme. Evnement: public event EventHandler Popup; Type dlgu: public delegate void EventHandler(object sender,

EventArgs e);

Changement du menu principal suivant l'tat du programme Il suffit de crer plusieurs menus principaux (MainMenu) et d'affecter l'un d'eux la proprit Menu du formulaire et ce suivant l'tat de l'excution du programme.

79

Karim Kalti

Accs aux donnes en .NET (ADO.NET)


Introduction
L'accs aux donnes est un lment important dans la majorit des applications dveloppes aujourd'hui. Microsoft a propos une panoplie de technologies d'accs aux donnes (ODBC, DAO, RDO, ADO). ADO.NET (anciennement appel ADO+) constitue la dernire technologie propose dans ce cadre.

Rappel
Terminologie API (Application Programming Interfaces) : une API est une bibliothque de modles de fonctions (interfaces) gnralement de bas-niveau ralisant une tche bien prcise. Dans un contexte orient objet, une API se prsente comme une bibliothque de classes interfaces disposant de mthodes permettant de raliser des tches bas-niveau. API d'accs aux donnes : Une API d'accs aux donnes est une bibliothque de fonctions ou d'objets permettant de faire les oprations d'accs aux bases de donnes, d'interrogation de ces bases (envoi des requtes) et de rcupration de donnes partir de ces bases. API native d'accs aux donnes : Chaque SGBD possde une API propritaire tenant compte de ses spcificits et qui permet de faire les oprations d'accs cet SGBD. Une telle API est appele une API native. ODBC (Open Data Base Connectivity) ODBC (Open Data Base Connectivity) est une API de fonctions (non oriente objet) unifie d'accs aux donnes qui a pour objectif de permettre l'accs n'importe quel SGBD sans ncessiter une connaissance des API natives.
Requte utilisateur (API native)

SGBD SQLServe

Requte utilisateur (API native)

Requte utilisateur (API ODBC)

Pont ODBC

SGBD Oracle

Requte utilisateur (API native)

SGBD Access
Requte utilisateur (API native)

SGBD X

Architecture d'un pont ODBC : Un pont ODBC est compos de trois couches : La premire couche est une couche de rception des requtes adresses par les applications un SGBD. Ces requtes sont spcifies par les applications l'aide de l'API ODBC. La deuxime couche est constitue d'un composant logiciel appel gestionnaire de pilotes. Ce gestionnaire joue le rle d'intermdiaire qui va dcider du choix du pilote ODBC appropri qui va prendre en charge la requte adresse par l'application. Ce choix se base sur le type de la base de donnes interroge. Le

80

Karim Kalti

gestionnaire assure le chargement en mmoire et la libration du pilote slectionn. La troisime couche assure la communication entre le gestionnaire des pilotes et les pilotes ODBC. Cette communication est faite travers des appels effectus par le gestionnaire, aux fonctions des pilotes ODBC. Ces fonctions font partie de l'API unifie dfinie par le standard ODBC et utilise par les dveloppeurs des pilotes ODBC.

Application API ODBC Gestionnaire de pilotes API Pilotes fournisseurs

Pilote ODBC

Pilote ODBC

Pilote ODBC

Pilote ODBC

SGBD 1

SGBD 2

SGBD 3

SGBD 4

Architecture d'un pont ODBC

Pilote ODBC Un pilote ODBC est un composant logiciel qui a pour objectif de traduire la requte crite avec l'API ODBC unifie vers un format (crit l'aide de l'API native) propre au SGBD interrog. Tout SGBD qui veut tre accessible travers ODBC doit fournir un pilote ODBC qui lui est spcifique. Ainsi par exemple, pour accder une base de donnes SQLServer ou Oracle travers ODBC, il faut installer sur la machine sur laquelle tourne l'application le pilote ODBC pour SQL Server, respectivement pour Oracle. Pour voir sous Windows XP la liste des pilotes ODBC installs sur une machine il faut aller : Panneau de configuration Outils d'administration Sources de donnes ODBC OLE DB : OLE DB (Open Linking and Embeding for DataBases) est une API unifie d'accs aux donnes qui offre plus de possibilits que l'API ODBC. En effet ODBC permet l'accs aux bases de donnes relationnelles seulement. Avec OLE DB il est possible d'accder n'importe quelle source de donnes, relationnelle ou non (Systme de fichiers, XML, Tableur, Messagerie,). OLE DB utilise une collection d'objets qui dfinit un modle diffrent de celui de ODBC. Ce modle s'articule autour des objets de base suivants : Data Source, Session, Command, Rowset. A ces objets de base s'ajoutent d'autres objets qui sont : Enumerator, Transaction, Error.

81

Karim Kalti

SGBD-R

XML

API OLE DB

Pont OLE DB

Fichiers

Tableur

Autres

Exemples de sources de donnes accessibles travers un pont OLE DB

Avantages et inconvnients de l'utilisation des APIs unifies. Sans l'utilisation d'une API unifie, les programmeurs d'applications sont obligs d'appendre diffrentes API natives pour faire des accs diffrents SGBDs. Ceci alourdit la charge de travail des dveloppeurs surtout dans les milieux professionnels o l'on est amen souvent travailler sur des SGBD diffrents d'un projet un autre. L'intrt des APIs unifies dans ce cas est grand puisqu'elles vont allger la charge de travail des dveloppeurs. Les APIs unifies sont toutefois moins rapides que les API natives cause notamment des tapes de conversion de requtes qui sont ncessaires dans ce cas.

Prsentation de ADO.NET
ADO.NET (ActiveX Database Object) est une nouvelle API d'accs aux donnes propose par Microsoft. Cette API permet aux applications dveloppes en .NET de travailler avec diffrents types de sources de donnes. Caractristiques : ADO.NET permet de travailler en mode connect et en mode dconnect. ADO.NET permet de travailler d'une manire compltement indpendante du type de la base de donnes. ADO.NET permet l'interoprabilit avec d'autres sources de donnes (relationnelle ou non telles que les systmes de fichiers, Active Directory, etc.). Cette interoprabilit est obtenue grce la possibilit d'importer et d'exporter les donnes au format XML. Configuration requise pour ADO.NET ADO.NET est fourni avec le FrameWork.NET. Il est ncessaire par ailleurs d'installer MDAC (Microsoft Data Access Components version 2.6 ou plus) pour pouvoir utiliser les fournisseurs de donnes SQL Server ou OLE DB. ADO.NET peut tre utilis sous Windows CE/95/98/ME/NT4 SP6a/2K/XP/2003 Server.

Les modes de travail avec ADO.NET


ADO.NET offre deux modes de travail : Le mode dconnect Ce mode permet de travailler d'une manire dconnecte de la source de donnes. Les tapes de travail avec ce mode se droulent comme suit : Le client entre en communication avec le serveur de BD pour effectuer une requte (gnralement un SELECT). Le serveur envoie en une seule fois le rsultat de la requte au client et la communication est ensuite coupe. Le client dispose donc dune copie locale dune partie de la BD serveur (qui correspond sa requte). Le client peut travailler sur la copie locale sans solliciter ni le serveur ni le rseau. Il peut modifier cette partie puis lenvoyer nouveau au serveur travers une nouvelle connexion la BD.

82

Karim Kalti

Le mode connect Ce mode permet de travailler d'une manire connecte par rapport la source de donnes. Les tapes de travail avec ce mode se droulent comme suit : Le client effectue une requte auprs du serveur (Exemple un SELECT). Le serveur calcule le rsultat de la requte, il maintient une communication logique avec le client et lui envoie le rsultat de son SELECT ligne par ligne suite aux demandes de ce client (dplacement entre les enregistrements de son RecordSet). Le serveur doit savoir o il en est dans sa communication avec chaque client qui lui est connect. Comparaison des deux modes Le mode dconnect est plus adapt la manire de travailler sur Internet. En effet sur Internet on ne peut pas connatre quand est ce que le client (lger dans ce cas) dcide de se dconnecter de la page d'accs aux donnes (Il peut la laisser ouverte et passer dautres pages). Maintenir plusieurs connexions ouvertes en continue avec la source de donnes constitue un frein la capacit de monte en charge d'une application. (ce problme peut toutefois tre vit en utilisant la proprit TimeOut lie la variable de Session). Le mode dconnect engendre une plus grande surcharge du rseau mais seulement au moment de la transmission du rsultat de la requte ce qui risque de provoquer des courts blocages. Le mode connect est prfr lorsque le jeu d'enregistrement traiter est trop grand pour tre facilement transfr et stock localement en mmoire.

Architecture gnrale de ADO.NET


ADO.NET est une API compose d'une collection de classes interfaces rpartie suivant un modle en deux couches comme le montre la figure ci-dessous :

Les deux couches qui composent ce modle sont : Une couche connecte qui comporte des classes manages qui font des accs physiques la base de donnes. Ces classes constituent ce que ADO.NET appelle un fournisseur de donnes ou Data Provider (Connection, Transaction, Command, Parameters, DataReader, DataAdapter,). Une couche dconnecte qui comporte des classes qui ne sont pas en liaison directe avec les bases de donnes. Ces classes constituent une sorte de cache pour le stockage en local d'une partie des donnes de la base.

83

Karim Kalti

Le modle de fournisseur de donnes


Un fournisseur de donnes est une API qui permet de faire des accs physiques la source de donnes. Cette API est compose de la collection de classes interfaces de la couche connecte de ADO.NET. Les quatre objets de cette couche sont prsents dans le tableau ci-dessous : Objet
Connection Command DataReader DataAdapter

Description
Etablit une connexion une source de donnes spcifique. Excute une commande adresse une source de donnes. Lit un flux partir d'une source de donnes. Seule la lecture est possible. Elle est faite dans un sens unique (vers l'avant). Remplit un DataSet partir d'une source de donnes et met jour cette dernire partir d'un DataSet.

A ces classes de base viennent s'ajouter d'autres qui les compltent : Objet
Transaction CommandBuilder Parameter Exception Error

Description
Permet de lister les commandes dans une transaction. Un assistant qui gnre automatiquement les proprits des commandes d'un DataAdapter. Dfinit les entres, les sorties et retourne les valeurs des paramtres pour les commandes et les procdures stockes. Exception retourne lorsqu'une erreur est rencontre au niveau de la source de donnes. Pour une erreur rencontre au niveau du client le fournisseur de donnes intercepte une exception du FrameWork.NET. Expose les informations accompagnant un avertissement ou une erreur retourn(e) par une source de donnes.

Les classes susmentionnes ne sont pas directement instanciables. Elles sont en effet dfinies dans le FrameWork .NET sous forme d'interfaces (car elles dfinissent un modle). Par exemple l'objet Connection est reprsent par l'interface IDbConnection, l'objet DataAdpater est reprsent par l'interface IDbDataAdapter, l'objet Command est reprsent par l'interface IDbCommand et l'objet DataReader est reprsent par l'interface IDbDataReader.

Fournisseurs de donnes de ADO.NET


Un fournisseur de donnes est une implmentation de l'API du modle des fournisseurs (collection d'interfaces prsente dans le paragraphe prcdent). ADO.NET dans sa version 1.1 propose quatre fournisseurs diffrents (quatre implmentations diffrentes) : Le fournisseur manag (OLEDB managed Provider) : Ce fournisseur est une implmentation du modle des fournisseurs l'aide de l'API de la technologie OLEDB propose par Microsoft. Les classes qui reprsentent cette implmentation sont dfinies dans l'espace de noms System.Data.OleDb. Ce fournisseur permet aux applications crites en .NET d'accder la majorit des SGBDs et ce travers le pont OLEDB. Le fournisseur manag ODBC (ODBC managed Provider) : Ce fournisseur est une implmentation du modle des fournisseurs l'aide de l'API ODBC. Il permet de ce fait d'accder n'importe quel SGBD possdant un pilote ODBC. Les classes composant ce fournisseur sont dfinie dans l'espace de noms System.Data.ODBC. Le fournisseur manag SQL Server (SQL Server managed Provider) : Ce fournisseur est une implmentation du modle des fournisseurs l'aide de l'API native du SGBD SQL Server. Il permet d'accder seulement au SGBD SQL Server (version 7 ou plus) pour lequel il offre de meilleurs performances que celles obtenues avec le fournisseur OLEDB (grce l'accs natif bien sr). Les classes composant ce fournisseur sont dfinies dans l'espace de noms System.Data.SqlClient. Le fournisseur manag ORACLE (ORACLE managed Provider) : Ce fournisseur est une implmentation du modle des fournisseurs l'aide de l'API native du SGBD ORACLE. Il ne peut tre utilis donc qu'avec ORACLE. Les classes composant ce fournisseur sont dfinies dans l'espace de noms System.Data.OracleClient. Les deux premiers fournisseurs utilisent des ponts (OLEDB et ODBC) et offrent par consquent un accs un grand nombre de SGBD. Les deux derniers fournisseurs font respectivement des accs natifs aux SGBD SQL Server et Oracle. Ils offrent de meilleures performances pour ces deux SGBDs par rapport celles obtenues travers les ponts OLEDB et ODBC.

84

Karim Kalti

Remarque 1: Tout SGBD qui se veut accessible d'une manire native travers une application .NET doit proposer sa propre implmentation du modle des fournisseurs de donnes (son propre pilote ADO.NET). Remarque 2 : Chaque classe qui implmente une interface faisant partie d'un fournisseur porte le nom de cette interface prfix du nom du fournisseur auquel elle appartient. Le tableau suivant donne quelques exemples de noms de classes implmentes par les diffrents fournisseurs :

Interface
Connection Command DataReader DataAdapter

OLE DB Provider
OleDbConnection OleDbCommand OleDbDataReader OleDbDataAdapter

ODBC Provider
ODBCConnection ODBCCommand ODBCDataReader ODBCDataAdapter

SQL Provider
SqlConnection SqlCommand SQLDataReader SqlDataAdapter

Oracle Provider
OracleConnection OracleCommand OracleDataReader OracleDataAdapter

Fournisseur SQL-Server API ADO.NET Fournisseur ORACLE Fournisseur OLEDB Fournisseur ODBC

Accs natif (API SQL Server)

SQL Server

Accs natif (API ORACLE) ORACLE API OLEDB

Pont OLEDB

MS-ACCESS

API ODBC

Pont ODBC

Autres SGBD

Les diffrentes APIs implmentant les fournisseurs de donnes de ADO.NET

Le reste de ce chapitre prsente les diffrentes tapes de l'accs une base de donnes l'aide du fournisseur OLEDB Provider. L'accs l'aide des autres fournisseurs se fait de la mme manire puisque tous les fournisseurs implmentent le mme modle.

Connexion une base de donnes


La connexion une base de donnes en ADO.NET se fait l'aide de l'interface Connection. Le fournisseur OLEDB implmente cette interface l'aide de la classe OleDbConnection.

Espace de nom de OleDbConnection: System.Data.OleDB ;

Constructeurs : Constructeur
OLeDbConnection() OleDbConnection(string connectionString)

Description
Cre un objet de connexion non initialis. Cre un objet de connexion tout en spcifiant une chane de connexion. Ce constructeur dcortique automatiquement la chane pour remplir les proprits de lobjet de connexion.

85

Karim Kalti

Principales proprits de OleDbConnection : Proprit


ConnectionString

Type
string

Description
Il sagit dune chane de caractres au format bien particulier qui est passe au constructeur de lobjet de connexion. Ce constructeur la place dans l'attribut courant et la dcortique pour initialiser les autres attributs de la classe. Il est noter que certains attributs sont en lecture seule et ne peuvent tre initialise en dehors du constructeur de la classe et donc travers la chane de connexion. Dure en secondes durant laquelle ltablissement dune connexion au serveur de BD est tent. Si pendant ce laps temps la connexion choue alors une erreur est signale. Une valeur nulle indique une attente infinie ( viter). Par dfaut la valeur est de 15 secondes. Nom de la base de donnes ( utiliser avec SQL Server). Nom de la source de donnes ( utiliser dans le cas de MSACCESS ou autres). Mot de passe pour accder la base Identificateur du type de la BD

ConnectionTimeOut DataBase DataSource Password Provider

int string string string string

Principales mthodes de OleDbConnection : Mthode


void Open() void Close()

Description
Ouverture explicite de la base. Une exception est gnre en cas dchec de louverture. Fermeture explicite de la base de donnes.

Spcification de la valeur de la proprit DataSource : La valeur de la proprit DataSource dsigne le chemin de la source de donnes. Ce chemin peut tre : Un chemin absolu. (Exemple : data source = C:\repertoire\MaBase.mdb) Un chemin relatif si la source se trouve dans le mme dossier que lexcutable de lapplication ou si elle se trouve dans un sous dossier de celui-ci. (Exemple pour un mme dossier : data source = MaBase.mdb) Un chemin rseau si la source se trouve sur une autre machine du rseau local. (Exemple: data source = \\machine\Lecteur\...\ MaBase.mdb) Spcification de la valeur de la proprit Provider : Cette proprit dsigne le type de la source de donnes laquelle est fait l'accs. Le tableau ci-dessous donne quelques exemples de valeurs utilises pour un certain nombre de SGBD.

SGBD
Access SGL Server AS400 DB2 Fox Pro Oracle

Valeur
Provider = Microsoft.Jet.OLEDB.4.0 Provider =SQLOLEDB Provider = IBMA400 ; Provider = DB2OLEDB ; Provider = vfpOLEDB ; Provider = MSDAORA

Exemple d'utilisation de l'objet de connexion :


using System; using System.Data; using System.Data.OleDb; ... // Cration de la chane de connexion string StrCnn = @"Provider=Microsoft.Jet.OleDb.4.0 ; Data Source=C:\Repertoire\MaBase.mdb"; // Cration de l'objet de connexion OleDbConnection cnn = new OleDbConnection(StrCnn); // Ouverture de la connexion cnn.Open(); ... // Mettre ici le code d'interrogation de la source de donnes ... // Fermeture de la connexion cnn.Close();

86

Karim Kalti

Commentaire : Suite la cration de l'objet de connexion, l'tablissement effectif de la liaison avec la base est amorc par l'appel la mthode Open. Une fois la connexion ouverte, il devient possible d'adresser la base des requtes de diffrents types (insertion, slection, ). Enfin, lorsque l'interrogation se termine, il faut fermer la connexion avec la mthode Close. Remarque : utilisation de @ devant la chane de connexion Par dfaut le caractre '\' introduit dans les chanes un caractre de formatage. Pour ne pas le considrer ainsi, il faut faire prcder la chane de @. Si non lorsquil sagit de spcifier un chemin, il faut utiliser \\ au lieu de \. Dans ce cas la chane de connexion devient :
"Provider=Microsoft.Jet.OleDb.4.0 ; Data Source = C:\\Repertoire\\MaBase.mdb";

Interrogation de la base de donnes en mode connect


L'interrogation de la base de donnes peut se faire dans un objectif d'insertion, de suppression, de mise jour ou de slection de donnes. En mode connect, la ralisation de toutes ces oprations passe par l'interface Command. Le fournisseur OLEDB implmente cette interface par la classe OleDbCommand. Espace de nom de OleDbCommand : System.Data.OleDB ; Constructeurs de OleDbCommand : Constructeur
OLeDbCommand() OLeDbCommand (string sqlstr) OLeDbCommand (string sqlstr, OleDbConnection cnn)

Description
Cre un objet de commande non initialis Cre une commande et lui passe une requte SQL. Cre une commande et lui passe une requte SQL plus un objet de connexion.

Principales proprits de OleDbCommand : Proprit Type

Description

CommandType

enum CommandType

CommandText

string

CommandTimeOut Connection Parameters

int OleDbConnection OleDbParameterCollection

Indique le type de la commande. Trois valeurs sont possibles dans ce cadre : Text : Signifie que la commande est une requte SQL. StoredProcedure : signifie que la commande reprsente un appel une procdure stocke. TableDirect : signifie que la commande est une requte de slection du contenu entier d'une table. Contient le texte de la commande. La manire d'interprtation de ce texte dpend de la valeur de la proprit CommandType. Si CommandType = Text alors CommandText reprsente le texte de la requte SQL. Si CommandType=StoredProcedure alors CommandText contient le nom de la procdure stocke qui sera appele. Si CommandType=TableDirect alors CommandText contient le nom de la table dont le contenu sera renvoy. Cette commande est quivalente une requte SLECT * applique la table en question. Nombre de secondes dattente avant quune commande ne soit dclare en erreur. La valeur par dfaut est de 30 sec. Lobjet connexion associ la commande. Il sert spcifier la source de donnes laquelle est destine la commande. Liste des paramtres utiliss par la commande. Par dfaut cette collection est vide.

Principales mthodes de OleDbCommand : Les mthodes les plus utilises de la classe OleDbCommand sont celles qui permettent d'excuter les commandes. Trois mthodes sont proposes cet effet : Mthode Description
Elle excute la commande spcifie dans CommandText. Dans ce cas la commande doit tre une commande dinsertion, de mise jour ou de suppression (INSERT, UPDATE, DELETE). La mthode retourne le nombre de lignes sur lesquelles a port la commande (nombre de lignes insres, supprimes, mises jour). La mthode ExecuteNonQuery ne peut pas excuter une commande de slection (SELECT). Elle retourne -1 dans ce cas.

int ExecuteNonQuery()

87

Karim Kalti

object ExecuteScalar()

OleDbDataReader ExecuteReader()

Cette mthode est essentiellement utilise pour excuter une commande qui renvoie une valeur scalaire (Exemple : SELECT COUNT* ). D'une manire gnrale, ExecuteScalar renvoie sous la forme dune valeur de type object la premire colonne de la premire ligne de la collection d'enregistrements reprsentant le rsultat de la requte. Elle retourne une rfrence nulle si ce rsultat est vide. Cette mthode est utilise lorsque la commande renvoie une collection d'enregistrements (Gnralement le rsultat d'une requte de slection). La collection d'enregistrements renvoye est place dans un objet de type OleDbDataReader (implmentation de l'interface DataReader). Cet objet permet de faire le parcours des enregistrements un par un, en lecture seule et dans un seul sens (vers l'avant).

L'objet OleDbParameter
Un objet Parameter reprsente un paramtre d'une commande. Il est noter qu'un objet Command peut comporter une collection de paramtres stocke dans sa proprit Parameters. Pour le fournisseur OleDb les paramtres sont crs l'aide de la classe OleDbParameter. Proprit
ParameterName

Type
string enum ParameterDirection OleDbType Bool Byte

Description
Nom du paramtre. - Input : le paramtre est un paramtre d'entre. - Output : le paramtre est un paramtre de sortie. - InputOutput : le paramtre est un paramtre d'entre et de sortie. - ReturnValue : le paramtre reprsente la valeur de retour (gnralement d'une procdure stocke). Le type du paramtre. Indique si le paramtre accepte la valeur null ou non (par dfaut false). Obtient ou dfinit le nombre maximal de chiffres utiliss pour reprsenter la proprit Value. (la valeur par dfaut est 0, elle signifie que c'est le fournisseur qui dtermine la prcision) Obtient ou dfinit le nombre de dcimales (chiffres aprs la virgule) appliqu la rsolution de Value. La proprit Scale est utilise uniquement pour les paramtres d'entre dcimaux et numriques. (la valeur par dfaut est 0, elle signifie que c'est le fournisseur qui dtermine la valeur de cette proprit). Obtient ou dfinit la taille maximale, en octets, des donnes figurant dans la colonne. Elle est utilise essentiellement pour les chanes de caractres. Pour les types de taille fixe cette valeur est tout simplement ignore. Obtient ou dfinit le nom de la colonne source mappe DataSet et utilise pour charger et retourner Value. Obtient ou dfinit la version de la ligne utiliser lors du chargement de Value. Obtient ou dfinit la valeur du paramtre.

Direction

OleDbType IsNullable Precision

Scale

Object

Size SourceColumn SourceVersion Value string DataRowVersion object

Les constructeurs les plus utiliss sont :


public OleDbParameter(); public OleDbParameter(string parameterName, OleDbType oledbType, int size, string sourceColumn); Construit un objet paramtre non initialis. Construit un objet paramtre avec initialisation de quelques proprits. Ce constructeur est souvent utilis pour crer des paramtres devant passer des nouvelles valeurs la requte stocke dans un objet Command. Construit un objet paramtre avec initialisation de l'ensemble des proprits. Ce constructeur est souvent utilis pour crer des paramtres devant passer des anciennes valeurs d'une ligne la requte stocke dans un objet Command.

public OleDbParameter(string parameterName, OleDbType oleDbType, int size, ParameterDirection direction, bool isNullable, byte precision, byte scale, string srcColumn, DataRowVersion srcVersion, object value);

Utilisation des espaces rserves dans les requtes Il est possible de faire passer des paramtres au texte SQL d'une requte et ce en utilisant des espaces rservs introduits par le caractre "?". Les espaces rservs ne sont pas accepts par tous les SGBD (Certains SGBDs demandent des paramtres nomms comme SQL Server par exemple). Les espaces rservs d'une requte prennent leurs valeurs partir de la collection des paramtres de l'objet Command qui reprsente cette requte. La correspondance entre les espaces et les paramtres se fait sur la base de l'ordre d'apparition des "?" dans le texte de la requte et de l'ordre d'ajout des paramtres la collection Parameters de l'objet Command. Ainsi, le premier paramtre ajout la collection correspond au premier espace rserv, le deuxime paramtre au deuxime espace rserv, etc. Au moment de l'excution de la commande, les espaces rservs de la requte seront remplacs par le contenu des proprits Value des objets paramtres qui leurs correspondent.

88

Karim Kalti

Exemple : Si on considre le texte de la requte suivante : "INSERT INTO NomTable Values (?, ?, ?)". L'objet command bas sur cette requte peut faire passer cette dernire des arguments qui prendront la place des espaces rservs. Ces arguments doivent provenir de la collection Parameters de cet objet Command.

Rcupration des enregistrements en mode connect


Les requtes de slection retournent gnralement une collection d'enregistrements. En mode connect, la gestion de cette collection se fait l'aide de l'objet OleDbDataReader. Cet objet : n'est pas cr l'aide d'un constructeur mais par appel la mthode ExecuteReader de lobjet Command. Fait un balayage du rsultat de la requte de slection enregistrement par enregistrement, d'une manire squentielle, du dbut vers la fin et uniquement dans ce sens. Rfrence un instant donn un seul enregistrement de la collection d'enregistrement renvoye par la requte de slection. Ne permet de faire que des accs en lecture aux donnes rcupres. Assure le transfert de chaque enregistrement du serveur de donnes vers le client juste au moment de la demande de lecture de cet enregistrement.

Espace de noms de OleDbDataReader : System.Data.OleDB ; Principales proprits de OleDbDataReader : Proprit


FieldCount Item

Type
int []

Description
Nombre de champs dans lenregistrement renvoy (nombre de colonnes dans la ligne). Indexeur daccs aux champs de l'enregistrement courant de lobjet OleDbDataReader. Il peut tre index sur le numro du champ ou sur le nom du champ.

Principales mthodes de OleDbDataReader : Mthode


void Close() string GetName(int n) int GetOrdinal(string) bool IsDBNull(int N) bool Read() bool NextResult()

Description
Ferme lobjet OleDbDataReader. Renvoie le nom du nime champ. Renvoie la position dun champ dont le nom est pass comme argument. Une exception est gnre si le nom du champ nest pas connu. Renvoie true si le champ en nime position contient une valeur nulle. Lit la ligne suivante dans la table reprsentant la collection d'enregistrements. Read renvoie true si une ligne a effectivement pu tre lue. Elle renvoie false quand la fin du rsultat du SELECT est atteinte. Permet de passer directement l'enregistrement suivant (ligne suivante de la table). Renvoie true si cette ligne existe. Remplit le tableau en argument avec le contenu des diffrentes colonnes dune ligne (le contenu de l'enregistrement rfrenc par le DataReader). Elle renvoie le nombre de cellules remplies dans ce tableau. Si le tableau contient un nombre n de cellules infrieur au nombre de champs alors seules les n cellules sont remplies.

int GetValues(Object[])

Exemples de code d'interrogation de base de donnes


La base de donnes interrog dans ces exemples s'appelle Biblio et contient une table Ouvrage. Cette base est cre avec MS-ACCESS.

Ouvrage

Champ Type

Inventaire Entier

Titre Chane

Auteur Chane

Anne d'dition Entier

89

Karim Kalti

Exemple 1 : requte renvoyant une valeur (Calcul du nombre d'ouvrages) Le calcul du nombre d'ouvrages se fait l'aide d'une requte qui retourne une valeur de type scalaire (entier). C'est la mthode ExecuteScalar de l'objet Command qui doit alors tre utilise :
using System; using System.Data; using System.Data.OleDb; class DataAccess { static int CalculNbOuvrages() { // Cration de la chane de connexion string StrCnn = @"Provider = Microsoft.Jet.OLEDB.4.0; Data Source = C:\ADO\ Biblio.mdb"; // Cration de l'objet de connexion OleDbConnection cnn = new OleDbConnection(StrCnn); // Ouverture de la connexion cnn.Open(); // Cration du texte de la commande string StrSql = "SELECT Count(*) FROM Ouvrage"; // Cration de l'objet Command OleDbCommand cmd=new OleDbCommand(StrSql,cnn); // Excution de la commande int n =(int)cmd.ExecuteScalar(); // Fermeture de la connexion cnn.Close(); return n; } static void Main() { Console.WriteLine("le rsultat est "+CalculNbOuvrages()); Console.ReadLine(); } }

Exemple 2 : Requte d'insertion dans une table (Ajout d'un ouvrage) L'insertion d'un enregistrement dans une table se fait gnralement l'aide de la mthode ExecuteNonQuery de l'objet Command.
using System; using System.Data; using System.Data.OleDb; class DataAccess { static int CalculNbOuvrages(){...} static void AjoutOuvrage() { // Cration de la chane de connexion string StrCnn = @"Provider = Microsoft.Jet.OLEDB.4.0; Data Source = C:\ADO\Biblio.mdb"; // Cration de l'objet de connexion OleDbConnection cnn = new OleDbConnection(StrCnn); // Ouverture de la connexion cnn.Open(); // Texte de la commande string StrSql = "INSERT INTO Ouvrage VALUES (12,'Programmation C','Didier Le Blanc', #10/12/1999#)"; // Cration de l'objet Command OleDbCommand cmd=new OleDbCommand(StrSql,cnn); // Excution de la commande cmd.ExecuteNonQuery();

90

Karim Kalti

// Fermeture de la connexion cnn.Close(); } static void Main() { Console.WriteLine("le rsultat est "+CalculNbOuvrages()); AjoutOuvrage(); Console.WriteLine("le rsultat est "+CalculNbOuvrages()); Console.ReadLine(); } }

Exemple 3 : Requte de suppression et de mise jour Les requtes de suppression et de mise jour s'excutent de la mme manire que la requte d'insertion ( l'aide de la mthode ExecuteNonQuery). Il suffit tout simplement de changer le texte de la requte. Exemple de texte d'une commande de mise jour :
string StrSql = "UPDATE Ouvrage SET Titre = 'Programmation Java' WHERE Inventaire = 12";

Exemple de texte d'une commande de suppression :


string StrSql = "DELETE FROM Ouvrage WHERE Inventaire = 12";

Exemple 4 : Requte de slection L'excution d'une requte de slection se fait l'aide de la mthode ExecuteReader de l'objet Command. La collection d'enregistrements renvoye est place dans un objet DataReader. C'est travers cet objet que se fait la consultation de ces enregistrements.
using System; using System.Data; using System.Data.OleDb; class DataAccess { static void ConsultationOuvrage() { // Cration de la chane de connexion string StrCnn = @"Provider = Microsoft.Jet.OLEDB.4.0; Data Source = C:\ADO\Biblio.mdb"; // Cration de l'objet de connexion OleDbConnection cnn = new OleDbConnection(StrCnn); // Ouverture de la connexion cnn.Open(); // Texte de la commande string StrSql = "SELECT * FROM Ouvrage"; // Cration de l'objet Command OleDbCommand cmd=new OleDbCommand(StrSql,cnn); // Execution de la commande et rcupration des donnes dans un DataReader OleDbDataReader rd = cmd.ExecuteReader(); // Parcours des enregistrements renvoys string s; int i =0; if(rd!=null) { while (rd.Read()) { s = (string)rd["Titre"]; // (string)rd[1] i+=1; Console.WriteLine("Ouvrage"+i+":"+s); } } // Fermeture de la connexion cnn.Close(); } static void Main() { ConsultationOuvrage(); Console.ReadLine(); } }

91

Karim Kalti

Requte paramtre
On considre dans ce qui suit la requte de slection de livres prsente au paragraphe prcdent. Supposons que l'on veuille slectionner seulement les livres dont l'anne d'dition est ultrieure une anne saisie par l'utilisateur. Le texte de la requte doit dans ce cas tre construit d'une manire dynamique. Deux solutions se prsentent cet gard. Solution 1 : Construction de la requte par concatnation. Dans cette solution, les donnes saisies par l'utilisateur sont converties en chanes de caractres et introduites dans le texte de la requte par concatnation comme le montre l'exemple suivant : Exemple :
int Anne; string StrCnn = @"Provider = Microsoft.Jet.OLEDB.4.0; Data Source =C:\Data\Bilbio.mdb"; OleDbConnection cnn = new OleDbConnection(StrCnn); cnn.Open(); // Saisie de l'anne de rfrence Console.WriteLine("Donner l'anne de rfrence"); Anne=Int32.Parse(Console.ReadLine()); // Cration du texte de la requte par concatnation string StrSql = "SELECT * FROM Ouvrage WHERE [Anne d'dition]>"+Anne.ToString(); // Cration d'une commande base sur la requte de slection OleDbCommand cmd=new OleDbCommand(StrSql,cnn); OleDbDataReader rd = cmd.ExecuteReader();

Solution 2 : Utilisation des objets Parameters L'ADO.NET propose une alternative permettant d'automatiser le passage de paramtres aux requtes. Cette alternative se base sur l'utilisation des espaces rservs et des objets Parameters. L'exemple suivant illustre l'utilisation de cette technique : Exemple :
int Anne; string StrCnn = @"Provider = Microsoft.Jet.OLEDB.4.0; Data Source =C:\Data\Bilbio.mdb"; OleDbConnection cnn = new OleDbConnection(StrCnn); cnn.Open(); // Saisie de l'anne de rfrence Console.WriteLine("Donner l'anne de rfrence"); Anne=Int32.Parse(Console.ReadLine()); // Texte de la requte avec utilisation d'un espace rserv permettant // de faire passer une anne d'dition comme argument string StrSql = "SELECT * FROM Ouvrage WHERE [Anne d'dition]>?"; // Cration d'un objet command bas sur la requte de slection OleDbCommand cmd=new OleDbCommand(StrSql,cnn); // Cration d'un objet Parameter qui va servir pour faire passer l'anne. // Il suffit de passer l'anne la proprit Value de l'objet Parameter OleDbParameter Par = new OleDbParameter("PDate",Anne); // Ajout du paramtre la liste des paramtres de la commande cmd.Parameters.Add(Par); // Excution de la commande OleDbDataReader rd = cmd.ExecuteReader();

92

Karim Kalti

Prsentation du mode dconnect


Une application dconnecte ne possde aucune connexion permanente sa source de donnes. Le modle de telles applications se base sur deux composants qui sont le DataAdapter et le DataSet. Architecture du modle dconnect

DataSet
Remplissage

DataTable DataTable
Lecture des donnes

DataAdapter
SelectCommand InsertCommand UpdateCommand DeleteCommand

Lecture des donnes

Source de donnes
Mise jour

Le composant DataSet reprsente une sorte de cache de donnes. Il stocke en local une partie de la base de donnes qui correspond au rsultat d'une requte de slection adresse par l'application la source de donnes. Ce rsultat est stock dans une table (DataTable) du DataSet. Il est noter que le DataSet peut comporter plusieurs tables cres chacune par une requte de slection. Le composant DataAdapter joue le rle d'intermdiaire entre la source de donnes et le DataSet. Dans ce cadre ce composant permet de : o Rcuprer le rsultat correspondant une requte de slection partir de la source de donnes et remplit avec, le DataSet. o Assurer la mise jour de la source de donnes dans le cas o les donnes locales du DataSet ont t modifies par l'utilisateur. Remarque : La copie locale des donnes stocke par un DataSet se trouve sur la machine cliente du serveur de base de donnes. Dans les applications Windows, il s'agit gnralement de la machine de l'utilisateur (cas des clients lourds). Pour les applications Web ce client est gnralement le serveur qui stocke les pages d'accs aux donnes (Serveurs Web). Les internautes travers leurs navigateurs (clients lgers) ne peuvent recevoir en effet que du HTML ou du javaScript.

Les objets d'adaptation de donnes (DataAdapter)


Le DataAdapter joue le rle d'un pont entre une source de donnes et une table du DataSet. Un DataAdapter fait des accs physiques la source de donnes chose qui le rend dpendant des fournisseurs de donnes. Il est spcifi en ADO.NET par l'interface IDataAdapter. Cette interface possde plusieurs implmentations proposes par les diffrents fournisseurs de donnes. Ces implmentations sont : OleDbDataAdapter, ODBCDataAdapter, SqlDataAdapter, OracleDataAdapter. Un objet DataAdapter possde deux mthodes importantes qui lui permettent d'assurer l'change de donnes entre la source et le DataSet. o La mthode Fill : qui permet de remplir une table du DataSet l'aide du rsultat d'une requte SELECT adresse la source. o La mthode Update : qui permet de mettre jour la source de donnes dans le cas o des modifications ont t apportes sur le DataSet.

Un DataAdapter possde quatre proprits de type Command qui reprsentent les actions que peut assurer l'adaptateur entre une source de donnes et un DataSet. Ces commandes sont :

93

Karim Kalti

Objet Command
SelectCommand InsertCommand UpdateCommand DeleteCommand

Signification
Contient une instruction SQL SELECT permettant de slectionner des donnes partir de la base et de les placer dans un DataSet. Contient une instruction SQL INSERT permettant d'insrer physiquement dans la base de donnes les lignes nouvellement ajoutes au DataSet. Contient une instruction SQL UPDATE permettant d'appliquer la base de donnes les modifications apportes sur les lignes du DataSet. Contient une instruction SQL DELETE permettant de supprimer physiquement de la base de donnes les lignes supprimes dans le DataSet.

L'appel de la mthode Fill du DataAdapter engendre l'excution automatique de l'objet SelectCommand. Le DataSet est alors rempli avec le rsultat de cette commande. L'appel de la mthode Update engendre l'excution des objets InsertCommand, UpdateCommand et DeleteCommand.

L'adaptateur OleDbDataAdapter
DataAdapter est un modle. Les classes rellement instanciables par les programmeurs sont celles qui implmentent ce modle. Ce paragraphe prsente l'implmentation OleDbDataAdapter propose par le fournisseur OleDb. Espace de noms : System.Data.OleDb Constructeurs : Constructeurs
OleDbDataAdapter() OleDbDataAdapter(OleDbCommand) OleDbDataAdapter( string ClauseSelect, string ChanedeConnexion ) OleDbDataAdapter( string ClauseSelect, OleDbConnection Cnn ) Cre un objet DataAdapter non initialis. Cre un objet DataAdapter partir d'un objet OleDbCommand (il s'agit d'une commande de slection. Cette commande est affecte la proprit SelectCommand de l'adaptateur). Cre un objet DataAdapter partir d'une requte de slection qui sera utilise par Fill, et d'une chane de connexion indiquant la source de donnes. Dans ce cas, il n'est pas ncessaire d'tablir la connexion l'aide d'un objet OleDbConnection. Ce dernier est automatiquement cr. Mme effet que le constructeur prcdent. Mais ici l'objet de connexion doit tre explicitement cr et pass au constructeur.

Principales proprits : Les principaux attributs sont : OleDbSelectCommand, OleDbInsertCommand, OleDbUpdateCommand, OleDbDeleteCommand.dont les interfaces viennent d'tre prsentes au paragraphe prcdent.

Principales mthodes : Mthode


int Fill(DataSet) int Fill( DataSet DS, string NomTable ) int Fill( DataSet DS, int StartRecord, int NbRecords; string NomTable )

Signification
Remplit un DataSet pass comme argument avec le rsultat de la requte de slection passe au constructeur. Fill renvoie le nombre de lignes reues du serveur. Une table est ainsi ajoute au DataSet. La table porte par dfaut le nom "Table". Aucune table n'est cependant ajoute au DataSet si ce nombre de lignes est gal zro. Mme effet que la version prcdente mais en donnant la possibilit de spcifier explicitement un nom la table ajoute au DataSet. Si une table qui porte le mme nom existe dj dans le DataSet alors la mthode Fill remplit cette table et aucune nouvelle table n'est cre.

Comme la fonction prcdente mais en remplissant le DataSet avec NbRecords lignes partir de la ligne numro StartRecord. (Les lignes provenant du SELECT).

94

Karim Kalti

int Fill(DataTable)

int Update(DataSet DS)

int Update(DataTable DT)

Insre directement le rsultat du SELECT dans un objet table en mmoire. Engendre l'excution des commandes INSERT, UPDATE et DELETE du DataAdapter afin de rpercuter dans la source de donnes les mises jour effectues dans le DataSet. Update retourne le nombre de lignes mises jour. Dans le cas o la table de la source n'est pas trouve une exception de type SystemException est leve. Dans le cas de l'echec d'une commande (insert,) une exception de type DbConcurrencyException est leve. Engendre l'excution des commandes INSERT, UPDATE et DELETE du DataAdapter afin de rpercuter dans la source de donnes les mises jour effectues dans le DataTable. Update retourne le nombre de lignes mises jour. Dans le cas o la table de la source n'est pas trouve une exception de type SystemException est leve. Dans le cas de l'echec d'une commande (insert,) une exception de type DbConcurrencyException est leve.

L'objet DataSet
Un DataSet reprsente une copie locale d'une partie de la base de donnes. Les donnes de cette copie locale peuvent tre consultes et modifies sans avoir besoin accder au serveur de donnes.

Modle objet d'un DataSet Le modle objet d'un DataSet est donn par la figure suivante :

Un objet DataSet comporte gnralement une collection de tables (objets DataTable) et une collection de relations (objets DataRelation). Chaque table comporte une collection de colonnes (objets DataColumn), une collection de lignes (objets DataRow) et une collection de contraintes (objets Constraint). Les tables peuvent tre cres et ajoutes au DataSet d'une manire explicite ou par appel aux mthodes Fill de plusieurs adaptateurs de donnes. Chaque adaptateur de donnes s'occupe gnralement de la gestion (remplissage et mise jour) d'une table du DataSet.

95

Karim Kalti

Un objet DataSet est compltement dconnect de la source de donnes. Il est indpendant des diffrents fournisseurs de donnes (implmentation unique pour les diffrents fournisseurs OleDb, SQL Server, Oracle,). En .NET, les donnes d'un DataSet sont crites en XML et le schma est crit en XSD (XML Schema Definition Language). Un DataSet peut ainsi importer et exporter d'une manire native les donnes au format XML. Il peut galement tre utilis pour changer des donnes entre diffrentes sources de donnes. Espace de noms : System.Data Constructeurs : Constructeur
DataSet() DataSet(string)

Signification
Cre un objet DataSet. Cre un objet DataSet en lui donnant un nom.

Principales proprits publiques : Nom Type


DataSetName EnforceConstraints Relations Tables string bool DataRelationCollection DataTableCollection

Signification
Nom donn au DataSet non initialis. Indique si les contraintes doivent tre vrifies ou non lors des oprations de mise jour effectues dans le DataSet. (true signifie qu'il y a vrification, c'est la valeur par dfaut pour cette proprit). Collection de relations (objets de type DataRelation) Collection de tables (objets de type DataTable)

Principales mthodes : Mthode


void Clear() DataSet Clone() DataSet Copy() string GetXml() string GetXmlSchema() void Merge(DataSet) void Merge(DataTable)

Signification
Efface le contenu du DataSet en supprimant toutes les lignes des tables. Copie la structure du DataSet (tables, relations, contraintes) sans copier les donnes. Copie la fois la structure et les donnes du DataSet. Retourne la reprsentation XML des donnes stockes dans le DataSet. Retourne le schma XSD de la reprsentation des donnes du DataSet. Fusionne le DataSet pass en argument et son schma avec le DataSet courant. Fusionne la table passe en argument et son schma dans le DataSet courant.

Exemple 1 : On considre la base de donnes Biblio comportant la table Ouvrage donne comme suit : Ouvrage Champ Type Inventaire Entier Titre Chane Anne ddition Entier

96

Karim Kalti

L'exemple suivant montre la cration d'un DataSet qui rcupre en local la liste des ouvrages de la base Biblio. Cette liste est place dans un objet DataTable nomm Ouvrage.
// Cration de la chane de connexion string StrCnn = @"Provider = Microsoft.Jet.OLEDB.4.0; Data Source = C:\Data\Biblio.mdb"; // Cration de l'objet de connexion OleDbConnection Cnn = new OleDbConnection(StrCnn); // Ouverture de la connexion Cnn.Open(); // Texte de la requte qui sera stock dans la proprit SelectCommand de l'adaptateur string StrSelect = "SELECT * FROM Ouvrage"; // Cration de l'adaptateur de donnes OleDbDataAdapter DA = new OleDbDataAdapter(StrSelect,Cnn); // Cration du DataSet DataSet DS = new DataSet(); // Remplissage du DataSet DA.Fill(DS, "Ouvrage");

L'objet DataTable
L'objet DataTable est une reprsentation en mmoire locale (ct client) d'une table de base de donnes. Une table dans un DataSet comporte un schma et des donnes. Le schma est dfini par les colonnes de la table (collection d'objets de type DataColumn) et par les contraintes appliques aux colonnes. Ces contraintes concernent la spcification de la cl primaire (objet UniqueConstraint) et de la cl trangre (objet ForeignKeyConstraint). Les donnes d'une table sont stockes dans des lignes (collection d'objets de type DataRow). Espace de noms : System.Data Constructeurs :
DataTable() DataTable(string) Cre une table sans lui donner de nom. Cre une table en lui donnant un nom.

Principales proprits publiques : Nom


TableName DataSet ChildRelations ParentRelations Columns Rows Constraints PrimaryKey

Type
string DataSet DataRelationCollection DataRelationCollection DataColumnsCollection DataRowCollection Constraintcollection DataColumn[]

Signification
Nom donn la table. En lecture seule, cette proprit permet de rcuprer le DataSet auquel appartient la table. En lecture seule. Cette proprit donne la collection de relations (objets DataRelation) de type enfant de la table. En lecture seule. Cette proprit donne la collection de relations (objets DataRelation) de type parent de la table. En lecture seule. Cette proprit donne la collection de colonnes (objets de type DataColumn) de la table. En lecture seule. Cette proprit donne la collection des lignes (objets de type DataRow) de la table. En lecture seule. Cette proprit donne la collection des contraintes associes la table. En lecture et criture. Cette proprit contient la liste des colonnes qui composent la cl primaire de la table.

Principales mthodes : Mthode


void Clear() DataTable Clone() DataTable Copy() void ImportRow(DataRow dr) DataRow NewRow()

Signification
Efface le contenu d'une table (les lignes). Clone la structure d'une table (schma et contraintes). Copie la fois la structure et les donnes d'une table. Ajoute la ligne dr la table. Crer une nouvelle ligne ayant le mme schma que la table.

97

Karim Kalti

L'objet DataTableCollection
Cet objet reprsente une collection de tables (DataTable). Principales proprits : Nom Type
Count Item int DataTable

Signification
Retourne le nombre de tables dans la collection. C'est un indexeur qui permet d'accder une table particulire de la collection. La table peut tre indexe par un numro (ordre d'ajout de la table dans la collection) ou par son nom.

Principales mthodes : Mthode


DataTable Add(string) void Add(DataTable) void AddRange(DataTable[]) void Clear() bool Contains(string name) int IndexOf(string name) int IndexOf(DataTable) void Remove(string name) void Remove(DataTable) void RemoveAt(int index)

Signification
Ajoute une nouvelle table la collection. La table possde comme nom la chane passe en argument. La mthode retourne une rfrence sur la table ajoute. Ajoute la table passe en argument la collection. Ajoute un tableau de tables la collection. ( la fin de la collection) Supprime toutes les tables de la collection. Vrifie si la collection contient la table dont le nom est pass en argument. Renvoi la position de l'indexe (position ordinale dans la collection) de la table qui est passe ou dont le nom est pass en argument. Supprime de la collection la table qui est passe ou dont le nom est pass en argument. Supprime de la collection la table dont l'indexe est pass en argument.

Exemple 1 : Cet exemple montre les diffrentes possibilits d'accs la table Ouvrage du DataSet DS cr dans l'exemple prcdent.
DS.Tables[0];

Accs l'aide de l'indice de la table dans le DataSet. (Les indices commencent partir de 0. Ils sont affects aux tables suivant l'ordre d'ajout de ces dernires au DataSet.
DS.Tables["Ouvrage"];

Accs l'aide d'un indexeur de la collection Tables qui prend un indice de type chane. Cet indice reprsente le nom de la table accder. Exemple 2: Il est possible de compter le nombre de tables du DataSet et ce l'aide de la proprit Count de la collection Tables du DataSet.
int n = DS.Tables.Count;

Remarque : Les objets DataColumnCollection et DataRowCollection possdent les mmes caractristiques que DataTableCollection. (Ce sont toutes des collections). On trouve ainsi presque les mmes proprits et mthodes mais c'est seulement le type de l'objet manipul par la collection qui change (respectivement DataColumn et DataRow au lieu de DataTable).

L'objet DataColumn
L'objet DataColumn reprsente une colonne d'une table en mmoire. Espace de noms : System.Data Constructeurs :
DataColumn() DataColumn(string N) DataColumn(string N, Type T) Cre une colonne sans lui donner de nom. Cre une colonne tout en lui attribuant un nom. Cre une colonne tout en lui attribuant un nom et un type. Type est une classe du .NET de l'espace de noms System qui permet de stocker des types de donnes.

98

Karim Kalti

Principales proprits publiques : Nom Type


AllowDbNull AutoIncrement AutoIncrementSeed AutoIncrementStep Caption ColumnName DataType DefaultValue Ordinal ReadOnly Unique bool bool int int string string Type Object int bool bool

Signification

Indique si des valeurs nulles peuvent tre introduites dans la colonne. Indique si le contenu de cette colonne doit tre automatiquement incrment lors de chaque ajout. Valeur de dbut d'un champ autoincrment. Valeur d'incrmentation (par dfaut 1). Libell de la colonne. Si ce champ n'est pas explicitement spcifi alors il prend par dfaut la valeur de ColumnName. Nom du champ correspondant la colonne. Type du champ. Valeur par dfaut lors d'un ajout Position de la colonne dans la collection des colonnes de la table. Indique si le contenu de la colonne est en lecture seule. Indique si la valeur de chaque ligne de la colonne doit tre unique.

Les quelques mthodes publiques de DataColumn sont rarement utilises. Exemple 1 : L'accs une colonne d'une table peut se faire de diffrentes manires comme le montrent les quatre instructions quivalentes suivantes :
DS.Tables["Ouvrage"].Columns[0]; DS.Tables["Ouvrage"].Columns["Inventaire"]; DS.Tables[0].Columns[0]; DS.Tables[0].Columns["Inventaire"];

Exemple 2 : Dtermination dynamique de la structure d'un DataSet


// Dtermination dynamique du nombre des tables et de leurs noms Console.WriteLine("Nombre de tables du DataSet : "+DS.Tables.Count); // Liste des noms des tables for(int i=0;i<DS.Tables.Count;i++) Console.WriteLine(DS.Tables[i].TableName+" ("+i+")"); // Dtermination dynamique des structures des tables du DataSet Console.WriteLine("\n\n /////// Structures des tables du DataSet ///////"); foreach(DataTable dt in DS.Tables) { Console.WriteLine("**** Table "+dt.TableName+" ****"); foreach(DataColumn dc in dt.Columns) Console.WriteLine(dc.ColumnName+" ("+dc.DataType.Name+")"); }

L'objet DataRow
L'objet DataRow reprsente une ligne d'une table. Espace de noms : System.Data Constructeurs : Pas de constructeurs explicites (constructeur par dfaut seulement). Gnralement c'est la mthode NewRow de la classe DataTable qui est utilise pour construire un DataRow. Principales proprits : Nom
Item ItemArray RowState Table

Type
Indexeur de la forme Object this[ ] object[] enum DataRowState DataTable

Signification
Indexeur donnant accs au contenu de chaque colonne de la ligne. Dans les crochets de l'indexeur il est possible de spcifier le numro de colonne, le nom de la colonne ou encore un objet DataColumn. Tableau des contenus des diffrentes colonnes de la ligne (contenu de la ligne). Etat de la ligne. RowState peut prendre l'une des valeurs suivantes de l'numration DataRowState : (Detached, Unchanged, Added, Deleted, Modified). Table laquelle appartient la ligne.

99

Karim Kalti

L'tat d'une ligne L'tat d'une ligne est dtermin par la proprit RowState de la classe DataRow. Les valeurs possibles de cette proprit sont celles de l'numration DataRowState : Valeur de DataRowState
Unchanged Added Modified Deleted

Signification
Aucune modification n'a t effectue sur la ligne depuis l'appel AcceptChanges ou depuis la cration de la ligne l'aide de la mthode Fill du DataAdapter. La ligne a t ajoute la table mais la mthode AcceptChanges n'a pas t appele. Certains lments de la ligne ont t modifis. La ligne a t supprime de la table et AcceptChanges n'a pas t encore appele. Cette valeur signifie que la ligne a t cre mais qu'elle ne fait pas partie d'un DataRowCollection. Le RowState d'une ligne cre prend la valeur Detached. Une fois la ligne ajoute un DataRowCollection l'aide de la mthode Add, la proprit RowState prend la valeur Added. La valeur Detached est galement dfinie pour une ligne qui a t supprime d'un DataRowCollection l'aide de la mthode Remove ou par la mthode Delete suivie de l'appel la mthode AcceptChanges.

Detached

Le DataAdapter se base sur la proprit RowState pour dcider de la commande excuter pour chaque ligne lors de l'appel de la mthode Update : (InsertCommand pour Added, UpdateCommand pour Modified et DeleteCommand pour Deleted). La version d'une ligne La version d'une ligne peut prendre l'une des valeurs de l'numration DataRowVersion. DataRowVersion
Current Default Original Proposed

Signification
C'est la version qui contient les valeurs actuelles de la ligne. Cette version de ligne n'existe pas pour les lignes dont le RowState est Deleted. C'est la version par dfaut d'une ligne particulire. La version par dfaut d'une ligne Added, Modified ou Unchanged est Current. La version par dfaut d'une ligne Deleted est Original. La version par dfaut d'une ligne Detached est Proposed. C'est la version qui contient les valeurs d'origine de la ligne. Cette version de ligne n'existe pas pour les lignes ayant un RowState Added. C'est la version qui contient les valeurs proposes d'une ligne. Cette version existe pendant une opration de modification sur une ligne ou pour une ligne qui ne fait pas partie d'un DataRowCollection.

Il est possible de savoir si une version particulire d'une ligne existe et ce en utilisant la mthode HasVersion. Les versions des lignes sont essentiellement utilises durant les oprations de mise jour de donnes partir du DataSet vers la base de donnes.

Principales mthodes : Mthode


void AcceptChanges()

Signification
La mthode AcceptChanges permet de valider tous les changements effectus sur une ligne depuis le dernier appel AcceptChanges. Si le RowState d'une ligne est Added ou Modified alors il devient Unchanged. Si le RowState d'une ligne est Deleted alors la ligne sera supprime de la table et son tat devient Detached. Retourne une valeur indiquant si la version passe en argument existe pour la ligne courante.

bool HasVersion(DataRowVersion)

Sur le plan pratique l'appel explicite de AcceptChanges est rare. Cet appel est souvent implicite. Il est effectu surtout par la mthode Update du DataAdapter. Ceci permet de ne faire que la mise jour des nouvelles modifications si un autre appel Update est effectu. L'appel implicite de AcceptChanges aprs l'appel de la mthode Fill du DataAdapter est dtermin quant lui par la proprit AcceptChangesDuringFill de la classe DataAdapter (la valeur par dfaut est true. Elle signifie qu'il y a appel). La mthode AcceptChanges est membre non seulement de la classe DataRow mais galement des classes DataSet et DataTable. o Pour DataRow son effet touche la ligne. o Pour DataTable son effet touche toutes les lignes d'une table. o Pour DataSet son effet touche toutes les lignes de toutes les tables du DataSet.

100

Karim Kalti

Exemple 1 : Accs une ligne L'accs la nime ligne d'une table se fait comme suit :
DS.Tables["Ouvrage"].Rows[n-1];

Les indices commencent toujours partir de 0. Si la n ime ligne n'existe pas alors une exception sera leve. L'accs au mime champ de la nime ligne se fait comme suit :
// Accs l'aide des indices DS.Tables["Ouvrage"].Rows[n-1][m-1]; // Accs travers le nom du champ. DS.Tables["Ouvrage"].Rows[n-1]["Inventaire"];

Exemple 2: Affichage du contenu d'une table


foreach(DataRow rw in DS.Tables["Ouvrage"].Rows) { Console.WriteLine("************************************"); Console.WriteLine("Inventaire : "+rw["Inventaire"]); Console.WriteLine("Titre : "+rw["Titre"]); Console.WriteLine("Anne d'dition : "+rw["Anne d'dition"]); }

Exemple 3: une autre version de l'exemple prcdent.


for(int i=0;i<DS.Tables["Ouvrage"].Rows.Count;i++) { Console.WriteLine("************************************"); Console.WriteLine("Inventaire : "+DS.Tables["Ouvrage"].Rows[i]["Inventaire"]); Console.WriteLine("Titre : "+DS.Tables["Ouvrage"].Rows[i]["Titre"]); Console.WriteLine("Anne d'dition : "+DS.Tables["Ouvrage"].Rows[i]["Anne d'dition"]); }

Exemple 4 : Code complet


class DisconnectedMode { private string StrCnn; // La private OleDbConnection Cnn; private string StrSelect; // private OleDbDataAdapter DA; private DataSet DS;

chane de connexion // Objet de Connexion Texte de la commande Select du DataAdapter // Adaptateur de donnes

public DisconnectedMode(string strcnn) { StrCnn =strcnn; Cnn = new OleDbConnection(StrCnn); Cnn.Open(); StrSelect = "SELECT * FROM Ouvrage"; DA = new OleDbDataAdapter(StrSelect,Cnn); DS = new DataSet(); // Remplissage du DataSet DA.Fill(DS, "Ouvrage"); } public void Disconnect() { //Fermeture de la connexion Cnn.Close(); } public void ShowStructure() { // Dtermination dynamique du nombre des tables et de leurs noms Console.WriteLine("Nombre de tables du DataSet : "+DS.Tables.Count); for(int i=0;i<DS.Tables.Count;i++) Console.WriteLine(DS.Tables[i].TableName+" ("+i+")"); // Dtermination dynamique des structures des tables Console.WriteLine("\n/////// Structures des tables du DataSet ///////\n");

foreach(DataTable dt in DS.Tables) { Console.WriteLine("**** Table "+dt.TableName+" ****");

101

Karim Kalti

foreach(DataColumn dc in dt.Columns) Console.WriteLine(dc.ColumnName+" ("+dc.DataType.Name+")"); } } public void ShowContent() { foreach(DataRow rw in DS.Tables["Ouvrage"].Rows) { Console.WriteLine("************************************"); Console.WriteLine("Inventaire : "+rw["Inventaire"]); Console.WriteLine("Titre : "+rw["Titre"]); Console.WriteLine("Anne d'dition : "+rw["Anne d'dition"]); } } } class Prog { public static void Main() { DisconnectedMode ins = new DisconnectedMode("C:\\Data\\Biblio.mdb"); ins.ShowStructure(); ins.ShowContent(); ins.Disconnect(); } }

L'objet CommandBuilder
L'objet CommandBuilder est utilis pour gnrer d'une manire automatique les objets DeleteCommand, InsertCommand et UpdateCommand du DataAdapter ncessaires pour effectuer la mise jour des donnes partir du DataSet. L'objet CommandBuilder se base sur le texte de l'objet SelectCommand du DataAdapter pour dduire les informations ncessaires cette gnration comme le nom de la table, la liste des champs rcuprs, les contraintes, etc. L'objet CommandBuilder est essentiellement utilis pour gnrer des commandes relatives des tables simples. (Gnralement pour les tables du DataSet issues d'une seule table de la source de donnes. Le CommandBuilder ne convient pas aux tables simples cres par un SELECT qui ne retourne pas parmi la liste des champs le champ cl. Il ne convient pas galement aux tables qui rsultent d'une opration de jointure). L'objet CommandBuilder est dpendant du fournisseur de donnes. L'implmentation propose par le fournisseur OleDb est OleDbCommandBuilder.

Espace de noms : System.Data.OleDb Quelques constructeurs :


Cre un OleDbCommandBuilder non initialis. Cre un OleDbCommandBuilder et l'associe un adaptateur de public OleDbCommandBuilder(OleDbDataAdapter); donnes. public OleDbCommandBuilder();

Principales proprits : Nom Type


DataAdapter QuotePrefix OleDbDataAdapter string

Signification
Obtient ou dfinit un objet OleDbDataAdapter pour lequel les instructions SQL sont automatiquement gnres. Obtient ou dfinit le ou les caractres de dbut utiliser lors de la spcification d'objets de base de donnes (par exemple, des tables ou colonnes) dont les noms contiennent des caractres tels que des espaces ou des jetons rservs. Obtient ou dfinit le ou les caractres de fin utiliser lors de la spcification d'objets de base de donnes (par exemple, des tables ou colonnes) dont les noms contiennent des caractres tels que des espaces ou des jetons rservs.

QuoteSuffix

string

102

Karim Kalti

Principales mthodes : Mthode


public void RefreshSchema();

Signification
Actualise les informations de schma de la base de donnes utilises pour gnrer des instructions INSERT, UPDATE ou DELETE. Cette mthode doit tre appele si l'adaptateur de donnes change sa commande SELECT aprs la construction du CommandBuilder. Cet appel va engendrer alors l'actualisation des informations de schma du CommandBuilder et la construction de commandes valides. Obtient l'objet OleDbCommand gnr automatiquement et requis pour effectuer des suppressions au niveau de la source de donnes. Obtient l'objet OleDbCommand gnr automatiquement et requis pour effectuer des insertions au niveau de la source de donnes. Obtient l'objet OleDbCommand gnr automatiquement et requis pour effectuer des mises jour au niveau de la source de donnes.

OleDbCommand GetDeleteCommand(); OleDbCommand GetInsertCommand(); OleDbCommand GetUpdateCommand();

La mise jour des donnes partir d'un DataSet


La mise jour des donnes d'un DataSet passe par l'utilisation des objets DeleteCommand, InsertCommand et UpdateCommand du DataAdapter. Ces commandes sont automatiquement excutes suite l'appel de la mthode Update du DataAdapter. Il existe globalement trois choix pour la gnration des commandes de mise jour du DataAdapter : o La gnration l'aide des assistants. o La gnration par le dveloppeur. o La gnration l'aide de l'objet CommandBuilder. La gnration l'aide des assistants Voir annexe. La gnration par le dveloppeur La gnration par le dveloppeur d'une commande de mise jour doit suivre les 3 tapes suivantes : La cration de la chane qui contient le texte de la requte. Si la requte est paramtre alors le texte doit comporter des espaces rservs. La cration d'un objet Command bas sur cette requte. La cration d'une collection d'objets de type Parameter. Le nombre de ces objets doit correspondre au nombre des espaces rservs de la requte. Une fois initialiss, ces objets doivent tre ajouts la collection Parameters de l'objet Command cr dans l'tape prcdente. Ces trois tapes doivent tre effectues pour chacune des commandes DeleteCommand, InsertCommand et UpdateCommand du DataAdapter comme le montre l'exemple suivant :

Exemple : Mise jour des donnes l'aide d'un DataAdapter Cet exemple montre la mise jour des modifications apportes aux donnes de la table Ouvrage situe dans le DataSet vers la table qui lui correspond dans la source de donnes. Le tableau suivant donne l'tat de la table Ouvrage avant la mise jour des donnes :

Ouvrage Inventaire Titre Anne d'dition 1 Programmation C 1996 2 Les rseaux 2004 3 Internet 2000 4 Les bases de donnes 1998

103

Karim Kalti

using System; using System.Data; using System.Data.OleDb; class DisconnectedMode { private string StrCnn; // La chane de connexion private OleDbConnection Cnn; // Objet de Connexion private string StrSelect; // Texte de la commande Select du DataAdapter private OleDbDataAdapter DA; // Adaptateur de donnes private DataSet DS; private OleDbCommand DelCmd; private OleDbCommand InsCmd; private OleDbCommand UpdateCmd; public DisconnectedMode() {StrCnn = @"Provider = Microsoft.Jet.OLEDB.4.0; Data Source = C:\Data\Biblio.mdb"; Cnn = new OleDbConnection(StrCnn); Cnn.Open(); StrSelect = "SELECT * FROM Ouvrage"; DA = new OleDbDataAdapter(StrSelect,Cnn); DS = new DataSet(); // Remplissage du DataSet DA.Fill(DS, "Ouvrage"); } public void Disconnecte() { Cnn.Close();} public void ShowContent() { foreach(DataRow rw in DS.Tables["Ouvrage"].Rows) { Console.WriteLine("************************************"); Console.WriteLine("Inventaire : "+rw["Inventaire"]); Console.WriteLine("Titre : "+rw["Titre"]); Console.WriteLine("Anne d'dition : "+rw["Anne d'dition"]); } } public void UpdateDataSet() { // Code d'ajout d'une ligne par programmation DataRow dr = DS.Tables["Ouvrage"].NewRow(); dr["Inventaire"]=5; dr["Titre"]= "UML"; dr["Anne d'dition"]=2004; DS.Tables["Ouvrage"].Rows.Add(dr); // Code de Modification d'une ligne DS.Tables["Ouvrage"].Rows[0]["Titre"]="Programmation C++"; DS.Tables["Ouvrage"].Rows[0]["Anne d'dition"]=2003; // Code de suppression d'une ligne DS.Tables["Ouvrage"].Rows[2].Delete(); } public void UpdateDataSource() { // Cration de la commande de suppression string StrDelete = "DELETE FROM Ouvrage WHERE Inventaire = ?"; DelCmd = new OleDbCommand(StrDelete, Cnn); OleDbParameter Param = new OleDbParameter(); Param.ParameterName="OriginInventaire"; Param.OleDbType = OleDbType.Integer; Param.Direction = ParameterDirection.Input; Param.IsNullable = false; Param.SourceColumn="Inventaire"; Param.SourceVersion=DataRowVersion.Original; DelCmd.Parameters.Add(Param); // Cration de la commande d'insertion string StrInsert = "INSERT INTO Ouvrage VALUES (?,?,?)"; InsCmd = new OleDbCommand(StrInsert, Cnn); OleDbParameter ParamInventaire = new OleDbParameter("ParInv",OleDbType.Integer,0, ParameterDirection.Input,false,(byte)0,(byte)0,"Inventaire",DataRowVersion.Current,null); OleDbParameter ParamTitre = new OleDbParameter("ParTitre",OleDbType.VarWChar,50, ParameterDirection.Input,false,(byte)0,(byte)0,"Titre",DataRowVersion.Current,null);

104

Karim Kalti

OleDbParameter ParamEdition = new OleDbParameter("ParEdition",OleDbType.Integer,0, ParameterDirection.Input,false,(byte)0,(byte)0,"Anne d'dition",DataRowVersion.Current, null); InsCmd.Parameters.Add(ParamInventaire); InsCmd.Parameters.Add(ParamTitre); InsCmd.Parameters.Add(ParamEdition); // Cration de la commande de modification string StrUpdate = "Update Ouvrage SET Inventaire=?, Titre=?, [Anne d'dition]=? WHERE Inventaire=? AND (Titre = ?) AND ([Anne d'dition]= ? OR ? IS NULL AND [Anne d'dition] IS NULL)"; UpdateCmd = new OleDbCommand(StrUpdate, Cnn); UpdateCmd.Parameters.Add(new OleDbParameter("NouvInventaire",OleDbType.Integer,0, "Inventaire")); UpdateCmd.Parameters.Add(new OleDbParameter("NouvTitre", OleDbType.VarWChar,50,"Titre")); UpdateCmd.Parameters.Add(new OleDbParameter("NouvEdition", OleDbType.Integer,0,"Anne d'dition")); UpdateCmd.Parameters.Add(new OleDbParameter("OriginalInv", OleDbType.Integer,0, ParameterDirection.Input,false,(byte)0,(byte)0,"Inventaire",DataRowVersion.Original, null)); UpdateCmd.Parameters.Add(new OleDbParameter("OriginalTitre", OleDbType.VarWChar,50, ParameterDirection.Input, false,(byte)0,(byte)0,"Titre",DataRowVersion.Original,null)); UpdateCmd.Parameters.Add(new OleDbParameter("OriginalEdition1", OleDbType.Integer,0, ParameterDirection.Input,false,(byte)0,(byte)0,"Anne d'dition",DataRowVersion.Original, null)); UpdateCmd.Parameters.Add(new OleDbParameter("OriginalEdition2", OleDbType.Integer,0, ParameterDirection.Input,false,(byte)0,(byte)0,"Anne d'dition",DataRowVersion.Original, null)); // Ajout des commandes l'adaptateur DA.DeleteCommand=DelCmd; DA.InsertCommand=InsCmd; DA.UpdateCommand=UpdateCmd; DA.Update(DS.Tables["Ouvrage"]); } } class Prog { public static void Main() { DisconnectedMode ins = new DisconnectedMode(); ins.UpdateDataSet(); ins.UpdateDataSource(); ins.ShowContent(); } }

Quelques prcisions : Il n'est pas ncessaire de dfinir la prcision pour les types numriques qui ne sont pas du type OleDbType.Decimal. Si la version d'une ligne n'est pas explicitement dfinie alors elle prend par dfaut la valeur Current. Dans le mode dconnect, la proprit Value d'un paramtre d'un objet commande d'un DataAdapter est dtermine d'une manire automatique en se basant sur les proprits SourceVersion et SourceColumn. Commentaire sur la commande de suppression : A chaque fois que le DataAdapter trouve une ligne dont l'tat est Deleted, il excute la commande DeleteCommand du DataAdapter. Cette commande rcupre la valeur originale de la ligne pour valoriser le paramtre de la requte qu'elle encapsule puis supprime physiquement cette ligne partir de la source de donnes. (Il est noter qu'une ligne supprime dans le DataSet ne possde pas de version courrante).

105

Karim Kalti

Commentaire sur la commande d'insertion : A chaque fois que le DataAdapter trouve une ligne dont l'tat est Added, il excute la commande InsertCommand du DataAdapter. Cette commande rcupre la version courante (la version par dfaut) de la ligne dans le DataSet et ce pour valoriser les paramtres de la requte puis insre physiquement cette ligne dans la source de donnes. Commentaire sur la commande de modification : A chaque fois que le DataAdapter trouve une ligne dont l'tat est Modified, il excute la commande UpdateCommand du DataAdapter. Cette commande rcupre la valeur courante (version par dfaut) de la ligne pour valoriser la premire partie des paramtres de la requte (les paramtres avant le WHERE). Les conditions introduites par le WHERE permettent de vrifier si la ligne n'a pas t modifie dans la source de donnes (par un autre utilisateur) depuis son chargement en local dans le DataSet (car dans le mode dconnect de tels changements ne peuvent pas tre immdiatement visibles dans le DataSet). Les paramtres utiliss par ces conditions prennent leurs valeurs de la version originale de la ligne (avant modification) et non de la version courante comme c'est le cas des paramtres de la premire partie de la requte. L'expression Champ=NULL est toujours fausse (en BD, NULL n'est pas une valeur mais signifie que le champ n'a pas de valeur). Ainsi chaque fois qu'un champ peut tre NULL, le critre doit tre de la forme Champ = ? OR ? IS NULL AND Champ IS NULL ce qui veut dire que le champ est gal au paramtre ou le champ et le paramtre sont tous les deux NULL. Cette condition est obligatoire pour les champs qui peuvent accepter la valeur NULL (IsNullable = true). La gnration l'aide de l'objet CommandBuilder Le code de mise jour des donnes en utilisant un objet CommandBuilder est assez simple. Il se prsente comme suit :
string StrCnn = @"Provider = Microsoft.Jet.OLEDB.4.0; Data Source = C:\Data\Biblio.mdb"; OleDbConnection Cnn = new OleDbConnection(StrCnn); Cnn.Open(); string StrSelect = "SELECT * FROM Ouvrage"; OleDbDataAdapter DA = new OleDbDataAdapter(StrSelect,Cnn); OleDbCommandBuilder CB = new OleDbCommandBuilder(DA); CB.QuotePrefix = "["; CB.QuoteSuffix = "]"; DataSet DS = new DataSet(); DA.Fill(DS, "Ouvrage"); // Mettre ici le code de modification des donnes du DataSet. // Mise jour des donnes vers la source DA.Update(DS,"Ouvrage"); Cnn.Close();

L'objet DataRelation
Cette classe reprsente une relation Parent/Enfant entre deux tables du DataSet. Espace de noms : System.Data.DataRelation Quelques constructeurs :
DataRelation( string N, DataColumn P, DataColumn C) DataRelation( string N, DataColumn[] P, DataColumn[] C) Cre une nouvelle relation qui possde comme nom interne N, comme champ parent P et comme champ enfant C.

Cre une nouvelle relation qui possde comme nom interne N, comme champs parents P et comme champs enfants C.

106

Karim Kalti

Principales proprits : Nom


RelationName ChildColumns ParentColumns ChildTable ParentTable DataSet

Type
String DataColumn[] DataColumn[] DataTable DataTable DataSet

Signification
Nom de la relation. En lecture seule. Stocke la liste des colonnes "enfants" de la relation. En lecture seule. Stocke la liste des colonnes "parents" de la relation. En lecture seule. Indique la table contenant le (les) champ(s) "enfant(s)" de la relation. En lecture seule. Indique la table contenant le (les) champ(s) "parent(s)" de la relation. En lecture seule. Indique le DataSet auquel appartient la relation.

Exemple : Ajout d'une relation entre Ouvrage et Prt On considre les trois tables suivantes : Ouvrage Champ Type Champ Type Champ Type Inventaire Entier Id Entier Numro Entier Titre Chane Nom Chane Inventaire Chane IdLecteur Entier Date Date Anne ddition Entier

Lecteur

Prt

L'exemple suivant montre l'ajout d'une relation entre les deux tables Ouvrage et Prt.
DataColumn ParentCol; DataColumn ChildCol; ParentCol = DS.Tables["Ouvrage"].Columns["Inventaire"]; ChildCol = DS.Tables["Prt"].Columns["Inventaire"]; DataRelation RelOuvragePret = new DataRelation("InventaireRelation", ParentCol, ChildCol); DS.Relations.Add(RelOuvragePret);

Ou d'une manire quivalente :


DS.Relations.Add("InventaireRelation",DS.Tables["Ouvrage"].Columns["Inventaire"], DS.Tables["Prt"].Columns["Inventaire"]);

Les objets contraintes


Une contrainte est une rgle utilise pour maintenir l'intgrit des donnes dans un objet DataTable. Les objets DataTable supportent deux types de contraintes reprsents par les classes UniqueConstraint et ForeignKeyConstraint. La classe UniqueConstraint UniqueConstraint permet de spcifier que les valeurs d'une colonnes ou de plusieurs colonnes doivent tre uniques. Si la proprit EnforceConstraints du DataSet est true, alors la violation de cette contrainte va engendrer la leve d'une exception. Quelques constructeurs :
public UniqueConstraint(string N, DataColumn Cl); public UniqueConstraint(string N, DataColumn[] Cl); public UniqueConstraint(string N, DataColumn Cl, bool b); Cre une contrainte nomme N et associe la colonne Cl. Cre une contrainte nomme N et associe plusieurs colonnes. Cre une contrainte nomme N, associe une colonne Cl et indique si la contrainte est une cl primaire. Cre une contrainte nomme N, associe plusieurs colonnes et indique si la contrainte est une cl primaire.

public UniqueConstraint(string N, DataColumn[] Cl, bool b);

107

Karim Kalti

Principales proprits : Nom


ConstraintName Table Columns IsPrimaryKey

Type
string DataTable Collection Bool

Signification
Nom de la contrainte (lecture seule) Nom de la table laquelle est associe la contrainte. Liste des colonnes concernes par la contrainte. Indique si la contrainte est une cl primaire. (true si c'est une contrainte de cl, c'est la valeur par dfaut).

Exemple : Ajout d'une UniqueConstraint une table (Source : MSDN)


private void MakeTableWithUniqueConstraint(){ DataTable myTable = new DataTable("myTable"); DataColumn idCol = new DataColumn("id",System.Type.GetType("System.Int32")); DataColumn NameCol = new DataColumn("Name", System.Type.GetType("System.String")); myTable.Columns.Add(idCol); myTable.Columns.Add(NameCol); AddUniqueConstraint(myTable); // Add one row to the table. DataRow myRow; myRow = myTable.NewRow(); myRow["id"] = 1; myRow["Name"] = "John"; myTable.Rows.Add(myRow); // Display the table in a DataGrid control. dataGrid1.DataSource=myTable;

// Try to add an identical row. try{ myRow = myTable.NewRow(); myRow["id"] = 1; myRow["Name"] = "John"; myTable.Rows.Add(myRow); } catch(Exception e) { System.Diagnostics.EventLog log = new System.Diagnostics.EventLog(); log.Source = "My Application"; log.WriteEntry(e.ToString()); Console.WriteLine("Exception of type {0} occurred.", e.GetType()); } } private void AddUniqueConstraint (DataTable myTable){ // Create the DataColumn array. DataColumn[] myColumns = new DataColumn[2]; myColumns[0] = myTable.Columns["id"]; myColumns[1] = myTable.Columns["Name"]; UniqueConstraint myUniqueConstraint; myUniqueConstraint = new UniqueConstraint("idNameConstraint", myColumns); myTable.Constraints.Add(myUniqueConstraint); }

La classe ForeignKeyConstraint Cette contrainte permet de spcifier comment agir lorsqu'une donne dpendante de deux ou plusieurs tables diffrentes est supprime. Faut-il la supprimer dans les autres tables, la mettre null ou mettre une valeur par dfaut. Quelques constructeurs :
public ForeignKeyConstraint(string N, DataColumn Parent, DataColumn Child); public ForeignKeyConstraint(string N, DataColumn[] Parent, DataColumn[] Child); Cre une contrainte nomme N entre deux colonnes Parent et Enfant. Cre une contrainte nomme N entre un ensemble de colonnes Parents et un ensemble de colonnes Enfants.

108

Karim Kalti

Principales proprits : Nom Type


ConstraintName Table Columns RelatedTable RelatedColumns DeleteRule UpdateRule string DataTable Collection DataTable Collection Rule Rule

Signification
Nom de la contrainte (lecture seule) Nom de la table "enfant" associe la contrainte. Liste des colonnes enfants de la contrainte. Nom de la table "Parent" de la contrainte. Liste des colonnes "Parent" de la contrainte. Permet de spcifier comment agir sur les donnes dpendantes lorsqu'une ligne est supprime. Les actions possibles sont donnes par l'numration Rule Permet de spcifier comment agir sur les donnes dpendantes lorsqu'une ligne est mise jour. Les actions possibles sont donnes par l'numration Rule

L'numration Rule Valeur


Cascade None SetDefault SetNull

Signification

Supprime ou met jour les lignes relies la ligne supprime ou modifie. C'est la valeur par dfaut pour les proprit DeleteRule et UpdateRule. Aucune action n'est effectue sur les lignes relies. Met les valeurs des colonnes des lignes relies la valeur spcifie dans la proprit DefaultValue de l'objet DataColumn. Met les valeurs dans les lignes relies la valeur DBNull.

Exemple : Ajout d'une contrainte de cl trangre


DataColumn pCol; DataColumn cCol; ForeignKeyConstraint myFKC; pCol = DS.Tables["Ouvrage"].Columns["Inventaire"]; cCol = DS.Tables["Prt"].Columns["Inventaire"]; myFKC = new ForeignKeyConstraint("PrtFKConstraint", pCol, cCol); myFKC.DeleteRule = Rule.SetNull; myFKC.UpdateRule = Rule.Cascade; myFKC.AcceptRejectRule = AcceptRejectRule.Cascade; DS.Tables["Prt"].Constraints.Add(MyFKC); DS.EnforceConstraints = true;

109

Karim Kalti

Annexe A
Code gnr par VS.NET 2003 suite la cration l'aide de l'assistant d'un Adaptateur de donnes et d'un DataSet

// Dans private private private private private private private

la partie attritbuts System.Data.OleDb.OleDbDataAdapter oleDbDataAdapter1; System.Data.OleDb.OleDbCommand oleDbSelectCommand1; System.Data.OleDb.OleDbCommand oleDbInsertCommand1; System.Data.OleDb.OleDbCommand oleDbUpdateCommand1; System.Data.OleDb.OleDbCommand oleDbDeleteCommand1; System.Data.OleDb.OleDbConnection oleDbConnection1; System.Data.DataSet dataSet1;

-----------------------------------------------------------------

// Dans la mthode InitializeComponents this.oleDbDataAdapter1 = new System.Data.OleDb.OleDbDataAdapter(); this.oleDbDeleteCommand1 = new System.Data.OleDb.OleDbCommand(); this.oleDbConnection1 = new System.Data.OleDb.OleDbConnection(); this.oleDbInsertCommand1 = new System.Data.OleDb.OleDbCommand(); this.oleDbSelectCommand1 = new System.Data.OleDb.OleDbCommand(); this.oleDbUpdateCommand1 = new System.Data.OleDb.OleDbCommand(); this.dataSet1 = new System.Data.DataSet(); ((System.ComponentModel.ISupportInitialize)(this.dataSet1)).BeginInit(); // oleDbDataAdapter1 this.oleDbDataAdapter1.DeleteCommand = this.oleDbDeleteCommand1; this.oleDbDataAdapter1.InsertCommand = this.oleDbInsertCommand1; this.oleDbDataAdapter1.SelectCommand = this.oleDbSelectCommand1; // Le Mapping est utilis pour faire la correspondance entre les noms utiliss par le DataSet et ceux utiliss par // la source de donnes. Il peut tre exploit pour modifier les noms au niveau du DataSet. this.oleDbDataAdapter1.TableMappings.AddRange(new System.Data.Common.DataTableMapping[] { new System.Data.Common.DataTableMapping("Table","Ouvrage",new System.Data.Common.DataColumnMapping[]{ new System.Data.Common.DataColumnMapping("Anne d\'dition", "Anne d\'dition"), new System.Data.Common.DataColumnMapping("Inventaire", "Inventaire"), new System.Data.Common.DataColumnMapping("Titre", "Titre")})}); this.oleDbDataAdapter1.UpdateCommand = this.oleDbUpdateCommand1; // oleDbDeleteCommand1 this.oleDbDeleteCommand1.CommandText = "DELETE FROM Ouvrage WHERE (Inventaire = ?) AND ([Anne d\'dition] = ? OR ? IS NUL" +"L AND [Anne d\'dition] IS NULL) AND (Titre = ?)"; this.oleDbDeleteCommand1.Connection = this.oleDbConnection1; this.oleDbDeleteCommand1.Parameters.Add(new System.Data.OleDb.OleDbParameter("Original_Inventaire", System.Data.OleDb.OleDbType.Integer, 0, System.Data.ParameterDirection.Input, false, ((System.Byte)(0)), ((System.Byte)(0)), "Inventaire", System.Data.DataRowVersion.Original, null)); this.oleDbDeleteCommand1.Parameters.Add(new System.Data.OleDb.OleDbParameter("Original_Anne_d\'dition", System.Data.OleDb.OleDbType.Integer, 0, System.Data.ParameterDirection.Input, false, ((System.Byte)(0)), ((System.Byte)(0)), "Anne d\'dition", System.Data.DataRowVersion.Original, null)); this.oleDbDeleteCommand1.Parameters.Add(new System.Data.OleDb.OleDbParameter("Original_Anne_d\'dition1", System.Data.OleDb.OleDbType.Integer, 0, System.Data.ParameterDirection.Input,

false,

110

Karim Kalti

((System.Byte)(0)), ((System.Byte)(0)), System.Data.DataRowVersion.Original, null));

"Anne

d\'dition",

this.oleDbDeleteCommand1.Parameters.Add(new System.Data.OleDb.OleDbParameter("Original_Titre", System.Data.OleDb.OleDbType.VarWChar, 50, System.Data.ParameterDirection.Input, false, ((System.Byte)(0)), ((System.Byte)(0)), "Titre", System.Data.DataRowVersion.Original, null)); // oleDbConnection1 this.oleDbConnection1.ConnectionString = @"Jet OLEDB:Global Partial Bulk Ops=2;Jet OLEDB:Registry Path=;Jet OLEDB:Database Locking Mode=1;Data Source=""C:\Data\Biblio.mdb""; Jet OLEDB:Engine Type=5;Provider=""Microsoft.Jet.OLEDB.4.0"";Jet OLEDB:System database=;Jet OLEDB:SFP=False;persist security info=False;Extended Properties=;Mode=Share Deny None;Jet OLEDB:Encrypt Database=False;Jet OLEDB:Create System Database=False;Jet OLEDB:Don't Copy Locale on Compact=False;Jet OLEDB:Compact Without Replica Repair=False;User ID=Admin;Jet OLEDB:Global Bulk Transactions=1"; // oleDbInsertCommand1 this.oleDbInsertCommand1.CommandText = "INSERT INTO Ouvrage([Anne d\'dition], Inventaire, Titre) VALUES (?, ?, ?)"; this.oleDbInsertCommand1.Connection = this.oleDbConnection1; this.oleDbInsertCommand1.Parameters.Add(new System.Data.OleDb.OleDbParameter("Anne_d\'dition", System.Data.OleDb.OleDbType.Integer, 0, "Anne d\'dition")); this.oleDbInsertCommand1.Parameters.Add(new System.Data.OleDb.OleDbParameter("Inventaire", System.Data.OleDb.OleDbType.Integer, 0, "Inventaire")); this.oleDbInsertCommand1.Parameters.Add(new System.Data.OleDb.OleDbParameter("Titre", System.Data.OleDb.OleDbType.VarWChar, 50, "Titre"));

// oleDbSelectCommand1 this.oleDbSelectCommand1.CommandText = "SELECT [Anne d\'dition], Ouvrage"; this.oleDbSelectCommand1.Connection = this.oleDbConnection1;

Inventaire,

Titre

FROM

// oleDbUpdateCommand1 this.oleDbUpdateCommand1.CommandText = "UPDATE Ouvrage SET [Anne d\'dition] = ?, Inventaire = ?, Titre = ? WHERE (Inventaire = ?) AND ([Anne d\'dition] = ? OR ? IS NULL AND [Anne d\'dition] IS NULL) AND (Titre = ?)"; this.oleDbUpdateCommand1.Connection = this.oleDbConnection1; this.oleDbUpdateCommand1.Parameters.Add(new System.Data.OleDb.OleDbParameter("Anne_d\'dition", System.Data.OleDb.OleDbType.Integer, "Anne d\'dition"));

0,

this.oleDbUpdateCommand1.Parameters.Add(new System.Data.OleDb.OleDbParameter("Inventaire", System.Data.OleDb.OleDbType.Integer, 0, "Inventaire")); this.oleDbUpdateCommand1.Parameters.Add(new System.Data.OleDb.OleDbParameter("Titre", System.Data.OleDb.OleDbType.VarWChar, 50, "Titre")); this.oleDbUpdateCommand1.Parameters.Add(new System.Data.OleDb.OleDbParameter("Original_Inventaire", System.Data.OleDb.OleDbType.Integer, 0, System.Data.ParameterDirection.Input, false, ((System.Byte)(0)), ((System.Byte)(0)), "Inventaire", System.Data.DataRowVersion.Original, null)); this.oleDbUpdateCommand1.Parameters.Add(new System.Data.OleDb.OleDbParameter("Original_Anne_d\'dition", System.Data.OleDb.OleDbType.Integer, 0, System.Data.ParameterDirection.Input, false, ((System.Byte)(0)), ((System.Byte)(0)), "Anne d\'dition", System.Data.DataRowVersion.Original, null)); this.oleDbUpdateCommand1.Parameters.Add(new System.Data.OleDb.OleDbParameter("Original_Anne_d\'dition1", System.Data.OleDb.OleDbType.Integer, 0, System.Data.ParameterDirection.Input, false, ((System.Byte)(0)), ((System.Byte)(0)), "Anne d\'dition", System.Data.DataRowVersion.Original, null)); this.oleDbUpdateCommand1.Parameters.Add(new System.Data.OleDb.OleDbParameter("Original_Titre", System.Data.OleDb.OleDbType.VarWChar, 50, System.Data.ParameterDirection.Input, false, ((System.Byte)(0)), ((System.Byte)(0)), "Titre", System.Data.DataRowVersion.Original, null)); // dataSet1 this.dataSet1.DataSetName = "NewDataSet"; this.dataSet1.Locale = new System.Globalization.CultureInfo("fr-FR"); ((System.ComponentModel.ISupportInitialize)(this.dataSet1)).EndInit();

111

Karim Kalti

Dveloppement d'applications Web dynamiques


Rappel
Site Web : Un site Web est un ensemble de pages Web, gnralement lies entre elles par des liens hypertextes et stockes sur un ordinateur connect en permanence Internet. Adresse IP : C'est un identifiant numrique compos de 4 nombres cods chacun sur un octet (0-255) permettant d'identifier d'une manire unique un ordinateur faisant partie d'un rseau qui utilise le protocole TCP/IP. Exemple : 193.94.15.3 Nom de domaine : Le protocole TCP/IP permet d'associer des noms en langage courant aux adresses IP numriques des ordinateurs. Ces noms sont plus significatifs et permettent de dsigner plus facilement ces ordinateurs. Pour assurer la correspondance entre le nom du domaine et l'adresse IP, le TCP/IP utilise un service appel Domain Name Service. Les machines qui hbergent ce service sont appeles des Domaine Name Server. Port de communication : Plusieurs applications sur une mme machine connecte un rseau peuvent utiliser en mme temps les services du protocole TCP/IP. Pour pouvoir distinguer les donnes changes par les diffrentes applications, ces dernires doivent se voir attribuer une adresse logique unique sur la machine. Cette adresse, code sur 16 bits est appele port de communication. La combinaison adresse IP + Port constitue une adresse unique sur une machine. Dans ce cadre l'adresse IP sert identifier de faon unique un ordinateur sur le rseau tandis que le numro de port indique l'application laquelle les donnes sont destines. De cette manire, lorsque l'ordinateur reoit des informations destines un port, les donnes sont envoyes vers l'application correspondante. URL : Acronyme de Uniform Resource Locator, l'URL est une chane de caractres ayant un format universel normalis permettant de dsigner une ressource sur Internet : UserName + Password (facultatif) User:PassWord@ Port
(facultatif si 80)

Protocole http://

Nom du serveur www.NomSite.net

Chemin /cours/index.htm

80

Serveur Web : Un serveur Web est un logiciel qui joue le rle d'intermdiaire (middleware) entre un client (navigateur) et une page Web demande par ce client et situe sur l'ordinateur serveur. Un serveur Web reoit la requte http (url) mise par le client, l'analyse, trouve la page correspondante sur le serveur et la renvoie toujours l'aide du protocole http au client. Le serveur reoit les requtes des clients sur un port de communication. La valeur par dfaut de ce port est 80. Les principaux serveurs Web sur le march sont entre autres : Apache, Microsoft IIS (Internet Information Server), Microsoft PWS (Personal Web Server), Navigateur : Un navigateur est un logiciel qui permet de : Envoyer des requtes http sous forme d'URL un serveur qui hberge des sites Web. Rcuprer la rponse du serveur Web et l'afficher l'cran.

112

Karim Kalti

Protocole http : HTTP est un protocole qui permet d'assurer le transfert de fichiers (essentiellement au format HTML), localiss grce une chane de caractres appele URL, entre un navigateur (le client) et un serveur Web.

Fonctionnement d'une application Web statique


Les applications Web emploient une architecture client/serveur.

Logiciels ncessaires sur chaque machine Client : Navigateur Web. Serveur : Serveur Web (middleware) + les pages qui composent l'application Web.

Droulement des changes de donnes entre le client et le serveur

On considre ici une application Web simple, c'est--dire une application dont les pages sont codes en HTML seulement sans aucun autre langage de script supplmentaire. 1- Le navigateur (client) demande une page Web en envoyant son URL au serveur l'aide du protocole HTTP. 2- Le serveur Web intercepte la requte du client et recherche la page demande. 3- Le serveur renvoie le code source (HTML) de la page au client l'aide du protocole HTTP. 4- Le navigateur du client reoit la rponse du serveur, interprte le code HTML reu et affiche la page qui rsulte de cette interprtation. Cette description montre le rle important qu'assure le navigateur dans ce processus d'change savoir le rle d'interprteur de code HTML.

113

Karim Kalti

Page Web statique et page Web dynamique


Page Web statique Une page Web statique est une page dont le contenu est fig et est identique pour chaque consultation de la page. Le contenu d'une page Web statique est connu au moment de la cration de la page. Le contenu statique ne peut tre modifi que suite une intervention sur le code source de la page Web par le programmeur (le crateur de la page). Page Web dynamique Une page Web dynamique est une page dont le contenu change d'une consultation une autre. Ce contenu ne peut pas tre explicitement dfini au moment de la cration de la page. Il est plutt gnr au moment de l'excution ( la vole). L'aspect dynamique d'un contenu peut tre d entre autres : o L'volution des donnes afficher dans le temps (Exemple : affichage de la date, affichage en temps rel des donnes de la bourse, ). o Interaction de l'utilisateur (Exemple : affichage des rsultats suivant la requte de l'utilisateur).

Langage pour la gnration du contenu dynamique


Limites du HTML Le HTML est un langage permettant de spcifier la mise en forme (formatage) du contenu d'une page Web. Le HTML ne propose pas de moyens de : o Faire de la programmation structure (pas de structures de contrle pas de fonctions, ). o Interaction avec l'utilisateur (Rcupration et traitement des donnes d'un formulaire, etc.). o De gnration dynamique du contenu. Contenu dynamique ct client et contenu dynamique ct serveur La gnration du contenu dynamique ncessite l'utilisation de langages complmentaires au HTML. Cette gnration peut se faire deux niveaux : au niveau du client (navigateur) et au niveau du serveur (serveur Web). Il existe des langages spcifiques pour chaque niveau de gnration dynamique de contenu.

Contenu dynamique ct client


Motivations La cration dynamique du contenu ct client peut tre motive par plusieurs raisons. Allger la charge de traitement du serveur en dlguant au client certaines oprations qui peuvent s'effectuer sur ce dernier. (Exemple : vrification des donnes saisies par l'utilisateur lors du remplissage d'un formulaire avant leur insertion dans une base de donnes). Certaines donnes dynamiques, de part leur nature, ne peuvent tre gnres que sur le poste client. (Exemple: affichage de l'heure courante sur le poste du client : le serveur peut tre situ dans une rgion qui n'appartient pas au mme faisceau horaire que celui de la rgion du client). Langages de script ct client : Il existe essentiellement deux langages pour la cration du contenu Web dynamique ct client : JavaScript et VBScript. Le script ct client est insr dans le mme fichier source que le HTML. Un fichier qui contient du HTML et du script ct client garde l'extension HTML ou HTM. Le script ct client est excut par le navigateur.

114

Karim Kalti

Echanges entre client et serveur pour une page qui contient un script client

Support des langages de script par les navigateurs JavaScript Toutes les dernires versions des navigateurs (IE, Netscape Navigator, firefox,) VbScript IE seulement : Les scripts VB sont tout simplement ignors par les autres navigateurs (Pas d'erreur signale).

Remarque : Il existe d'autres langages qui permettent d'crire des modules qui sont tlchargs avec les pages Web et excuts par les machines clientes comme par exemple les applettes Java et les contrles ActiveX (C++, VB,).

Gnration ct serveur
Motivations Les scripts ct serveur peuvent tre utiliss pour effectuer tout genre d'oprations d'interaction ou de cration de contenu dynamique mais ct serveur (traitement des formulaires, mise en page dynamique, accs aux donnes, etc.). L'utilisation la plus frquente reste celle de l'accs aux donnes (gnration dynamique du contenu en se basant sur des donnes qui rsultent de l'interrogation d'une base de donnes). Ce genre d'oprations ne peut pas tre effectu ct client (ncessit dans ce cas d'avoir une copie locale de la base sur chaque client). Intgration de script serveur dans une page Web Un script serveur est gnralement insr dans le code HTML avec des balises spciales (balises qui dpendent du langage de script utilis). Une page qui contient du HTML et un script serveur ne peut pas avoir l'extension HTML ou HTM. Son extension dpend du langage du script serveur qu'elle utilise. Une mme page Web ne peut utiliser qu'un seul langage de script serveur (pas de possibilit d'utiliser plusieurs langages de script serveur au sein d'une mme page). Interprtation des scripts ct serveur L'interprtation des scripts ct serveur est effectu par le serveur Web.

115

Karim Kalti

Droulement des changes entre le client et le serveur

1- Le navigateur (client) demande une page Web dynamique en envoyant son URL au serveur l'aide du protocole HTTP. 2- Le serveur recherche la page et reconnat qu'elle contient un script serveur (d'aprs son extension). 3- Le serveur analyse le code de la page : a. Il laisse intacte les parties codes en HTML. b. Il interprte le script serveur et gnre dynamiquement un code HTML quivalent. 4- Le serveur envoie la page (qui contient du HTML seulement) au client via le protocole HTTP. 5- Le navigateur du client reoit la rponse du serveur, interprte le code HTML reu et affiche la page qui rsulte de cette interprtation.

Langages de scripts ct serveur Il existe une panoplie de langages de script ct serveur. Mais actuellement trois sont les plus utiliss : ASP.NET, PHP, JSP. Acronyme de ASP JSP PHP
Active Server Pages Java Server Pages Pre Hypertext Processor

Propritaire
Microsoft Sun Open source

Langage de programmation
C#, VB, C++ , ... Java PHP proche du C

Plateforme
Windows, (Linux projet en cours) Linux, Solaris, Windows, Linux, Solaris, Windows,

Serveur Web
IIS IIS, Apache, Tomcat, IIS, Apache,

116

Karim Kalti

ASP.NET
Introduction
ASP.NET est la nouvelle technologie propose par MS pour le dveloppement d'applications Web dynamiques. ASP.NET est diffrent de ASP (une nouvelle conception Architecture diffrente). ASP.NET fait partie du .NET FrameWork. Les langages de dveloppement : VB, C#, C++,

VB

C++

C#

JScript

Common Language Specification ASP.NET: Web Services and Web Forms Windows Forms

ADO.NET: Data and XML .NET Framework Base Classes Common Language Runtime

Caractristiques de ASP.NET
Permet le dveloppement ct serveur d'applications Web dynamiques. Programmation oriente objet. Accs toute l'API du .NET FrameWork. Introduction des contrles Web ct serveur. (Facilit de programmation et adaptation dynamique aux navigateurs clients). Possibilit de programmer avec diffrents langages. Intgration avec ADO.NET pour l'accs aux donnes. Prise en charge complte de XML. Mcanisme intgr pour mettre en cache les pages Web les plus frquemment rclames au serveur. ASP permet de dvelopper des pages interprtes alors que ASP.NET permet de dvelopper des applications compils ( l'aide de la technique du code behind) donc plus rapides que celles dveloppes avec ASP.

Structure et fichiers d'une application ASP.NET


Une application Web ASP.NET se compose : D'un ensemble de pages Web dynamiques (Fichiers *.aspx) comportant gnralement des formulaires Web. A la manire des formulaires Windows, les formulaires Web constituent la partie visuelle de la page. Elle peut comporter galement : Des pages Web simples (Fichiers *.html). Des contrles Web personnaliss construits partir d'autres contrles serveur (Fichiers *.ascx). Une application Web peut faire appel galement des services Web distants (Fichiers *.asmx).

117

Karim Kalti

ASP.NET a t conu de faon permettre la sparation entre le code de traitement et l'interface. Ce code de traitement peut tre plac dans des fichiers sources C# (*.cs) ou Visual Basic (*.vb) lis aux fichiers des interfaces (*.aspx).

Fichiers HTML

Fichiers ASPX

Fichiers CS

Service Web (asmx)

Contrle Utilisateur

Fichiers d'une application Web ASP.NET

Outils pour dvelopper en ASP.NET


Un diteur de texte pour crire le code (Exemple : Notepad). Un Serveur Web : IIS ou Cassini. La CLR : (elle doit tre installe aprs l'installation du serveur Web). Il existe des environnements de dveloppement intgrs (EDI) plus labors : Visual Studio.NET (payant) WebMatrix (gratuit).

Structure gnrale d'une page ASP.NET


La structure gnrale d'une page ASP.NET (fichier aspx) est de la forme :
<head> <script language= "c#" runat="server"> type fct (type i) { } </script> <script language= "javascript"> function f ; </script> </head> <body> <table> </table> <asp :Label [Proprits]></asp :Label> <% =fct(5) %> </body>

Une page aspx comporte : Des scripts ASP.Net crits en VB ou en C# ou en tout autre langage support par le .NET. Du HTML pour le formatage du contenu statique et ventuellement du javascript pour effectuer des traitements ct client.

118

Karim Kalti

Echanges client serveur lors de la consultation d'une page ASP.NET

Commentaires : Suite sa premire demande une page ASP.NET est compile puis mise en cache. Toute nouvelle demande de cette page va engendrer l'envoi direct du cache sans ncessiter une recompilation sauf si une mise jour de la page est ncessaire. La mise jour dont il est question ici concerne le code de traitement et de gnration associ la page. La saisie des donnes d'un formulaire ne demande pas une recompilation, le code de traitement et de gnration tant en effet toujours le mme (c'est comme la saisie des donnes pour un formulaire Windows, elle ne demande pas la recompilation et la gnration d'un nouvel excutable). Remarque : Si le fichier consult est un fichier aspx alors le client (le navigateur dans ce cas) reoit de la part du serveur une page. Si le fichier consult est un fichier asmx alors le client (une application web dans ce cas) reoit de la part du serveur un objet.

Insertion des scripts ASP.NET dans une page Web dynamique


L'insertion des scripts serveur ASP.NET dans une page Web se fait l'aide de balises spciales. Les balises utilises dans ce cadre diffrent suivant l'endroit d'insertion de ces scripts.

Balise
<% = %> <% # %> <script > </script> <asp:NomControl > </asp:NomControl>

Utilisation
Pour l'affichage de la valeur d'une expression. Cette expression doit renvoyer une chane de caractres. Ces expressions peuvent tre des variables simples ou des appels des fonctions (fonctions de l'API .NET ou personnalises). La valeur de l'expression est concatne avec le contenu statique format en HTML Pour l'affichage du contenu des variables seulement (variables chanes de caractres). Pour l'insertion des scripts. Les scripts doivent figurer dans la partie entte de la page. Pour l'insertion des contrles Web dans un formulaire serveur.

119

Karim Kalti

Affichage de la valeur d'une expression Exemple :


<html> <head> <title>Exemple 1 ASP.NET </title> </head> <body> Il est <% =DateTime.Now.ToString("T") %> </body> </html>

Commentaires : L'expression en question ici est un appel d'une fonction. Ce code montre comment appeler une fonction prdfinie du .NET et comment concatner sa valeur de retour avec un contenu statique. La mthode ToString de cet objet est surcharge. La version utilise permet de spcifier le format d'affichage de la date. Il n'est pas ncessaire de spcifier le langage car le code de l'appel s'crit de la mme manire en VB et en C# (Fonction .NET). Rsultat : (heure sur le serveur)
Il est 23:39:33

Code HTML reu par le navigateur : Suite la rception d'une demande de la page, le serveur Web interprte le script ASP.NET et gnre du HTML qu'il insre avec le flux HTML renvoy au client.
<html> <head> <title>Exemple 1 ASP.NET </title> </head> <body> Il est 23:39:33 </body> </html>

Insertion de modules de scripts Si le contenu dynamique ncessite la dfinition de modules de scripts (fonctions) alors ces modules doivent tre insrs dans la page dans une zone part, dfinie par les balises <script> </script>, et se trouvant dans la partie entte de la page. L'appel de ces fonctions dans le corps de la page peut toujours se faire en utilisant la balise <% = %>. Cette technique permet une meilleure organisation du code source de la page en sparant les scripts de gnration de contenu, du code HTML permettant le formatage de ce contenu. Exemple :
<html> <head> <script language= "c#" runat= "server"> string Demain() { DateTime aujourdhui=DateTime.Now ; DateTime demain=aujourdhui.AddDays(1) ; return demain.ToString() ; } </script> </head> <body> Date du jour : <% =DateTime.Now.ToString() %><br> Date de demain : <% =Demain() %> </body> </html>

120

Karim Kalti

Commentaires : L'attribut language dsigne le langage utilis pour crire les scripts ASP.NET. Les deux langages les plus utiliss sont C# et VB. Il n'est pas possible d'utiliser deux langages diffrents dans la mme page. La valeur server de l'attribut runat indique au serveur Web que le script doit tre excut sur le serveur. Le client recevra seulement du HTML. Rsultat : Date du jour : 24/01/2003 23:51:45 Date de demain : 25/01/2003 23:51:45 Affichage du contenu d'une variable. La valeur d'une variable peut tre insre dans le flux HTML l'aide de la balise <%# La variable doit tre de type chane ou convertie en chane. Il faut faire un Binding lors du chargement de la page. %>.

Exemple :
<html> <script language= "c#" runat= "server"> string s = "bonjour"; void Page_Load(Object sender, EventArgs e) { DataBind();} </script> <body> le contenu de la variable est : <%# s %> </body> </html>

Insertion de contenu dynamique dans la rponse adresse au navigateur


L'ASP.NET dispose d'un objet Response qui reprsente la rponse (code HTML de la page) qui sera envoye par le serveur au navigateur. Cet objet possde une mthode Write qui permet d'insrer un contenu gnr dynamiquement dans le flux de donnes envoy au navigateur. Exemple 1 : Insertion d'une chane de caractres simple :
<html> <script language= "c#" runat= "server"> </script> <body> <% Response.Write("Hello Word"); %> </body> </html>

Exemple 2 : Insertion d'un flux format


<html> <script language= "c#" runat= "server"> </script> <body> <% Response.Write("Bonjour <b>tout <i>le monde</i><b>"); %> </body> </html>

121

Karim Kalti

Rsultat : Bonjour tout le monde

Exemple 3 : Insertion d'un flux format


<html> <script language= "c#" runat= "server"> </script> <body> <% for(int i=6;i>1;i--) { string s= "<h"+i+">" + "Nous sommes le : " + DateTime.Now.ToString() + "</h"+i+">"; Response.Write(s); } %> </body> </html>

Rsultat :
Nous sommes le : 25/01/2003 00:10:41

Nous sommes le : 25/01/2003 00:10:41

Nous sommes le : 25/01/2003 00:10:41

Nous sommes le : 25/01/2003 00:10:41

Nous sommes le : 25/01/2003 00:10:41


L'ajout de commentaires dans un code ASP.NET
Une page ASP.NET peut contenir des balises HTML, des balises ASP et du code C# ou VB. L'insertion des commentaires dpend alors du langage utilis :
Dans du code C# Dans du code HTML Dans une balise ASP.NET // le reste de la ligne est en commentaire. /* */ Commentaire multi lignes. <!-- dbut des commentaires --> Fin des commentaires <%-- dbut des commentaires --%> Fin des commentaires

La technique du code behind


Le code behind est une manire d'organiser le code d'une page web dynamique qui vise sparer la partie interface de la partie traitement (couche prsentation et couche mtier). En ASP.NET, cela consiste sparer dans deux fichiers diffrents le code ncessaire la cration de l'interface (fichier aspx) et le code qui contient la partie traitement (fichier cs). Fichier Page1.cs

using System; public class LaDate : System.Web.UI.Page { protected DateTime aujourdhui; protected DateTime demain;

122

Karim Kalti

protected string Demain() { aujourdhui=DateTime.Now; demain=aujourdhui.AddDays(1); return demain.ToString() ; } }

Fichier Test.aspx
<%@ Page Language="C#" Src="Page1.cs" Inherits="LaDate"%> <html> <body> Date de demain : <% =Demain() %> </body> </html>

Commentaires : Le fichier Page1.cs Ce fichier contient la dfinition d'une classe LaDate qui contient le code permettant de dterminer la date recherche (script de la partie traitement). Ce fichier est entirement crit en C# (aucune rfrence l'interface). La classe Page est la classe de base de toute page Web crite en ASP.NET. La classe LaDate hrite de la classe Page. Le fichier Test.aspx Le fichier Test.aspx contient le code permettant de gnrer le contenu de la page (la partie interface). Ce fichier contient un appel la fonction Demain( ) qui n'est pas dfinie dans ce fichier mais dans le fichier associ nomm Page1.cs. La directive @Page au dbut du fichier Test.aspx indique au serveur que la page Test en tant qu'objet est base sur le modle de page (hritage) dfinie par la classe LaDate. Cette directive spcifie galement le langage de programmation (Language="C#") et le fichier source dans lequel est dfinie la classe LaDate (Src="Page1.cs"). La dfinition de l'objet qui reprsente la page Test est transparente pour le programmeur. Grce au lien d'hritage avec la classe LaDate, cet objet peut utiliser directement les mthodes et proprits de cette classe et des classes sur lesquelles elle se base. Ceci explique la possibilit de l'appel directe de la fonction Demain( ) dans Test.aspx.

123

Karim Kalti

Documents d'une application Web


Une application Web est une application regroupant divers documents : Des fichiers aspx : contenant des scripts serveur. Des fichiers de code .NET (partie mtier). Des fichiers HTML. Des contrles utilisateurs. Des fichiers spciaux (global.asax et web.config). Des ressources (images, sons, vido, ).

Organisation des documents d'une application Web


Organisation physique Une application Web ASP.NET comprend gnralement : Un dossier Racine : Les documents d'une application Web doivent tre sous une mme racine appele la racine de l'application Web. Un dossier [bin] : Ce dossier sert placer les modules pr-compils de l'application. Il doit tre un sousdossier du dossier racine. Un fichier [global.asax] qui permet d'initialiser l'application Web dans son ensemble ainsi que l'environnement d'excution de chacun de ses utilisateurs. Un fichier [web.config] qui permet de paramtrer le fonctionnement de l'application. Un fichier [default.aspx] qui joue le rle de porte d'entre de l'application (page de dmarrage). Dossier virtuel Le dossier racine d'une application Web doit tre associe un chemin virtuel au sein du serveur Web pour que ce dernier puisse reconnatre l'application et servir ses demandeurs.

Cycle de vie d'une application Web


Une application Web dmarre ds q'une page situe dans le dossier virtuel qui lui est associ est demande par un client. Chaque client (navigateur) qui demande une page de l'application engendre la cration d'une nouvelle session. Une application Web dure aussi longtemps qu'elle a des sessions actives. Une application Web est termine par le serveur Web lorsqu'elle reste inactive pendant un dlai donn aprs la fermeture de la dernire session active. Ce dlai d'inactivit est configurable dans le fichier [web.config] associ l'application. Remarque : Le client du serveur Web n'est pas l'utilisateur mais plutt le navigateur. Si un utilisateur ouvre sur sa machine deux instances du navigateur pour consulter une application Web alors chaque instance reprsente un client.

Modle objet d'une application Web


ASP.NET fournit une panoplie d'objets permettant de manipuler par programmation les diffrentes composantes d'une application Web. Les objets les plus importants et qui constituent le cur de toute application Web sont : Application : qui reprsente une application Web et permet de manipuler ses proprits. Session : qui reprsente une session ouverte par un client. Page : qui reprsente une page Web. Les contrles Web : Ces contrles sont similaires aux contrles Windows et permettent de crer des formulaires Web. Request : qui reprsente la requte mise par le client au serveur. Response : qui reprsente la rponse envoye par le serveur Web au client.

124

Karim Kalti

Espaces de noms des objets ASP.NET


ASP.NET n'est pas un langage proprement dit. Il se prsente plutt comme une bibliothque de classes du FrameWork .NET qui offre toutes les fonctionnalits ncessaires pour la cration d'une application Web. Ces classes sont regroupes dans les espaces de noms prsents par le tableau suivant : Espaces de noms
System.Web

System.Web.SessionState System.Web.Services System.Web.UI System.Web.UI.WebControls System.Web.Caching System.Web.mail System.Web.Security

Classes Contient la majorit des objets qui composent une application Web comme les objets : Application, Browser, Cookies, Exception, Request, Response, Server et Trace. Contient les objets permettant de grer l'tat d'une session comme l'objet Session. Contient les objets qui permettent de crer et d'exploiter des services Web. Contient les objets qui permettent de contrler l'interface comme les objets Page et Control. Contient les objets contrles serveur utiliss dans les formulaires Web. Contient essentiellement la classe Cache qui sert mettre en uvre un cache ct serveur afin d'amliorer les performances de l'application. Contient les objets MailMessage, MailAttachement et SmtpMail qui servent envoyer des courriers lectroniques. Contient les objets et les modules d'authentification. Ils servent authentifier les utilisateurs afin de renforcer la scurit des applications.

L'objet Page
Un fichier aspx reprsente une page Web qui comporte gnralement un formulaire Web gnr et trait ct serveur. L'accs par programmation cette page se fait l'aide de l'objet Page de ASP.NET. Chaque demande d'une page aspx par un client engendre la cration sur le serveur d'une instance de l'objet Page base sur la page demande. Cycle de vie d'une page aspx Le cycle de vie d'une page Web est comme suit : Le client demande une page (fichier aspx). Le serveur Web : o localise le fichier aspx sur le serveur. o Cre en mmoire une instance Page partir du fichier aspx. o Gnre la rponse sous forme de code HTML. o Transmet cette rponse au navigateur. o Dtruit l'instance de l'objet Page sur le serveur (pas le fichier aspx). Espace de noms : System.Web.UI Constructeurs :
public Page();

Principales proprits : Proprit Type


Application Cache Controls Request Response Server Session Visible EnableViewState HttpApplicationState Cache ControlCollection HttpRequest HttpResponse HttpServerUtility HttpSessionState bool bool

Signification
Donne accs l'tat de l'application en cours. Donne accs l'objet Cache associ l'application. Contient la collection des contrles Web de la page. Donne accs l'objet Request de la requte en cours. Donne accs l'objet Response de la rponse en cours. Donne accs l'objet Server. Donne accs l'objet Session. Obtient ou dfinit une valeur indiquant si l'objet Page est rendu. Obtient ou dfinit une valeur indiquant si la page conserve son tat d'affichage, ainsi que celui de tous les contrles serveur qu'elle contient, la fin de la demande de la page en cours. Obtient une valeur indiquant si la page est en cours de chargement en rponse une publication du client ou en rponse une premire demande d'accs.

IsPostBack

bool

125

Karim Kalti

Principales mthodes : Mthode


void DataBind() string MapPath(string)

Signification
Lie une source de donnes au contrle serveur appel et tous ses contrles enfants. Retourne le chemin physique d'un chemin virtuel pass comme argument.

Principaux vnements : Les principaux vnements d'un objet Page sont cits dans le tableau suivant :

Evnement

Type de dlgation

Gestionnaire

Signification
Cet vnement se dclenche lorsqu'un contrle est charg en mmoire et initialis partir de ses proprits spcifies au moment de la dfinition de l'objet qui reprsente ce contrle. Il n'est pas possible d'accder aux autres contrles durant cet vnement (ces derniers ne sont pas ncessairement dj crs). Pour cette raison, il n'est pas possible d'agir sur les proprits des contrles pour dfinir la disposition par exemple. Cet vnement se dclenche lorsque le contrle courant et tous ses contrles enfants (La page et tous ses contrles serveur) ont t chargs en mmoire (aprs l'vnement Init). Il est possible dans ce cas d'accder ces contrles et d'agir sur leurs proprits pour faire une initialisation dynamique par exemple. Cet vnement se dclenche lorsque la page se dcharge de la mmoire. Il est exploit pour librer les ressources utilises par le contrle (fermeture des fichiers et des connexions aux bases de donnes, ). L'accs aux contrles enfants est encore possible ce niveau. Cet vnement se dclenche lorsque la page est dtruite (l'accs aux contrles enfants n'est pas sr). C'est le dernier vnement dans le cycle de vie d'une page. Se dclenche lorsqu'une exception non gre se produit dans le code de l'objet qui reprsente la page.

Init

EventHandler

Page_Init

Load

EventHandler

Page_Load

Unload

EventHandler

Page_Unload

Disposed

EventHandler

Page_Disposed

Error

EventHandler

Page_Error

Sur le plan pratique l'vnement Load est l'vnement le plus trait. A part l'vnement Error, l'ordre d'occurrence des autres vnements suit l'ordre de leur apparition dans le tableau ci-dessus.

Les formulaires et les contrles Web ct serveur


ASP.NET apporte travers son modle objet une nouveaut qui consiste en une bibliothque de classes permettant de crer ct serveur des formulaires Web avec des contrles similaires ceux utiliss dans les applications Windows classique (les WinForms). Les formulaires Web sont crs dans les pages aspx. Ils sont insrs dans ces dernires l'aide de la balise
<Form runat="server"> . . . </Form>.

Un contrle Web ct serveur est insr dans un formulaire Web l'aide de la balise : <asp:Nomcontrle> </asp:Nomcontrle>.

126

Karim Kalti

Les contrles Web les plus utiliss fournis par le FrameWork .NET sont rsums dans le tableau suivant : Evnements frquemment utiliss
Les vnements sont rarement utiliss. TextChanged Les vnements sont rarement utiliss. Click, Command (click avec argument). Click

Composant
Label TextBox Image Button ImageButton

Fonctionnalit
Affichage de texte. Le texte peut inclure des balises html. Zone d'dition. Affichage d'une image. Bouton de commande. Bouton de commande avec image. Lien hypertexte pour la navigation Web. Le transfert vers la page de destination est direct partir du client sans passage par le serveur. Panneau permettant de dposer d'autres composants. Case cocher. Case options. Bote de liste. Bote combo (Liste droulante). Bote de liste avec case cocher pour chaque ligne.

Code d'ajout du contrle


<asp:Label id=Label1 runat="server">Label</asp:Label> <asp:TextBox id=TextBox1 runat="server"></asp:TextBox> <asp:Image id=Image1 runat="server"></asp:Image> <asp:Button id=Button1 runat="server" Text="Button"></asp:Button> <asp:ImageButton id=ImageButton1 runat="server"></asp:ImageButton> <asp:HyperLink id=HyperLink1 runat="server">HyperLink </asp:HyperLink> <asp:Panel id=Panel1 runat="server">Panel</asp:Panel> <asp:CheckBox id=CheckBox1 runat="server"></asp:CheckBox> <asp:RadioButton id=RadioButton1 runat="server"></asp:RadioButton> <asp:ListBox id=ListBox1 runat="server"></asp:ListBox> <asp:DropDownList id=DropDownList1 runat="server"></asp:DropDownList> <asp:CheckBox id=CheckBox1 runat="server"></asp:CheckBox>

HyperLink

Les vnements sont rarement utiliss. Les vnements sont rarement utiliss. CheckChanged CheckChanged SelectedIndexChanged SelectedIndexChanged CheckChanged CancelCommand, EditCommand, DeleteCommand, ItemCommand, SelectedIndexChanged, PageIndexChanged, SortCommand, UpdateCommand, ItemCreated, ItemDataBound

Panel CheckBox RadioButton ListBox DropDownList CheckBoxList

DataGrid

Grille de donnes.

<asp:DataGrid id=DataGrid1 runat="server"></asp:DataGrid>

Premier formulaire Web


<%@ Page Language="C#" %> <script runat="server"> void BtnSomme_Click(object sender, EventArgs e) { int Somme; if(TxtBE1.Text!="" && TxtBE2.Text!="") { try { Somme = Int32.Parse(TxtBE1.Text)+Int32.Parse(TxtBE2.Text); LbResultat.Text = "La somme est :" + Somme.ToString(); } catch(Exception) { LbResultat.Text = "Prire de vrifier les valeurs saisies";} } } </script>

127

Karim Kalti

<html> <head> </head> <body> <form runat="server"> <p> <asp:Label id="LbE1" runat="server">Entier 1 : </asp:Label> <asp:TextBox id="TxtBE1" runat="server"></asp:TextBox> <br/> <asp:Label id="LbE2" runat="server">Entier 2 : </asp:Label> <asp:TextBox id="TxtBE2" runat="server"></asp:TextBox> <br /> <asp:Button id="BtnSomme" onclick="BtnSomme_Click" runat="server" Text="Somme"></asp:Button> <br /> <asp:Label id="LbResultat" runat="server">La somme est : </asp:Label> </p> </form> </body> </html>

Rsultat de l'excution

Organisation gnrale du code La premire ligne de code du fichier <%@ Page Language="C#" %> est une directive qui indique qu'il s'agit d'une page aspx et que le langage utilis par cette page est le C#. Le reste du code source du fichier est divis en deux parties : o La premire partie, dfinie dans l'entte de la page et dlimite par les balises <script runat="server"> </script>, reprsente un script C# qui dfinit les traitements effectus par le formulaire. o La deuxime partie dfinie dans le corps de la page, reprsente le code ncessaire la cration de la prsentation de la page (Interface). Cette partie comporte essentiellement un formulaire Web.

Ajout du formulaire la page Le formulaire Web est ajout la page l'aide de la paire de balises <form runat="server"> </form>. L'attribut runat="server" indique que le formulaire Web est un formulaire qui doit tre trait sur le serveur.

128

Karim Kalti

Ajout d'un contrle au formulaire L'ajout des contrles Web au formulaire se fait l'aide de la balise : <asp:Nomcontrle . . .> </asp:Nomcontrle.>. Exemple : Cet exemple montre l'ajout d'un bouton au formulaire :
<asp:Button id="BtnSomme" onclick="BtnSomme_Click" runat="server" Text="Somme"></asp:Button>

asp:Button : indique que le contrle est un bouton. L'attribut Id permet de spcifier l'identifiant du bouton. L'attribut onclick permet de spcifier le gestionnaire de l'vnement clic sur le bouton. Dans l'exemple courant ce gestionnaire est BtnSomme_Click. L'attribut Runat="Server" : indique que le bouton est gr ct serveur. L'attribut Text permet de spcifier le texte qui sera affich sur le bouton. Modle de l'objet instanci en mmoire lors de la demande de la page La demande d'une page aspx comportant un formulaire Web par un client va engendrer la cration ct serveur d'une instance d'un objet bas sur cette page et d'un ensemble d'instances des objets reprsentant les contrles serveur composant le formulaire. L'objet qui reprsente la page hrite de l'objet Page de ASP.NET. Les instances des contrles Web sont associes cet objet sous forme d'attributs. Les identifiants des contrles spcifis par l'attribut Id permettent de rfrencer les instances de ces contrles. Pour l'exemple courant la structure de l'objet instanci en mmoire suite la demande de la page Test.aspx ressemble ceci : Page

Test
Button BtnSomme; Label LbResultat; Label LbE1; Label LbE2; TextBox TxtBE1; TextBox TxtBE2;

Cycle de vie d'une page ASP.NET contenant un formulaire Web


Le client demande la page pour la premire fois. Le serveur : o Localise la page. o Cre en mmoire une instance de l'objet reprsentant cette page (objet semblable celui dcrit cidessus). o Traite l'objet (excution des gestionnaires d'vnements, Page_Init puis Page_Load) et gnre la rponse HTML. o Renvoie la rponse au client. o Dtruit l'instance de la page ct serveur. Le client : o Reoit la page contenant le formulaire vide. o Remplit les champs du formulaire et renvoie les valeurs saisies au serveur suite au clic sur un bouton de soumission. Cette opration s'appelle un Postback ou galement "server round-trip". Le serveur : o cre en mmoire une nouvelle instance de l'objet reprsentant cette page. o Traite l'objet (excution des gestionnaires d'vnements, Page_Init puis Page_Load et enfin ButtonClic).

129

Karim Kalti

La proprit IsPostBack d'une page


L'objet Page sur lequel sont bass les pages ASP.NET possde une proprit intressante appele IsPostBack qui permet de vrifier si la page en cours de chargement est envoye pour la premire fois au client ou s'il s'agit d'un renvoi de la page suite un server round-trip. Cette proprit est surtout utilise dans le gestionnaire Page_Load pour dcider de la manire avec laquelle il faut initialiser la page. Exemple : Supposons que l'on souhaite que lors de l'affichage de la page Test pour la premire fois pour un client, les zones de texte contiennent par dfaut la valeur 0. Pour cela il suffit d'affecter la valeur 0 aux deux contrles TextBox lors du chargement de la page (dans le gestionnaire Page_Load). Toutefois avec cette approche, chaque fois qu'une instance de la page est cre en mmoire les deux entiers saisis par l'utilisateur seront crass et remplacs par 0 et la somme vaudra toujours 0 (car sur le serveur l'vnement Load se dclenche avant l'vnement Click associ au bouton). Pour remdier cela il suffit de faire cette initialisation seulement lors du premier chargement de la page.

Code permettant de grer l'initialisation


<%@ Page Language="C#" %> <script runat="server"> void Page_Load(object sender, EventArgs e) { if( IsPostBack == false) { TxtBE1.Text="0"; TxtBE2.Text="0"; } } void BtnSomme_Click(object sender, EventArgs e) { int Somme; if(TxtBE1.Text!="" && TxtBE2.Text!="") { try { Somme = Int32.Parse(TxtBE1.Text)+Int32.Parse(TxtBE2.Text); LbResultat.Text = "La somme est :" + Somme.ToString(); } catch(Exception) { LbResultat.Text = "Prire de vrifier les valeurs saisies";} } }

130

Karim Kalti

</script> <html> <head> </head> <body> <form runat="server"> <p> <asp:Label id="LbE1" runat="server">Entier 1 : </asp:Label> <asp:TextBox id="TxtBE1" runat="server"></asp:TextBox> <br /> <asp:Label id="LbE2" runat="server">Entier 2 : </asp:Label> <asp:TextBox id="TxtBE2" runat="server"></asp:TextBox> <br /> <asp:Button id="BtnSomme" onclick="BtnSomme_Click" runat="server" Text="Somme"> </asp:Button> <br/> <asp:Label id="LbResultat" runat="server">La somme est : </asp:Label> </p> </form> </body> </html>

Remarque : Un fichier aspx inclut par dfaut les espaces de noms les plus frquemment utiliss lors de la cration d'une page Web. Ces espaces de noms sont : System, System.Web, System.Web.UI, System.Web.UI.WebControls. Ceci explique d'ailleurs la possibilit d'utilisation directe des objets "Contrles Web", des exceptions, etc. Version "code behind" du code prcdent Fichier Test.aspx
<%@ Page Language="C#" Src="Page1.cs" Inherits="Test.Page1" %> <html> <head> </head> <body> <form runat="server"> <p> <asp:Label id="LbE1" runat="server">Entier 1 : </asp:Label> <asp:TextBox id="TxtBE1" runat="server"></asp:TextBox> <br /> <asp:Label id="LbE2" runat="server">Entier 2 : </asp:Label> <asp:TextBox id="TxtBE2" runat="server"></asp:TextBox> <br /> <asp:Button id="BtnSomme" onclick="BtnSomme_Click" runat="server" Text="Somme"></asp:Button> <br /> <asp:Label id="LbResultat" runat="server">La somme est : </asp:Label> </p> </form> </body> </html>

Fichier Page1.cs
namespace { using using using using Test System; System.Web; System.Web.UI; System.Web.UI.WebControls;

public class Page1 : Page { // Rfrences aux contrles dfinis dans le fichier aspx public Label LbE1; public Label LbE2; public Label LbResultat; public TextBox TxtBE1; public TextBox TxtBE2;

131

Karim Kalti

public Button BtnSomme; protected void Page_Load(object sender, EventArgs e) { if( IsPostBack == false) { TxtBE1.Text="0"; TxtBE2.Text="0"; } } public void BtnSomme_Click(object sender, EventArgs e) { int Somme; if(TxtBE1.Text!="" && TxtBE2.Text!="") { try { Somme = Int32.Parse(TxtBE1.Text)+Int32.Parse(TxtBE2.Text); LbResultat.Text = "La somme est :" + Somme.ToString(); } catch(Exception) { LbResultat.Text = "Prire de vrifier les valeurs saisies";} } } } }

Remarque : Aucun espace de noms n'est inclut par dfaut dans un fichier .cs. C'est pourquoi, il est ncessaire de mentionner explicitement les espaces de noms utiliss dans ce type de fichier.

La classe Control
Cette classe est la classe de base de tous les contrles. (Web Controls et HTML Controls). Principales proprits : Proprit Type
ID Page Parent Controls string Page Control ControlCollection

Signification
Tout composant peut porter un nom, ce nom est lId. Cest partir de ce nom qu'il est possible de modifier les attributs du contrle dans du code c# . Il est interdit d'avoir deux fois le mme Id dans une mme page asp.NET. Obtient une rfrence l'instance de Page qui contient le contrle serveur. Obtient une rfrence au contrle parent du contrle serveur dans la hirarchie des contrles de la page. Obtient un objet ControlCollection qui reprsente les contrles enfants d'un contrle serveur spcifi dans la hirarchie de l'interface utilisateur. Obtient ou dfinit une valeur indiquant si le contrle serveur rend persistant son tat d'affichage, ainsi que celui de tous les contrles enfants qu'il contient, sur le client l'origine de la demande. Obtient ou dfinit une valeur qui indique si un contrle serveur est rendu sous la forme d'une interface utilisateur sur la page.

EnableViewState

Bool

Visible

bool

Principales mthodes : Mthode


void DataBind() void Dispose() bool HasControls()

Signification
Lie une source de donnes au contrle serveur appel et tous ses contrles enfants. Permet un contrle serveur d'effectuer le nettoyage final avant qu'il soit libr de la mmoire. Dtermine si le contrle serveur contient des contrles enfants.

Principaux vnements : Evnement


Init

Type de dlgation
EventHandler

Signification
Cet vnement se dclenche lorsqu'un contrle est charg en mmoire et initialis partir de ses proprits spcifies au moment de la dfinition de l'objet qui reprsente ce contrle. Il n'est pas possible d'accder aux autres contrles durant cet vnement

132

Karim Kalti

Load

EventHandler

Unload Disposed

EventHandler EventHandler

(ces derniers ne sont pas ncessairement dj crs). Pour cette raison, il n'est pas possible d'agir sur les proprits des contrles pour dfinir la disposition par exemple. Cet vnement se dclenche lorsque le contrle courant et tous ses contrles enfants ont t chargs en mmoire (aprs l'vnement Init). Il est possible dans ce cas d'accder ces contrles et d'agir sur leurs proprits pour faire une initialisation dynamique par exemple. Cet vnement se dclenche lorsque le contrle se dcharge de la mmoire. Il est exploit pour librer les ressources utilises par le contrle. Cet vnement se dclenche lorsque le contrle est dtruit.

La classe WebControl
Cette classe est la classe de base de tous les contrles Web ct serveur. Elle dfinit les mthodes, proprits et vnements communs tous ces contrles. Espace de noms : System.Web.UI.WebControls Classes drives
System.Object System.Web.UI.Control System.Web.UI.WebControls.WebControl System.Web.UI.WebControls.AdRotator System.Web.UI.WebControls.BaseDataList System.Web.UI.WebControls.Button System.Web.UI.WebControls.Calendar System.Web.UI.WebControls.CheckBox System.Web.UI.WebControls.DataListItem System.Web.UI.WebControls.HyperLink System.Web.UI.WebControls.Image System.Web.UI.WebControls.Label System.Web.UI.WebControls.LinkButton System.Web.UI.WebControls.ListControl System.Web.UI.WebControls.Panel System.Web.UI.WebControls.Table System.Web.UI.WebControls.TableCell System.Web.UI.WebControls.TableRow System.Web.UI.WebControls.TextBox System.Web.UI.WebControls.ValidationSummary

Principales proprits communes aux Web contrles : Proprit


AccessKey Backcolor BorderWidth BorderStyle Enabled ForeColor Height TabIndex Width

Type
string enum Color Uint enum BorderStyle bool enum Color Uint short Uint

Signification
C'est la touche servant d'acclrateur (en combinaison avec ALT) pour excuter l'vnement click sur le contrle. (Exemple AccessKey='A', ALT+A). Couleur d'arrire plan du contrle. Epaisseur de la bordure. Type de contour. Les valeurs possibles sont celles de l'numration BorderStyle. Indique si le contrle est activ ou non. Couleur d'avant plan du texte. Hauteur du contrle en pixels. Ordre du passage du focus d'entre par les touches de tabulation. Largeur du contrle en pixels.

Spcification des diffrents contrles Web ct serveur


La spcification complte des contrles Web ct serveur est donne dans la documentation du FrameWork .NET (Consulter MSDN).

133

Karim Kalti

L'objet HttpApplication
L'objet HttpApplication se situe au sommet de la hirarchie des objets d'une application Web ASP.NET. Il permet la configuration et la sauvegarde des informations d'tat au niveau de l'application et au niveau des sessions. L'objet HttpApplication permet travers ses proprits d'accder aux diffrents autres objets composant une application Web. Le tableau suivant prsente quelques exemples de ces objets : Proprit
Application Session Request Response

Type
HttpApplicationState HttpSessionState HttpRequest HttpResponse

Signification
Permet de sauvegarder des donnes ayant une porte au niveau "Application". Permet de sauvegarder des donnes ayant une porte au niveau "Session". Donne accs l'objet Request qui reprsente la requte courante de l'utilisateur. Donne accs l'objet Response qui reprsente la rponse courante envoye par le serveur au client. Cette proprit donne accs l'objet Server qui fournit des mthodes trs pratiques pour l'encodage et le dcodage des URL et pour la rcupration d'informations sur le serveur.

Server

HttpServerUtility

Chaque application Web est reprsente par un objet qui drive de la classe HttpApplication. Cet objet appel gnralement Global est automatiquement instanci au moment du dmarrage de l'application Web et est libr lorsque cette dernire se termine. L'objet Global est dfini dans un fichier particulier appel Global.asax de la manire suivante :
public class Global : System.Web.HttpApplication { . . .}

L'objet HttpRequest
L'objet HttpRequest contient les informations renvoyes par le client (navigateur) lorsque ce dernier demande une page de l'application. L'objet HttpRequest possde des proprits qui permettent d'accder d'autres objets et informations susceptibles d'accompagner la requte du client. Le tableau suivant prsente quelques exemples de ces proprits : Proprit
Browser Cookies Files InputStream ApplicationPath URL UserHostAdress

Type
HttpBrowserCapabilities HttpCookieCollection HttpFileCollection Stream String classe Uri string

Signification
Permet de rcuprer des informations sur le browser du client ayant mis la requte. Permet de rcuprer une collection de cookies partir du client. Reoit les fichiers tlchargs du client vers le serveur. Permet d'avoir accs au contenu du corps de la requte http adresse au serveur. Retourne le chemin virtuel de l'application sur le serveur Retourne l'url de la requte courante. La classe Uri permet d'avoir une reprsentation objet de l'url. Retourne l'adresse IP d'un client distant. Contient la collection de paramtres qui accompagne la requte. L'accs un paramtre donn se fait l'aide d'un indexeur de la collection qui prend comme argument le nom du paramtre et qui retourne sa valeur.

Params

NameValueCollection

L'accs par programmation l'instance de la classe HttpRequest qui reprsente la requte courante adresse au serveur se fait travers la proprit Request de l'objet Global automatiquement instanci par drivation de la classe HttpApplication lors du dmarrage de l'application. Le fait que l'objet Global soit global, rend galement l'objet Request global et directement accessible partir de n'importe quelle page de l'application Web.

134

Karim Kalti

Exemple 1 : Lecture de la valeur d'un cookie


protected void Page_Load(object sender, EventArgs e) { // ce code s'excute lorsque la page est affiche pour la premire fois if( IsPostBack == false) { // Vrification si le navigateur accepte les cookies if(Request.Browser.Cookies) { // Vrification de l'existance d'un cookie appel UName if(Request.Cookies["UName"]!=null) // Lecture de la valeur du cookie Session["UName"] = Request.Cookies["UName"].Value; } } }

Exemple 2 : Rcuprer les donnes d'un GET Pour rappel, Il existe deux mthodes permettant d'envoyer les donnes d'un formulaire d'une page Web vers le serveur. La mthode GET : qui engendre un envoi des donnes avec l'url. L'url ressemble alors ceci :
http://NomDomaine/PageScript?champ1=valeur1&champ2=valeur2&champ3=valeur3

La mthode POST : qui engendre un envoi des donnes dans le corps de la requte. Le choix de la mthode d'envoi est spcifi dans la balise d'ajout du formulaire comme suit :
<form id="Form1" method="GET" runat="server">

On considre l'url : http://NomDomaine/PageScript?champ1=valeur1&champ2=valeur2&champ3=valeur3 La rcupration de la valeur du champ1 du formulaire se fait comme suit :
Request.Params["champ1"]

L'objet HttpResponse
L'objet HttpResponse sert constituer le flux HTML envoy par le serveur au client (navigateur) en rponse une requte de ce dernier. L'objet HttpResponse possde des proprits permettant d'accder d'autres objets qui peuvent accompagns ou tre utiliss par la rponse. Le tableau suivant prsente quelques exemples de ces proprits : Proprit
Cache Cookies OutputStream

Type
HttpCachePolicy HttpCookieCollection Stream

Signification
Dtermine la manire avec laquelle le serveur met en cache la rponse (la page) avant de l'envoyer au client. Dfinit le contenu du cookie qui est envoy au client. Permet d'avoir accs au flux qui contient les donnes brutes qui composent la rponse envoye au client.

La classe HttpResponse possde quelques mthodes intressantes qui sont prsentes dans le tableau suivant : Mthode
void Clear() void Redirect(string) void Write(string s)

Signification
Efface le contenu de la rponse (le flux OutputStream). Redirige le client vers l'url spcifie comme argument. Ecrit la chane s dans le flux constituant la rponse.

L'accs par programmation l'instance de la classe HttpResponse qui reprsente la rponse courante du serveur se fait travers la proprit Response de l'objet Global automatiquement instanci par drivation de la classe HttpApplication lors du dmarrage de l'application. Le fait que l'objet Global soit global, rend galement l'objet Response global et directement accessible partir de n'importe quelle page de l'application Web.

135

Karim Kalti

Exemple 1 : Ecriture d'un texte dans une page Web. ASP.NET fournit un moyen d'insrer directement du texte dans la rponse renvoye au client et ce l'aide de la mthode Write de la classe HttpResponse. Cette mthode est similaire la fonction echo de PHP ou la mthode Response.Write de l'ASP (la version avant .NET). La mthode Write est utilise comme suit :
Resposne.Write ("Ceci est un programme ASP.NET");

La chane passe comme argument peut tre formate avec du HTML.


Resposne.Write ("Ceci est un programme <b>ASP.NET</b>");

Toutefois ASP.NET fournit une autre alternative pour afficher le texte dans une page web et qui consiste dans l'utilisation des contrles Web ct serveur et notamment le contrle Label. Exemple 2 : Redirection L'objet Response fournit le moyen d'effectuer une redirection par programmation et ce l'aide de la mthode Redirect.
Response.Redirect("NouvellePage.aspx");

Exemple 3 : Cration d'un cookie


protected void Page_Load(object sender, EventArgs e) { if( IsPostBack == false) { // Vrification si le navigateur accepte les cookies if(Request.Browser.Cookies) { // Cration d'un cookie HttpCookie MyCookie = new HttpCookie("LastVisit"); MyCookie.Value= DateTime.Now.ToString(); // cookie valuable 30 jours DateTime dt=DateTime.Now; TimeSpan ts = new TimeSpan(30,0,0); MyCookie.Expires = dt.Add(ts); // Ajout du cookie la rponse Response.Cookies.Add(MyCookie); } } }

Exemple d'application : contrle d'accs (passage d'arguments travers l'url) Fichier LogPw.aspx
<html> <head> <%@ Page Language="C#" %> <script runat="server"> public void Check(object sender, EventArgs e) { string[,] tab={{"ali","a1"},{"salah","s1"}}; int i=0; while (i<2) { if (TbLogin.Text == tab[i,0] && TbPasswd.Text == tab[i,1]) Response.Redirect("MesInfos.aspx?Lg=" + TbLogin.Text +"&Pw=" + TbPasswd.Text); i++; } Response.Write("Veuillez saisir une autre fois le login et le password!!"); } </script> </head> <body> <form runat="server"> Login: &nbsp&nbsp&nbsp<asp:TextBox id="TbLogin" Runat="server"></asp:TextBox><br/> Passwd: <asp:TextBox id="TbPasswd" Runat="server"></asp:TextBox><br/><br/> <asp:Button id="BuLogin" onclick="Check" Runat="server" Text="Login"></asp:Button> </form> </body> </html>

136

Karim Kalti

Fichier MesInfos.aspx
<html> <head> <%@ Page Language="C#" %> <script runat="server"> void Page_Load(object sender, EventArgs e) { if (Request.Params["Lg"]!=null) La.Text = "<br><b>Login :</b> " + Request.Params["Lg"].ToString(); if (Request.Params["Pw"]!=null) La.Text += "<br><b>Password :</b> " + Request.Params["Pw"].ToString(); } </script> </head> <body> <form runat="server"> Page MesInfos<br> <asp:Label Runat=server ID=La></asp:Label> </form> </body> </html>

LogPw.aspx

MesInfos.aspx

L'objet HttpApplicationState
Rappel : Une application Web dmarre lors de l'ouverture d'une premire session par un client. Une application Web peut avoir plusieurs sessions ouvertes en mme temps. Une session se termine aprs l'coulement d'une priode d'attente paramtrable (Timeout) aprs la fermeture du navigateur ou l'annulation de la session par programmation. Une application Web se termine suite l'coulement d'une priode d'attente paramtrable (Timeout) aprs la terminaison de la dernire session ouverte de l'application. Les variables d'application Lors du dveloppement d'une application Web, il est souvent utile de dclarer des variables ou des objets qui ont une porte globale (visibles dans toute l'application Web). Ces objets sont partags par toutes les pages de toutes les sessions d'une application. Ils sont appels des variables d'application. La classe HttpApplicationState permet de grer les variables d'application. Proprit
Count

Type
Int

Signification
Donne le nombre d'objets stocks dans l'tat Application (le nombre de variables d'application). Indexeur permettant d'accder aux diffrents objets stocks dans l'tat Application. L'index peut tre numrique ou une chane qui reprsente le nom de l'objet auquel on veut accder.

Item

Indexeur []

137

Karim Kalti

Mthode
void Add(string name, object value); void Clear() void Remove(string name) void RemoveAt(int index) void Lock() void Unlock()

Signification
Ajoute l'objet dont le nom est "name" et la valeur est "value" la collection des variables d'application. Supprime tous les objets de la collection de variables d'application. Supprime l'objet dont le nom est pass comme argument de la collection de variables d'application. Supprime l'objet dont l'index numrique est pass comme argument de la collection de variables d'application. Effectue un verrouillage de l'tat d'application afin de faciliter la synchronisation des accs aux variables d'application. Effectue un dverrouillage de l'tat d'application afin de faciliter la synchronisation des accs aux variables d'application.

L'accs par programmation l'instance de la classe HttpApplicationState qui reprsente l'tat de l'application courante se fait travers la proprit Application de l'objet Global automatiquement instanci par drivation de la classe HttpApplication lors du dmarrage de l'application. Le fait que l'objet Global soit global, rend galement l'objet Application global et directement accessible partir de n'importe quelle page de l'application Web. Utilisation des variables d'application La classe HttpApplicationState offre la possibilit de dclarer des variables qui sont accessibles partir de n'importe quel endroit d'une application Web par toutes les sessions ouvertes. Ces variables sont dites des variables d'application. La cration d'une variable d'application se fait au vol sans dclaration explicite, ni spcification de type. La syntaxe utilise pour faire cette cration est : Application["NomVariable"] = Valeur; La cration d'une variable d'application peut se faire n'importe o dans une application Web. Toutefois l'endroit qui est gnralement utilis pour faire cette cration est le gestionnaire Application_Start dans le fichier Global.asax. Exemple :
<%@ Page Language="C#" %> <script runat="server"> void Page_Load(object sender, EventArgs e) { if(Application["DerniereOffre"]!=null) LbDerniereOffre.Text ="La dernire offre est :"+Application["DerniereOffre"]; } void BtnRafraichir_Click(object sender, EventArgs e) { Response.Redirect("Offre.aspx"); } void BtnEnvoyer_Click(object sender, EventArgs e) { if(TxtBProposer.Text!="") { Application["DerniereOffre"]=TxtBProposer.Text; LbDerniereOffre.Text ="La dernire offre est :"+Application["DerniereOffre"]; } } </script> <html> <head> </head> <body> <form runat="server"> <p> <asp:Label id="LbDerniereOffre" runat="server" width="265px">dernire offre: </asp:Label> <br /> <asp:Button id="BtnRafraichir" onclick="BtnRafraichir_Click" runat="server" Width="100px" Text="Rafrachir" Height="25px"></asp:Button> </p> <p>

138

Karim Kalti

<asp:Label id="LbProposer" runat="server">Proposer une offre :</asp:Label> <asp:TextBox id="TxtBProposer" runat="server"></asp:TextBox><br /> <asp:Button id="BtnEnvoyer" onclick="BtnEnvoyer_Click" runat="server" Width="100px" Text="Envoyer" Height="25px"></asp:Button> </p> </form> </body> </html>

Commentaire : Ce code cre une interface qui permet diffrents utilisateurs de proposer des offres (des entiers numriques) et de voir chaque fois la dernire offre propose (bouton Rafrachir).

Synchronisation des accs une variable d'application : Le fait que les variables d'application soient partages par toutes les sessions peut engendrer des problmes lors des tentatives d'accs simultans ces variables par plusieurs utilisateurs. Par exemple un utilisateur accde une variable d'application et commence faire des traitements avec et entre temps un autre utilisateur accde cette variable et modifie son contenu. Pour viter ce genre de problme, il faut synchroniser les oprations d'accs l'aide des mthodes Lock et Unlock. Exemple :
. . . Application.Lock(); Application["DerniereOffre"]=TxtBProposer.Text; LbDerniereOffre.Text ="La Dernire offre est :"+Application["DerniereOffre"]; Application.UnLock(); . . .

L'objet HttpSessionState
Les variables de session Outre les variables d'application, il existe une autre catgorie de variables globales qui peut tre trs utile lors du dveloppement d'une application Web. Il s'agit des variables qui ont pour porte une session et qui sont appeles de ce fait les variables de session. Une variable de session est partage par toutes les pages d'une application Web mais pour une session donne. La classe HttpSessionState permet de grer les variables et les paramtres relatifs une session donne. Proprit
Count Item SessionID TimeOut

Type
Int Indexeur [] String Int

Signification
Donne le nombre d'lments stocks dans l'tat d'une session. Indexeur permettant d'accder aux diffrents lments stocks dans l'tat d'une session. L'index peut tre numrique ou une chane qui reprsente le nom de l'lment auquel on veut accder. Rcupre un ID permettant d'identifier d'une manire unique une session. Dtermine le temps d'attente (en minutes) qu'il ne faut pas dpasser entre deux requtes avant qu'une session ne soit termine.

Mthode
void Add(string name, object value);

Signification
Ajoute l'objet dont le nom est "name" et la valeur est "value" la

139

Karim Kalti

void Abandon() void Clear() void Remove(string name) void RemoveAt(int index)

collection des variables de session. Annule la session en cours. Supprime tous les objets de la collection de variables de session. Supprime l'objet dont le nom est pass comme argument de la collection de variables de session. Supprime l'objet dont l'index numrique est pass comme argument de la collection de variables de session.

L'accs par programmation l'instance de la classe HttpSessionState qui reprsente l'tat de la session courante se fait travers la proprit Session de l'objet Global. Le fait que l'objet Global soit global, rend galement l'objet Session global et directement accessible partir de n'importe quelle page de l'application Web. Utilisation des variables de session : La cration d'une variable de session se fait au vol sans dclaration explicite, ni spcification de type. La syntaxe utilise pour faire cette cration est : Session["NomVariable"] = Valeur; La cration d'une variable de session peut se faire n'importe o dans une application Web. Cette variable est alors accessible partir de n'importe quelle page mais pour une session donne. L'endroit qui est gnralement utilis pour crer les variables de session est le gestionnaire Session_Start dfini dans le fichier Global.asax. Exemple : Programme "contrle d'accs" utilisant les variables de session Il s'agit du mme programme de contrle d'accs prsent prcdemment. Cette fois ce programme utilise les variables de session au lieu du passage d'arguments travers l'url. Fichier LogPw.aspx
<html> <head> <%@ Page Language="C#" %> <script runat="server"> public void Check(object sender, EventArgs e) { string[,] tab={{"ali","a1"},{"salah","s1"}}; int i=0; while (i<2) { if (TbLogin.Text == tab[i,0] && TbPasswd.Text == tab[i,1]) { Session["Lg"]=TbLogin.Text; Session["Pw"]=TbPasswd.Text; Response.Redirect("MesInfos.aspx"); } i++; } Response.Write("Veuillez saisir une autre fois le login et le password!!"); } </script> </head> <body> <form runat="server"> Login: &nbsp&nbsp&nbsp<asp:TextBox id="TbLogin" Runat="server"></asp:TextBox><br/> Passwd: <asp:TextBox id="TbPasswd" Runat="server"></asp:TextBox><br/><br/> <asp:Button id="BuLogin" onclick="Check" Runat="server" Text="Login"></asp:Button> </form> </body> </html>

Fichier MesInfos.aspx

140

Karim Kalti

<html> <head> <%@ Page Language="C#" %> <script runat="server"> void Page_Load(object sender, EventArgs e) { if (Session["Lg"]!=null) La.Text = "<br><b>Login :</b> " + Session["Lg"]; if (Session["Pw"]!=null) La.Text += "<br><b>Password :</b> " + Session["Pw"]; } </script> </head> <body> <form runat="server"> Page MesInfos<br><br> <asp:Label Runat=server ID=La></asp:Label> </form> </body> </html>

Remarque: Les variables de session et d'application sont stockes en mmoire sur le serveur. Il peut y avoir autant de variables que lon le dsire, cependant il ne faut pas perdre de vue quavec laccroissement du nombre de variables utilises, ce sont souvent les performances qui sont en chute libre. Il faut donc trouver le juste milieu entre performances et facilit. Les informations utilises de manire rpte, si elles nont pas un trop haut cot en mmoire, peuvent donc tre stocke dans ce type de variables (par exemple : le UserName de lutilisateur pour les variables de session, les chanes et les objets de connexion la base de donnes pour les variables d'application).

Le fichier Global.asax
Le fichier Global.asax, connu galement comme le fichier d'application, est un fichier optionnel qui contient le code permettant de grer les vnements dclenchs par une application Web ainsi que par ses sessions et ses modules. Le fichier Global.asax doit rsider toujours dans le rpertoire racine de l'application Web. Le fichier Global.asax est configur de faon ce que toute requte qui lui est adresse (url) soit rejete. Ce fichier ne peut ni tre tlcharg ni dit par un utilisateur externe. Lors du lancement d'une application Web, le fichier Global.asax est compil et ses donnes sont utilises pour gnrer dynamiquement une classe drive de la classe HttpApplication appele Global. Remarque : Le fichier Global.asax est optionnel. S'il n'est pas prsent pour une application Web alors cela suppose que cette dernire ne gre pas les vnements au niveau Application et au niveau Session. La classe Global est dans ce cas implicitement dfinie et instancie. Evnements grs dans le Global.asax Le fichier Global.asax permet d'crire le code de gestion des vnements dclenchs par une application ASP.NET et par ses modules (ventuellement des modules personnaliss). Toutefois les vnements les plus traits dans ce fichier restent ceux lis au niveau Application et au niveau Session. Les noms des gestionnaires d'vnements pour ces deux objets sont prdfinis et automatiquement reconnus par Global.asax. (Si l'attribut AutoEventWireup de l'objet Page vaut "true", true est la valeur par dfaut pour cet attribut). Le tableau suivant donne quelques exemples de gestionnaires les plus utiliss dans ce cadre ainsi qu'une description des vnements qu'ils traitent. Gestionnaire d'vnement
Application_Start ou galement Application_OnStart

Type de dlgation

Description de l'vnement trait


Ce gestionnaire s'excute lors du lancement de l'application (quant un premier client effectue une premire requte une ressource situe dans le rpertoire virtuel de l'application). Ce gestionnaire est exploit pour faire les initialisations ncessaires au fonctionnement de l'application comme par exemple la cration des variables d'application.

EventHandler

141

Karim Kalti

Application_End ou galement Application_OnEnd

EventHandler

Application_BeginRequest

EventHandler

Application_EndRequest

EventHandler

Application_Error

EventHandler

Ce gestionnaire s'excute lorsque l'application est termine. . A toute application est associ un dlai d'inactivit, configurable dans [web.config], au bout duquel l'application est considre comme termine. C'est donc le serveur web qui prend cette dcision en fonction du paramtrage de l'application. Le dlai d'inactivit d'une application est dfini comme le temps pendant lequel aucun client n'a fait une demande pour une ressource de l'application. Ce gestionnaire s'excute au dbut de chaque requte envoye par un client au serveur (demande d'une page). Ce gestionnaire peut tre exploit pour examiner la requte avant de l'envoyer la page demande. Il est mme possible de rediriger la requte vers une autre page. Ce gestionnaire s'excute la fin de chaque requte envoye par un client au serveur Ce gestionnaire s'excute chaque fois que se produit une erreur non explicitement interceptes dans le code du fichier Global.asax ou dans les fichiers .aspx et .cs. Il constitue un bon moyen pour centraliser le processus de gestion des erreurs pouvant se produire dans toute l'application. Ce gestionnaire s'excute chaque ouverture d'une nouvelle session. Ce gestionnaire s'excute la fermeture de chaque session. (la fermeture d'une session peut tre dclenche par la fermeture du navigateur, ou suite l'coulement d'un dlai d'inactivit de la session. Une page Web peut proposer galement une commande de fermeture explicite de la session l'utilisateur).

Session_Start ou galement Session_OnStart

EventHandler

Session_End

EventHandler

Structure du fichier Global.asax


<%@ Application language="C#" %> <script runat="server"> public // } public // } public // } public // } public // } public // } public // } </script> void Application_Start(Object sender, EventArgs e){ Code qui s'excute lors du dmarrage de l'application. void Application_End(Object sender, EventArgs e){ Code qui s'excute lorsque l'application se termine void Application_BeginRequest(Object sender, EventArgs e){ Code qui s'excute au dbut de chaque demande de page void Application_EndRequest(Object sender, EventArgs e){ Code qui s'excute la fin de chaque demande de page void Application_Error(Object sender, EventArgs e) { Code qui s'excute lorsqu'une erreur non gre se produit void Session_Start(Object sender, EventArgs e) { Code qui s'excute lors du dmarrage d'une session void Session_End(Object sender, EventArgs e) { Code qui s'excute lorsqu'une session se termine

Commentaire : La directive utilise au dbut du fichier n'est plus Page comme cela a t le cas pour les exemples prcdents mais Application : <%@ Application language="C#" %>. Avec cette directive, toutes les mthodes qui figurent dans la partie script du fichier seront compiles et ajoutes la classe Global base sur HttpApplication.

142

Karim Kalti

Version "Code behind" du fichier Global.asax Comme les fichiers aspx, le fichier Global.asax peut tre organis suivant le modle "Code Behind" et tre ainsi rparti sur deux fichiers Global.asax et Global.asax.cs. Contenu du fichier Global.asax
<%@ Application src="Global.asax.cs" Inherits="Global" %>

Contenu du fichier Global.asax.cs


public class Global : System.Web.HttpApplication { public Global() { } protected void Application_Start(Object sender, EventArgs e) { } protected void Session_Start(Object sender, EventArgs e) { } protected void Application_BeginRequest(Object sender, EventArgs e){ } protected void Application_EndRequest(Object sender, EventArgs e){ } protected void Application_Error(Object sender, EventArgs e){ } protected void Session_End(Object sender, EventArgs e){ } protected void Application_End(Object sender, EventArgs e){ } }

Exemple d'application 1 L'exemple suivant montre les diffrents moments d'appel des gestionnaires d'vnements Application_Start, Session_Start et Application_BeginRequest dfinis dans le fichier Global.asax. Fichier Global.asax :
<%@ Application language="C#" %> <script runat="server"> public void Application_Start(Object sender, EventArgs e) { Application["StartApp"] = DateTime.Now.ToString("T"); } public void Session_Start(Object sender, EventArgs e) { Session["StartSess"] = DateTime.Now.ToString("T"); } public void Application_BeginRequest(Object sender, EventArgs e) { Context.Items["StartReq"] = DateTime.Now.ToString("T"); } </script>

Fichier principal.aspx
<html> <head> <%@ Page Language="C#" Debug="true" %> <script runat="server"> string string string string jeton; startApplication; startSession; startRequest;

void Page_Load(object sender, EventArgs e) { jeton=Session.SessionID; startApplication = Application["StartApp"].ToString(); startSession = Session["StartSess"].ToString(); startRequest = Context.Items["StartReq"].ToString(); } </script>

143

Karim Kalti

</head> <body> jeton de session : <% =jeton %> <br /> dbut Application : <% =startApplication %> <br /> dbut Session : <% =startSession %> <br /> dbut Requte : <% =startRequest %> <br /> </body> </html>

Pour voir les diffrents moments d'excution des gestionnaires d'vnements lancer le fichier principal.aspx partir de plusieurs instances du navigateur sur une mme machine ou sur des machines diffrentes.

Exemple d'application 2 Cet exemple montre comment il est possible en utilisant les variables d'application de dterminer le nombre d'utilisateurs connects. Fichier Global.asax :
<%@ Application language="C#" %> <script runat="server"> public void Application_Start(Object sender, EventArgs e) { Application["NbUtilisateurs"] = 0; } public void Session_Start(Object sender, EventArgs e) { Application["NbUtilisateurs"] = Convert.ToInt32(Application["NbUtilisateurs"])+1; } public void Session_End(Object sender, EventArgs e) { Application["NbUtilisateurs"] = Convert.ToInt32(Application["NbUtilisateurs"])-1; } </script>

Fichier principal.aspx
<%@ Page Language="C#" %> <html> <head> </head> <body> Nombre d'utilisateurs connects : <% =Application["NbUtilisateurs"] %> <br /> </body> </html>

Commentaires : La fermeture du navigateur n'engendre pas la terminaison immdiate de la session. Cette dernire se termine en effet aprs l'coulement d'un Timeout paramtrable dans le fichier Web.config. (fichier de configuration d'une application Web ASP.NET) Les variables d'application et de session sont par dfaut de type object. Ceci explique d'une part la possibilit d'y placer directement des valeurs et d'autre part la ncessiter de les convertir travers un casting lorsqu'elles sont utilises dans des expressions.

144

Karim Kalti

Accs aux donnes dans les applications Web ASP.NET


Introduction
L'accs aux donnes dans les applications Web ASP.NET se fait l'aide de ADO.NET comme c'est le cas pour toutes les applications dveloppes en .NET. Dans une page Web dynamique qui fait des accs une base de donnes, le rle de ASP se rduit alors au dveloppement de la couche "Prsentation" (interface). L'accs et le traitement des donnes se font en effet l'aide de ADO.NET en utilisant comme langage C# ou VB. Les deux modes d'accs (connect et dconnect) supports par ADO.NET peuvent tre utiliss en ASP.NET. Les paragraphes suivants prsentent des exemples de pages Web dynamiques faisant des accs une base de donnes pour effectuer diffrentes oprations de mise jour et de slection. La base de donnes considre possde les caractristiques suivantes : Nom :"BIBLIO ". Format : MS ACCESS. Tables : une seule table appele "OUVRAGE". La structure de la table OUVRAGE est comme suit :

Ouvrage
Inventaire 1 2 3 4 5 Titre AnneEdition Programmation C++ 2003 Les rseaux 2004 Les bases de donnes 1995 Java 1999 UML 2004

Exemple 1 : Page d'ajout d'un ouvrage la base

<%@ Page Language="C#" Debug="true" %> <%@ import Namespace="System.Data" %> <%@ import Namespace="System.Data.OleDb" %> <script runat="server"> void ClickAjouter(object sender, EventArgs e) { // Cration de la chane de connexion string StrCnn = "Provider = Microsoft.Jet.OLEDB.4.0; Data Source ="+ // Cration de l'objet de connexion OleDbConnection cnn = new OleDbConnection(StrCnn); // Ouverture de la connexion cnn.Open(); // Texte de la commande string StrSql = "INSERT INTO Ouvrage VALUES ("+ TxtBInventaire.Text+",'"+TxtBTitre.Text+"',"+ TxtBEdition.Text+")"; // Cration de l'objet Command OleDbCommand cmd=new OleDbCommand(StrSql,cnn);

MapPath("Biblio.mdb");

145

Karim Kalti

// Excution de la commande try { cmd.ExecuteNonQuery(); } catch(Exception) { Response.Write("Erreur d'insertion"); } finally { // Fermeture de la connexion cnn.Close(); } } </script> <html> <head> </head> <body> <form runat="server"> <div align="left"><font size="7">Ajout d'ouvrages</font> </div> <div align="left"> </div> <div align="left"><asp:Label id="LbInventaire" runat="server">Inventaire : </asp:Label>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<asp:TextBox id="TxtBInventaire" runat="server" Width="162px"></asp:TextBox> <br /> <asp:Label id="LbTitre" runat="server">Titre : </asp:Label>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbs p;&nbsp;&nbsp; <asp:TextBox id="TxtBTitre" runat="server" Width="159px"></asp:TextBox> <br /> <asp:Label id="LbEdition" runat="server">Anne d'dition : </asp:Label> <asp:TextBox id="TxtBEdition" runat="server" Width="160px"></asp:TextBox> </div> <div align="left"> </div> <div align="left"> <asp:Button id="BtnAjouter" onclick="ClickAjouter" runat="server" Width="86px" Text="Ajouter"></asp:Button> </div> <!-- Insert content here --> </form> </body> </html>

146

Karim Kalti

Exemple 2 : Affichage de la liste des ouvrages

<%@ Page Language="C#" Debug="true" %> <%@ import Namespace="System.Data" %> <%@ import Namespace="System.Data.OleDb" %> <script runat="server"> void Page_Load(object sender, EventArgs e) { string StrCnn = "Provider = Microsoft.Jet.OLEDB.4.0; ="+MapPath("Biblio.mdb"); OleDbConnection cnn = new OleDbConnection(StrCnn); string StrSql = "SELECT * FROM Ouvrage"; OleDbDataAdapter DA; DataSet DS; cnn.Open(); DA = new OleDbDataAdapter(StrSql,cnn); DS = new DataSet(); DA.Fill(DS,"LesInventaires"); DG.DataSource = DS; DG.DataMember = DS.Tables["LesInventaires"].ToString(); DG.DataBind(); } </script> <html> <head> </head> <body> <form runat="server"> <p> <font size="7">Liste des ouvrages</font> </p> <p> <font size="7"> <asp:DataGrid id="DG" runat="server" EnableViewState="False" OnLoad="Page_Load"> <HeaderStyle font-bold="True" horizontalalign="Center" forecolor="Black" verticalalign="Middle" backcolor="Silver"></HeaderStyle> <AlternatingItemStyle horizontalalign="Center" backcolor="WhiteSmoke"></AlternatingItemStyle> <ItemStyle horizontalalign="Center" verticalalign="Middle" backcolor="Beige"></ItemStyle> </asp:DataGrid> </font> </p> </form> </body> </html> Data Source

147

Karim Kalti

Exemple 3 : Page de suppression d'un ouvrage de la base

<%@ Page Language="C#" Debug="true" %> <%@ import Namespace="System.Data" %> <%@ import Namespace="System.Data.OleDb" %> <script runat="server"> void Page_Load(object sender, EventArgs e) { if(IsPostBack==false) { string StrCnn = "Provider = Microsoft.Jet.OLEDB.4.0; Data Source ="+MapPath("Biblio.mdb"); OleDbConnection cnn = new OleDbConnection(StrCnn); cnn.Open(); string StrSql = "SELECT * FROM Ouvrage"; OleDbDataAdapter DA; DataSet DS; DA = new OleDbDataAdapter(StrSql,cnn); DS = new DataSet(); DA.Fill(DS,"LesInventaires"); CmbInventaire.DataSource=DS.Tables["LesInventaires"]; CmbInventaire.DataTextField="Inventaire"; CmbInventaire.DataBind(); TxtBTitre.Text= DS.Tables["LesInventaires"].Rows[CmbInventaire.SelectedIndex]["Titre"].ToString(); TxtBEdition.Text= DS.Tables["LesInventaires"].Rows[CmbInventaire.SelectedIndex]["AnneEdition"].ToString(); cnn.Close(); } } void ClickSupprimer(object sender, EventArgs e) { string StrCnn = "Provider = Microsoft.Jet.OLEDB.4.0; Data Source ="+MapPath("Biblio.mdb"); OleDbConnection cnn = new OleDbConnection(StrCnn); OleDbDataAdapter DA; DataSet DS; cnn.Open(); string StrSql = "DELETE FROM Ouvrage WHERE Inventaire = "+ CmbInventaire.SelectedValue; OleDbCommand cmd=new OleDbCommand(StrSql,cnn);

148

Karim Kalti

try { cmd.ExecuteNonQuery(); // Suppression DA = new OleDbDataAdapter("SELECT * FROM Ouvrage",cnn); DS = new DataSet(); DA.Fill(DS,"LesInventaires"); CmbInventaire.DataSource=DS.Tables["LesInventaires"]; CmbInventaire.DataTextField="Inventaire"; CmbInventaire.DataBind(); TxtBTitre.Text= DS.Tables["LesInventaires"].Rows[CmbInventaire.SelectedIndex]["Titre"].ToString(); TxtBEdition.Text= DS.Tables["LesInventaires"].Rows[CmbInventaire.SelectedIndex]["AnneEdition"].ToString(); } catch(Exception) { Response.Write("Erreur de suppression"); } finally { cnn.Close(); } } void Index_Changed(object sender, EventArgs e) { string StrCnn = "Provider = Microsoft.Jet.OLEDB.4.0; Data Source ="+MapPath("Biblio.mdb"); OleDbConnection cnn; OleDbDataReader rd; OleDbCommand cmd; cnn = new OleDbConnection(StrCnn); cnn.Open(); string StrSql = "SELECT * FROM Ouvrage WHERE Inventaire = "+CmbInventaire.SelectedValue; try { cmd = new OleDbCommand(StrSql,cnn); rd = cmd.ExecuteReader(); if(rd!=null) { if(rd.Read()) { TxtBTitre.Text=rd["Titre"].ToString(); TxtBEdition.Text=rd["AnneEdition"].ToString(); } } } catch(Exception) { Response.Write("erreur");} finally { cnn.Close();} } </script> <html> <head> </head> <body> <form runat="server"> <div align="left"><font size="6">Suppression&nbsp;d'ouvrages</font> </div> <div align="left"> </div> <div align="left"><asp:Label id="LbInventaire" runat="server">Inventaire : </asp:Label>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <asp:DropDownList id="CmbInventaire" runat="server" Width="160px" OnSelectedIndexChanged="Index_Changed" AutoPostBack="True"></asp:DropDownList> <br/> <asp:Label id="LbTitre" runat="server">Titre : </asp:Label>&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;<asp:TextBox id="TxtBTitre" runat="server" Width="161"></asp:TextBox> <br/> <asp:Label id="LbEdition" runat="server">Anne d'dition : </asp:Label>&nbsp; <asp:TextBox id="TxtBEdition" runat="server" Width="161"></asp:TextBox> </div> <div align="left"> </div> <div align="left"> <asp:Button id="BtnSupprimer" onclick="ClickSupprimer" runat="server" Width="86px" Text="Supprimer"></asp:Button> </div> </form> </body> </html>

149

Karim Kalti

Le code de l'exemple de suppression a t dlibrment crit de faon montrer la possibilit d'utiliser les modes connect et dconnect de ADO.NET dans ASP.NET. Ainsi dans certains gestionnaires on trouve parfois des accs la base l'aide des objets Command d'une part et l'aide du DataAdpeter et du DataSet d'autre part. Il serait plus judicieux d'utiliser un seul mode par gestionnaire. Il est noter par ailleurs que chaque gestionnaire a utilis ses propres objets de connexion la base. Il est possible d'optimiser encore plus le code en proposant une autre conception qui fait partager tous ces objets par les diffrents gestionnaires.

Exercices
Exercice d'application 1 : Proposer une version "code behind" des trois pages d'ajout, de suppression et de consultation d'ouvrages. Exercice d'application 2 : Proposer une nouvelle conception du code de la page de suppression d'ouvrages utilisant seulement un mode de travail (connect ou dconnect) et permettant de faire partager les objets de connexion la base par tous les gestionnaires. Exercice d'application 3 : Proposer une nouvelle conception du code de l'application (ajout, suppression et consultation d'ouvrages) de faon permettre le partage des mmes objets de connexion par toutes les pages de l'application.

150

Karim Kalti

Le fichier de configuration Web.config


Vue d'ensemble
ASP.Net propose un modle de configuration des applications Web bas sur l'utilisation de fichiers de configuration spars de l'application. Ce systme fournit une infrastructure de configuration hirarchique permettant la dfinition et l'utilisation de donnes de configuration extensibles dans une application, un site et/ou un ordinateur. Ce modle prsente plusieurs avantages : o Les donnes de configuration sont enregistres dans des fichiers de texte brut. Les administrateurs et les dveloppeurs peuvent utiliser n'importe quel diteur de texte, analyseur XML ou langage de script standard pour interprter et mettre jour ces donnes de configuration. o Les modifications apportes aux fichiers de configuration ASP.NET sont automatiquement dtectes par le systme et appliques sans intervention de la part de l'utilisateur (en d'autres termes, un administrateur ne doit pas redmarrer le serveur Web ou ramorcer l'ordinateur pour qu'elles entrent en vigueur).

Modle hirarchique des fichiers de configuration


Les fichiers de configuration ASP.NET sont des fichiers texte bass sur XML, portant chacun le nom Web.config, et pouvant apparatre dans n'importe quel rpertoire d'un serveur d'application Web ASP.NET. Chaque fichier Web.config applique des paramtres de configuration au rpertoire dans lequel il se trouve et tous ses rpertoires virtuels enfants. Les paramtres des rpertoires enfants peuvent ventuellement substituer ou modifier les paramtres spcifis dans les rpertoires parents. Le fichier de configuration racine : WinNT\Microsoft.NET\Framework\<version>\config\ machine.config, fournit les paramtres de configuration par dfaut pour la totalit de l'ordinateur. Au moment de l'excution, ASP.NET utilise ces fichiers de configuration Web.config pour calculer de manire hirarchique une collection unique de paramtres pour chaque demande cible d'URL entrante (ces paramtres ne sont calculs qu'une seule fois, avant d'tre mis en cache pour les demandes suivantes. ASP.NET recherche automatiquement les modifications du fichier et invalide le cache si un des fichiers de configuration est modifi). Exemple : Les paramtres de configuration de l'URL http://myserver/myapplication/mydir/page.aspx sont calculs en appliquant les paramtres du fichier Web.config dans l'ordre suivant :
Base configuration settings for machine. C:\WinNT\Microsoft.NET\Framework\v.1.00\config\machine.config Overridden by the configuration settings for the site (or the root application). C:\inetpub\wwwroot\Web.config Overridden by application configuration settings. D:\MyApplication\Web.config Overridden by subdirectory configuration settings. D:\MyApplication\MyDir\Web.config

Si un fichier Web.config est prsent dans le rpertoire racine d'un site, par exemple Inetpub\wwwroot , ses paramtres de configuration s'appliquent toutes les applications de ce site. Certains de ces paramtres peuvent tre redfinis l'intrieur d'une application et ce l'aide d'un fichier Web.config spcifique cette application et situ la racine de cette dernire. Remarque 1 : La prsence d'un fichier Web.config la racine d'une application ou dans un rpertoire donn est compltement facultative. Si aucun fichier Web.config n'est prsent, tous les paramtres de configuration du rpertoire sont automatiquement hrits du rpertoire parent.

151

Karim Kalti

Remarque 2 : ASP.NET configure IIS pour viter que le navigateur puisse accder directement aux fichiers Web.config afin de garantir que leurs valeurs ne risquent pas d'tre publiques. En cas de tentative d'accs ces fichiers, ASP.NET retourne l'erreur 403: Accs interdit.

Structure d'un fichier de configuration


Un fichier Web.config est un fichier texte bas sur XML, contenant des lments de document XML standard, notamment des balises au format adquat, des commentaires, du texte, etc. La racine du document : L'lment racine d'un fichier Web.config est toujours une balise <configuration>. Les paramtres ASP.NET et d'utilisateur final sont ensuite encapsuls dans la balise de la manire suivante :
<configuration> <!- les paramtres de configurations doivent tre ici --> </configuration>

Les groupes de sections : Le corps du fichier de configuration est organis d'une manire hirarchique en groupes de sections. Chaque groupe de sections est dfini par une balise qui porte le nom du groupe. Exemple : System.Web est un groupe de section qui contient les sections de configuration les plus frquemment utilises.
<configuration> <System.Web> <!- les paramtres de configurations doivent tre ici --> </System.Web> </configuration>

Un groupe de sections peut comporter d'autres sous-groupes de sections. Remarque : Les groupes de sections sont facultatifs. Ils ont essentiellement un intrt organisationnel permettant de regrouper les sections de configuration d'une manire thmatique. Section de configuration Une section de configuration est une zone qui comprend des paramtres de configuration. Cette zone est dfinie par une paire de balises qui porte le nom de la section. Les paramtres sont dfinis sous forme d'attributs de cette balise. Les sections de configuration les plus utilises dans le groupe de sections system.web sont : Section sessionState compilation trace Exemple :
<configuration> <System.Web> <SessionState> <!- les paramtres de configurations doivent tre ici --> </SessionState> <Compilation> <!- les paramtres de configurations doivent tre ici --> </Compilation> </System.Web> </configuration>

Description Permet de grer les sessions au sein de l'application Web. Permet de grer les paramtres de compilation pour ASP.NET. Permet de grer le suivi ASP.NET.

152

Karim Kalti

Centralisation de la configuration
Grce l'organisation hirarchique des fichiers de configuration et la possibilit d'hritage des paramtres, il est possible de centraliser tous les paramtres de toutes les applications Web dans un seul fichier Web.config plac la racine du serveur Web. L'accs aux paramtres spcifiques chaque application se fait alors l'aide d'une balise Location laquelle on passe le chemin de l'application comme suit :
<configuration> <location path="WebApp1"> <System.Web> <!- les sections de configuration de WebApp1 --> </System.Web> <location path="WebApp1"> <location path="WebApp2"> <System.Web> <!- les sections de configuration de WebApp2 --> </System.Web> <location path="WebApp2"> </configuration>

Verrouillage des paramtres de configuration


Outre la spcification des informations de chemin d'accs l'aide de la balise <location>, il est galement possible de configurer la scurit afin que les paramtres ne puissent pas tre substitus par un autre fichier de configuration situ un niveau infrieur de la hirarchie de la configuration. Pour verrouiller un groupe de paramtres, il faut spcifier un attribut allowOverride sur la balise <location> qui l'entoure et lui affecter la valeur false. Le code suivant verrouille les paramtres d'emprunt d'identit pour deux applications diffrentes.
<configuration> <location path="app1" allowOverride="false"> <system.web> <identity impersonate="false" userName="app1" password="app1pw" /> </system.web> </location> <location path="app2" allowOverride="false"> <system.web> <identity impersonate="false" userName="app2" password="app2pw" /> </system.web> </location> </configuration>

Si un utilisateur tente de substituer ces paramtres dans un autre fichier de configuration, le systme de configuration affiche une erreur :
<configuration> <system.web> <identity userName="developer" password="loginpw" /> </system.web> </configuration>

Paramtres personnaliss
Il est possible d'ajouter dans le fichier de configuration des paramtres personnaliss comme la chane de connexion une base de donnes par exemple. Les paramtres personnaliss sont placs dans une section de configuration spciale dfinie par la balise appSettings. Exemple :
<configuration> <appSettings> <add key="ConnectionString" value="c:\Data\..."/> <add key="Nom" value="Dupond"/> </appSettings> </configuration>

153

Karim Kalti

L'ajout d'un paramtre personnalis se fait l'aide de la balise <add> comme suit :
<add key="identificateur" value="valeur"/>

Accs aux paramtres de configuration par programmation


ASP.NET fournit des classes qui permettent de rcuprer les valeurs des paramtres de configuration par programmation l'intrieur de l'application. Il fournit mme grce la classe ConfigurationSettings un moyen pour rcuprer les valeurs des paramtres personnaliss dfinis par l'utilisateur. L'accs aux paramtres se fait l'aide de la proprit AppSettings de la classe ConfigurationSettings. Proprit
AppSettings

Type
Collection NameValueCollection

Signification
Permet de rcuprer la liste des paramtres dfinis dans la section appSettings sous forme d'une collection de paires (paramtre/valeur). La collection NameValueCollection possde un indexeur qui prend comme argument le nom du paramtre et qui retourne sa valeur.

Exemple :
using System.Configuration; . . . string strcnn =ConfigurationSettings.AppSettings["ConnectionString"];

154

Karim Kalti

Les services Web


Introduction
La notion de composant logiciel Un composant logiciel est un module informatique qui effectue une tche bien donne et qui s'intgre par programmation dans une application de plus grande taille. Caractristiques des composants logiciels Les composants exposent gnralement un certain nombre de classes instanciables et de mthodes invocables par programmation par les applications qui intgrent ces composants. Ces classes et mthodes sont appeles les interfaces du composant. Un composant cache aux applications qui l'intgrent ses membres privs. Les composants sont compils. Ils cachent par consquent les dtails de leur implmentation. Un composant logiciel classique doit se trouver dans la mme machine que l'application qui l'appelle. Exemples de technologies utilises pour la cration de composants Il existe plusieurs technologies permettant la cration de composants logiciels comme par exemple : les dll, les ActiveX, les objets COM, et les Java Beans. Certaines de ces technologies sont indpendantes des langages comme par exemple la technologie COM et les ActiveX. Un composant issu de ces technologies peut tre crit dans un langage et appel par un programme crit dans un autre langage. D'autres technologies sont spcifiques un langage bien donn (les Beans pour le langage JAVA). Avantages des composants Rutilisation. Acclration du processus de dveloppement et rduction des cots. Facilit de maintenance des applications. Les composants distribus Aujourd'hui l'informatique de l'entreprise est rsolument devenue distribue. Les "gros" systmes informatiques sont le plus souvent rpartis sur plusieurs sites physiquement distribus. Par ailleurs, grce l'volution des technologies Client/Serveur, de plus en plus d'applications offrent la possibilit de consultation de leurs services distance (exemple : consultation des comptes bancaires partir des mobiles ou de l'Internet). Le dveloppement de ce genre d'applications a engendr la ncessite de l'utilisation de composants logiciels invocables distance. Technologies utilises La premire technologie qui a t utilise pour crer des composants invocables distance est la technologie RPC (Remote Procedure Call). D'autres technologies orientes objet ont galement vu le jour par la suite : DCOM, CORBA, RMI. La technologie des services Web est le dernier n dans ce genre de technologies d'accs distants aux composants logiciels programmables.

Qu'est ce qu'un service Web


Un Service Web est une unit logique applicative programmable accessible via les protocoles standards de l'Internet. En d'autres mots, c'est une librairie fournissant des donnes et des services dautres applications travers un rseau intranet ou extranet en utilisant les technologies de l'Internet.

155

Karim Kalti

Objectifs Accs rapide, intgr et gnralis l'information en interne (Intranet) ou en externe (Internet). Interoprabilit : Les services Web sont indpendants de la plateforme (unix, windows, ) et du langage de programmation (C#, VB.NET, Java, ). Leur capacit de faire converser entre elles des applications et des composants htrognes est remarquable. On peut trs bien raliser un service Web fonctionnant sous GNU/Linux en Java et l'interroger depuis une page Web ASP.NET en mme temps que depuis une application Perl. Rutilisation : l'utilisation des composants distribus permet d'acclrer le processus de dveloppement d'applications et rduit par consquent les cots. Exemples de services Web Diffusion d'informations : (horaires des vols, des trains, cours de la bourse, tats de stocks, incidents, ). Commerce lectronique : (prsentation, transactions, paiement, recherche, ) Authentification d'accs.

Les Architectures Orientes Services (SOA)


Prsentation Une architecture oriente services (note SOA pour Services Oriented Architecture) est une architecture logicielle s'appuyant sur un ensemble de services simples. La notion de service dsignant ici une fonction encapsule dans un composant que l'on peut interroger l'aide d'une requte compose d'un ou plusieurs paramtres et fournissant une ou plusieurs rponses. Idalement chaque service doit tre indpendant des autres afin de garantir sa rutilisabilit et son interoprabilit. L'ide sous-jacente derrire les SOA est de cesser de construire les applications de l'entreprise sous forme d'un systme tout-en-un pour faire en sorte de construire une architecture logicielle globale dcomposes en services correspondant chacun un des processus mtiers de l'entreprise. Le rle de ces architectures globales revient alors dcrire finement le schma d'interaction entre ces services. Lorsque l'architecture SOA s'appuie sur des services Web, on parle alors de WSOA, pour Web Services Oriented Architecture). Avantages d'une architecture oriente service Une architecture oriente services permet d'obtenir tous les avantages d'une architecture client-serveur et notamment : Une modularit permettant de remplacer facilement un composant (service) par un autre. Une rutilisation possible des composants (par opposition un systme tout-en-un fait sur mesure pour une organisation). De meilleures possibilits d'volution (il suffit de faire voluer un service ou d'ajouter un nouveau service). Une plus grande tolrance aux pannes et une maintenance facilite

Les intervenants dans le processus d'utilisation d'un service Web


Le client (Service Requester) : le demandeur de service. C'est une application cliente qui se connecte un service et invoque ses fonctions. L'annuaire de services (Service Registry) : c'est l'annuaire des services publis par les fournisseurs de services. L'annuaire est gr sur un serveur au niveau Intranet ou Internet. L'annuaire permet de retrouver le service et de rcuprer les informations qui le concernent. Le fournisseur de service (Service Provider) : Composant s'excutant sur un serveur d'applications et qui fournit le service demand.

156

Karim Kalti

Le scnario complet d'utilisation d'un service Web


Le scnario d'utilisation d'un service comporte deux grande phases : la publication et la consommation du service. La publication du service Etape 1: Dfinition et description du service : il s'agit d'une description d'un point de vue informatique du service Web. La description est faite en WSDL au sein du fournisseur de services. Etape 2 : Publication du service Une fois le service dfini et dcrit en termes de mise en uvre, il peut tre dclar dans un annuaire. Il s'agit alors de la publication du service afin de le rendre accessible aux clients. La publication est faite au sein d'un annuaire ddi. La Consommation du service Etape 1 : Recherche du service (1 et 2 sur la figure) Le client se connecte un annuaire pour effectuer une recherche de service. Etape 2 : Etablissement de contrats (3 et 4 sur la figure) Une fois le service trouv par le client, ce dernier doit tablir un contrat avec le fournisseur. Ce contrat consiste en un document WSDL transmis par le fournisseur au client et indiquant les rgles d'utilisation que doit respecter le client s'il veut exploiter le service. Etape 3 : Mise en uvre du service (5 et 6 sur la figure) Le client peut invoquer le service suivant les conditions du contrat mentionnes dans le document WSDL et le fournisseur renvoie le rsultat.

Figure 1 : scnario complet d'utilisation d'un service

Remarque : la composition de services Un service Web peut jouer le rle de client un autre service Web. On parle dans ce cas de composition de services.

157

Karim Kalti

Pile de protocoles standards utiliss par les services Web


Les protocoles standards utiliss par les services Web sont : UDDI, WSDL, SOAP, XML, HTTP. Tous ces protocoles sont disposs en couches comme le montre la figure ci-dessous :

UDDI (standard) ou DISCO (MS) WSDL (bas sur XML et XSD) SOAP (bas sur XML)
Protocole de transport (http, SMTP, )

Publication et recherche de services Description des services Communication (change de messages) N'importe quel protocole (gnralement le HTTP)

Le WDSL : Web Service Description Language


Le WSDL est un langage de description de services Web bas sur XML. La description est faite en deux niveaux d'abstraction : Le niveau interface du service. Il s'agit d'une description indpendante des dtails de l'implmentation du service. Elle permet de garantir l'interoprabilit du service (neutralit par rapport la plateforme et au langage). La description concerne dans ce cas : o o Les types : il s'agit des types de donnes manipuls par le service. La description est faite en XSD. Les messages : un message dcrit la nature des donnes changes entre le service et le client. Cette description indique le type de ces donnes, et le rle qu'elles jouent dans l'change. Par exemple l'interaction avec une mthode du service ncessite deux messages, un dcrivant l'appel de la mthode (Request) et les donnes passer comme arguments et l'autre dcrivant la rponse de la mthode (Response). Les donnes changes dans chaque message sont dfinies avec les lments "Part". Les types de ports : le type de port dcrit l'ensemble des oprations abstraites d'un service. Une opration abstraite est une description d'une mthode du service en terme de paramtres en entre et de valeur de retour. En d'autres mots une opration abstraite est une description de la signature d'une mthode du service sous forme de messages (en fait c'est une squence de deux messages un pour l'appel de la mthode et l'autre pour le retour). Les liaisons : une liaison dcrit les dtails ncessaires l'appel effectif d'une opration abstraite. Ces dtails concernent la technique d'invocation distante de l'opration, le protocole utilis pour recevoir les donnes en entre et pour renvoyer la valeur de retour (http, RPC, ).

Le niveau implmentation du service : cette description s'intresse aux informations permettant de localiser le service sur un serveur donn. Elle concerne : o Les ports : un port (appel galement endpoint) reprsente une adresse url qui est associe l'implmentation de l'une des liaisons d'un service par un fournisseur. Le service : Le service est dcrit comme une collection de ports. Chaque port dsigne l'adresse d'une des liaisons du service.

Remarque : Un mme service Web spcifi par son interface peut tre implmente par plusieurs fournisseurs. Les niveaux d'abstraction qu'offre le WSDL (notamment la distinction entre la description de l'interface et de l'implmentation) permettent de dcrire d'une manire unique un mme service et de rfrencer sparment ses diffrents fournisseurs (implmentations).

158

Karim Kalti

Figure 2 : Elments de la grammaire XML dfinissant le WSDL

Le SOAP : Simple Object Access Protocol


SOAP est un protocol permettant d'changer les informations dans un environnement distribu et htrogne. Ce protocole bas sur XML permet de dfinir : o Le format des messages d'informations changs entre le demandeur et le fournisseur du service. Les informations en question concernent essentiellement les noms des mthodes invoquer, les valeurs des paramtres leur faire passer et les valeurs renvoyes par ces mthodes. o La manire avec laquelle sont envoyes les donnes. o La manire avec laquelle sont reues les rponses. o L'encodage des donnes.

Figure 3 : Communication SOAP entre le client et le service

Elments d'un message SOAP Enveloppe : C'est l'enveloppe du message. Elle encapsule les sous lments du message. L'entte (header) : c'est sous lment optionnel de l'enveloppe. Il peut contenir des extensions d'informations telles que l'authentification, les sessions, Le corps (body) : c'est un sous lment obligatoire de l'enveloppe. Il contient des informations sur la mthode invoquer ainsi que ses paramtres (Request message) ou sur la valeur de retour (Response message). Il peut contenir un lment "Fault" en cas d'erreur.

159

Karim Kalti

Figure 4 : Architecture d'un message SOAP

Caractristiques de SOAP SOAP est bas sur le XML. Les donnes changes entre le demandeur et le fournisseur du service sont donc au format texte. SOAP est indpendant des systmes d'exploitation et des langages de programmation. Il permet par consquent l'interoprabilit des systmes. SOAP est indpendant du protocole de transport (il utilise souvent le protocole HTTP).

Figure 5 : Interoprabilit des services Web

160

Karim Kalti

DISCO
DISCO (Discovery) est une technologie de Microsoft pour la publication et la recherche de services Web. Il s'agit d'un algorithme qui permet de rechercher les services Web exposs sur un serveur donn. Il permet galement de dcouvrir les capacits de chaque service et la manire d'interagir avec lui et ce en analysant le document WSDL qui accompagne ce service. Publication d'un service l'aide de DISCO Pour publier un service Web l'aide de DISCO, il suffit de crer un fichier .disco et de le placer dans le rpertoire racine du service Exemple : pour un service appel math, il faut ajouter le fichier .disco comme suit dans le rpertoire du service.
\inetpub \wwwroot \math (vroot) math.asmx web.config math.disco \bin simpleMath.dll complexMath.dll

Le fichier .disco est un document XML qui contient des liens aux ressources qui dcrivent le service (document WSDL).
<disco:discovery xmlns:disco="http://schemas.xmlsoap.org/disco/" xmlns:scl="http://schemas.xmlsoap.org/disco/scl/"> <!-- reference to other DISCO document --> <disco:discoveryRef ref="related-services/default.disco"/> <!-- reference to WSDL and documentation --> <scl:contractRef ref="math.asmx?wsdl" docRef="math.asmx"/> </disco:discovery>

Rcupration des informations l'aide de DISCO La rcupration des informations travers un fichier .disco se fait l'aide d'un utilitaire qui fonctionne en ligne de commande appel disco.exe. Cette commande prend comme argument l'url du fichier .disco du service consulter. Exemple :
c:\temp> disco.exe http://localhost/math/math.disco

Cette commande gnre en sortie un fichier appel result.discomap qui contient des informations sur le service Web situ cette url. Remarques : Il est possible d'utiliser au lieu des fichiers .disco, des fichiers .vsdisco pour rcuprer d'une manire dynamique la liste de tous les services Web qui se trouvent sur un serveur donn spcifi par son url. (c'est spcifique pour MS VS). DISCO est une technologie de microsoft. Elle utilise pour la publication et la recherche petite chelle. Le client doit connatre au pralable l'url du service Web qu'il veut consommer (ce n'est pas toujours le cas en pratique). L'alternative DISCO est UDDI qui est un standard universel pour la publication et la recherche grande chelle de services Web.

161

Karim Kalti

UDDI : Universal Description, Discovery and Integration


UDDI est un annuaire qui donne des informations sur les entreprises et les services qu'elles publient. Il spcifie un mcanisme pour les fournisseurs de services Web pour publier leurs services et pour les consommateurs de services de localiser les services qui les intressent. Interaction avec un annuaire UDDI L'interaction avec un annuaire peut tre manuelle (via des moteurs de recherche) ou l'aide d'une API de programmation qui repose sur SOAP. Il existe deux API permettant de dialoguer avec un annuaire : o Une API d'interrogation de l'annuaire : permet de recherche dans les points d'entre de l'annuaire et de lire les descriptions des services. o Une API de publication : Elle permet de publier ou de supprimer des services au sein d'un annuaire. Elle impose des autorisations d'accs. Remarque : L'existence d'une API d'interrogation d'annuaires ouvre la porte aux applications consommatrices de dcouvrir d'une manire dynamique les services qui les intressent. Le service qui sera utilis peut ne pas tre connu au moment du dveloppement de l'application cliente (son interface doit tre connue mais pas son implmentation).

Figure 6 : Processus de dcouverte d'un service

Organisation des donnes dans l'annuaire L'annuaire est organis sous forme de pages de trois catgories selon les informations qu'elles renferment : Les pages blanches : elles contiennent des informations qui concernent les entreprises (noms des entreprises, leurs coordonnes, leurs domaines d'activit, des descriptions supplmentaires, etc.). Les pages jaunes : Elles donnent la liste des services par catgorie selon leurs natures ou selon les entreprises qui les proposent. Les pages vertes : elles contiennent les spcifications techniques des services, classes par socit.

Figure 7 : Types de pages d'un annuaire UDDI

162

Karim Kalti

Exemples d'entit de donnes utilises par UDDI Le modle UDDI comporte cinq structures de donnes principales dcrites sous formes de schmas XML : BusinessEntity : Ensemble d'informations sur l'entreprise qui publie le service (domaine d'activit, nom, description, coordonnes). BusinessService : Ensemble d'informations sur le service publi par l'entreprise (nom du service, sa description, son code unique). tModel : ensemble d'informations dcrivant le modle du service. C'est l'interface qui dfinie la spcification du service (Description WSDL). BindingTemplate : ensemble d'informations concernant le lieu d'hbergement du service (url de ses points d'accs). Il s'agit de l'url de l'implmentation de la spcification dcrite dans le tModel. La spcification d'un service peut avoir plusieurs implmentations proposes par diffrents industriels sous forme de plusieurs BindingTemplate qui rfrencent donc le mme tModel. PublisherAssertion : ensembles d'informations ncessaires l'tablissement de contrats entre partenaires dans le cadre d'changes commerciaux.

Annexe : Discovery-driven Applications


Cette annexe est une partie d'un article rdig par Aaron Skonnard dans lequel il discute des avantages et des inconvnients du processus de dcouverte dynamique des services publis dans les annuaires UDDI par les applications qui les consomment. Discovery-driven Applications Auteur : Aaron Skonnard Source : MSDN Magazine - Faburary 2002 One of the main benefits of UDDI's richer data model and more advanced inquiry API is that developers can build their applications around certain types of Web Services, each with the same technical specifications, interfaces, and protocols that can be discovered at runtime (just like COM component categories). This allows applications to automatically take advantage of new and improved Web Services (of that specific type) that are published after the application ships. Building applications with this functionality requires the lookup and categorization features offered today only by UDDI. However, even though it's technically possible to build discovery-driven applications, most developers won't do it. Developers want to choose their business partners a priori so they can establish strong relationships based on quality assurance and future legal liabilities. No serious developer is going to allow the inclusion of some hacker's completely untested service to debilitate his or her aggregate application. This is exactly why COM component category-based applications never gained wide acceptance in the industry. And since most of today's UDDI hype revolves around this type of discovery-driven application, it's unclear as to how much better this beefed-up API will be compared to something that is more primitive like DISCO. If the information in the existing UDDI repositories is a sign of future acceptance, it's not looking good. If you browse some of the test UDDI sites, you'll notice that there is plenty of yellow page information (like business name, business details, and so forth), but very little technical information (such as contract information or WSDL documents). Developers using DISCO today have found it simple and effective, and they retain complete control over the discovery process. Moving to UDDI increases the complexity by an order of magnitude and forces developers to either relinquish control to a centralized UDDI operating site or implement their own. It's hard to imagine that many will rush to implement that solution.

163

Karim Kalti

Mise en uvre des Services Web en .NET


Le FrameWork .NET travers ASP.NET fournit l'infrastructure ncessaire pour la cration et la consommation de services Web XML.

Outils pour dvelopper et dployer un service Web XML


Outils pour le dveloppement : Un diteur de texte pour crire le code (Exemple : Notepad). Le SDK du FrameWork .NET. Il existe des environnements de dveloppement intgrs (EDI) plus labors : Visual Studio.NET (payant) WebMatrix avec son serveur Web Cassini (gratuit). Outils pour le dploiement Un Serveur Web : IIS ou Cassini. La CLR : (elle doit tre installe aprs l'installation du serveur Web).

Implmentation d'un service Web XML


Fichier d'implmentation Un service Web XML est implment sous forme d'une classe place dans un fichier qui porte l'extension (.asmx). Cette classe comporte les mthodes exposes par le service. Toutefois un service peut ventuellement utiliser en interne d'autres ressources places dans des fichiers ayant d'autres extensions que (.asmx). Par exemple des fichiers de bases de donnes si le service en fait accs, des fichiers de code compil, etc. Langage d'implmentation En .NET un service Web peut tre programm dans n'importe quel langage support par ASP.NET (C#, VB, JavaScript).

Dclaration d'un service Web


La dclaration d'un service Web se fait de la manire suivante :
<%@ WebService Language="C#" Class="NomDuService"%>

Cette dclaration est faite dans un fichier (asmx). La directive @WebService indique que le fichier contient l'implmentation d'un service Web. L'attribut Language indique le langage de programmation utilis (C#, VB, JavaScript). L'attribut Class permet de spcifier le nom de la classe qui implmente le service Web.

164

Karim Kalti

Dfinition de la classe du service Web


La dfinition de la classe qui implmente le service Web se fait de la manire suivante :
using System.Web.Services; public class NomDuService { // Dfinition des mthodes du service [WebMethod] Mthode1( ) {} [WebMethod] MthodeN( ) {} }

NomDuService est le nom de la classe qui implmente le service Web. Cette classe publique comporte gnralement les mthodes qui seront exposes par le service. Mthodes exposes par un service Une mthode expose par un service est une mthode qui peut tre appele par le client du service. Une telle mthode : o doit tre membre de la classe qui implmente le service. o doit tre dclare publique. o doit tre prcde dans sa dfinition par l'attribut [WebMethod]. C'est cet attribut, qui va rendre la mthode appelables par les clients du service. Une mthode de la classe du service Web qui n'est pas dfinie en tant que [WebMethod] ne peut pas tre invoque par les clients mme si elle est dclare publique. [WebMethod] est un attribut prdfini en .NET dans l'espace de noms System.Web.Services. Ceci explique l'utilisation de la directive using System.Web.Services; avant la dfinition de la classe. Endroit de dfinition de la classe du service Web Dfinition dans le fichier (asmx) La classe qui implmente le service peut tre dfinie dans le fichier (asmx). Dans ce cas elle doit succder la dclaration du service.
<%@ WebService Language="C#" Class="NomDuService"%> using System.Web.Services; public class NomDuService { // Dfinition des mthodes du service [WebMethod] Mthode1( ) {} [WebMethod] MthodeN( ) {} }

Dfinition selon le modle "codebehind" La classe du service peut tre dfinie dans un fichier de code pur (.cs ou .vb) spar du fichier (asmx) selon le modle "codebehind" utilis par les WebForms (pages aspx). Contenu du fichier de dclaration du service (.asmx)
<%@ WebService Language="C#" CodeBehind="NomFichierClass.cs" Class="EspaceNoms.NomDuService"%>

La dclaration du service inclut dans ce cas une rfrence au fichier qui contient la dfinition de la classe. Cette rfrence est spcifie l'aide de l'attribut CodeBehind.

165

Karim Kalti

Contenu du fichier d'implmentation de la classe du service (.cs)


using System.Web.Services; namespace EspaceNoms { public class NomDuService { // Dfinition des mthodes du service [WebMethod] Mthode1( ) {} [WebMethod] MthodeN( ) {} } }

Remarque : Il est possible d'appeler dans la dclaration d'un service Web une classe dj compile au lieu du fichier contenant le code source de la classe. Dans ce cas, la dclaration du service doit tre effectue comme suit :
<%@ WebService Language="C#" Class="EspaceNoms.NomDuService, NomAssemblage"%>

NomAssemblage dsigne le nom de l'assemblage qui contient la classe compile. Ce dernier doit figurer dans le rpertoire \bin de l'application qui reprsente le service Web.

Ajout d'informations supplmentaires un service Web


Il est possible d'ajouter des informations supplmentaires un service Web. La spcification de ces informations est optionnelle. Elle se fait l'aide de l'attribut optionnel WebService. Cet attribut possde deux proprits intressantes : Namespace : cette proprit permet d'associer un espace de noms XML au service. Cet espace de noms permet aux applications clientes d'identifier d'une manire unique le service dans le cas o ce dernier porte le mme nom qu'un autre service publi sur le NET. Il est remarquer dans ce cadre que : o L'espace de noms par dfaut associ au service en cours de construction est http://tempuri.org/. o Si le fournisseur du service dsire publier ce dernier en intranet dans un domaine dont il contrle les noms des services alors la spcification de l'espace de noms n'est pas ncessaire et l'espace de noms par dfaut suffit. Toutefois si ce fournisseur dsire publier son service sur le NET alors l'attribution d'un espace de nom unique devient inluctable pour viter tout risque de conflit. o L'attribut Namespace peut accepter comme valeur n'importe quelle chane de caractres unique. Cependant la valeur qui lui est communment donne se prsente souvent sous la forme de l'url de l'entreprise qui fournit le service. o L'espace de noms dont il est question est l'espace XML. Il ne faut pas le confondre avec l'espace de noms de la classe qui implmente le service. Description : Cette proprit permet de fournir des informations supplmentaires pour dcrire avec plus de dtails le service. Le contenu gnrique d'un fichier (asmx) peut se prsenter comme suit :
using System.Web.Services; namespace EspaceNoms { [WebService (Namespace ="www.MonEspace.com") (Description = "Ce service permet ")] public class NomDuService { // Dfinition des mthodes du service [WebMethod] Mthode1( ) [WebMethod] MthodeN( ) } }

166

Karim Kalti

Remarque : Il est galement possible d'ajouter des informations supplmentaires pour chaque mthode du service et ce l'aide de la proprit Description de l'attribut [WebMethod].
[WebMethod (Description = "Cette mthode effectue ")] Mthode1( )

Gestion des tats Application et Session dans un service Web


Un service Web peut bnficier de la panoplie de possibilits qu'offre l'ASP.NET notamment en ce qui concerne la gestion des tats Application, Session, etc. Pour cela il faut faire driver la classe qui implmente le service de la classe System.Web.Services.WebService du FrameWork .NET. Le contenu gnrique d'un fichier (asmx) peut se prsenter comme suit :
using System.Web.Services; namespace EspaceNoms { [WebService (Namespace ="www.MonEspace.com", Description = "Ce service permet ")] public class NomDuService : WebService { // Dfinition des mthodes du service [WebMethod] Mthode1( ) [WebMethod] MthodeN( ) } }

Premier exemple de service Web


L'exemple suivant montre l'implmentation d'un service Web simple qui effectue la somme de deux entiers :
<%@ WebService Language="C#" Class="MathOps.Operations"%> using System.Web.Services; namespace MathOps { [WebService (Namespace="www.Test.com", Description = "Premier service Web")] public class Operations { [WebMethod (Description ="Cette mthode effectue la somme de deux entiers")] public int Somme(int a, int b) {return a+b;} } }

Test du service Web


Pour tester le service Web que l'on vient de crer, il n'est pas ncessaire de dvelopper une application cliente mais il suffit de placer le fichier Operations.aspx dans le rpertoire de publication (wwwroot pour IIS) et de taper son url dans le navigateur. http://localhost/Operations.asmx Le navigateur affiche une page cre automatiquement par IIS avec la collaboration des services du FrameWork qui dcrit le service Web demand. Cette description comporte : Le nom du service et sa description mentionne dans la proprit Description de l'attribut WebService. Les noms des mthodes exposes par le service et leurs descriptions mentionnes dans la proprit Description de l'attribut WebMethod.

167

Karim Kalti

Figure 1 : Interface de prsentation du service Web

Le clic sur le lien vers la mthode Somme engendre l'affichage de la page suivante :

Figure 2 : Interface de test de la mthode Somme

Cette page permet de tester la mthode Somme du service Web. L'appel de la mthode du service aurait pu tre effectu directement en tapant l'url suivante : http://localhost/Operations.asmx?op=Somme

168

Karim Kalti

Le navigateur affiche galement : o o le texte des deux messages SOAP utiliss par cette mthode pour recevoir les paramtres et pour renvoyer le rsultat. le texte montrant l'appel de la mthode l'aide de HTTP POST.

SOAP Le texte suivant est un exemple de demande et de rponse SOAP. Les espaces rservs affichs doivent tre remplacs par des valeurs relles. POST /Operations.asmx HTTP/1.1 Host: localhost Content-Type: text/xml; charset=utf-8 Content-Length: length SOAPAction: "www.Test.com/Somme" <?xml version="1.0" encoding="utf-8"?> <soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"> <soap:Body> <Somme xmlns="www.Test.com"> <a>int</a> <b>int</b> </Somme> </soap:Body> </soap:Envelope> HTTP/1.1 200 OK Content-Type: text/xml; charset=utf-8 Content-Length: length <?xml version="1.0" encoding="utf-8"?> <soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"> <soap:Body> <SommeResponse xmlns="www.Test.com"> <SommeResult>int</SommeResult> </SommeResponse> </soap:Body> </soap:Envelope>

HTTP POST Le texte suivant est un exemple de demande et de rponse HTTP POST. Les espaces rservs affichs doivent tre remplacs par des valeurs relles. POST /Operations.asmx/Somme HTTP/1.1 Host: localhost Content-Type: application/x-www-form-urlencoded Content-Length: length a=string&b=string HTTP/1.1 200 OK Content-Type: text/xml; charset=utf-8 Content-Length: length <?xml version="1.0" encoding="utf-8"?> <int xmlns="

169

Karim Kalti

La saisie des valeurs pour les deux paramtres a et b et le clic sur le bouton Appeler engendre l'affichage de la page suivante qui contient le rsultat :

Figure 3 : Page affichant le rsultat de la mthode Somme

Gnration de la description WSDL pour un service


La gnration de la description WSDL pour un service peut tre faite d'une manire automatique en adjoignant ?wsdl l'url du service. Pour l'exemple du service Operations, cela se traduit comme suit : http://localhost/Operations.asmx?wsdl La description gnre dans le navigateur est alors la suivante :
<?xml version="1.0" encoding="utf-8" ?> -<definitions xmlns:http=http://schemas.xmlsoap.org/wsdl/http/ xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:s="http://www.w3.org/2001/XMLSchema" xmlns:s0="www.Test.com" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:tm="http://microsoft.com/wsdl/mime/textMatching/" xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/" targetNamespace="www.Test.com" xmlns="http://schemas.xmlsoap.org/wsdl/"> - <types> - <s:schema elementFormDefault="qualified" targetNamespace="www.Test.com"> - <s:element name="Somme"> - <s:complexType> - <s:sequence> <s:element minOccurs="1" maxOccurs="1" name="a" type="s:int" /> <s:element minOccurs="1" maxOccurs="1" name="b" type="s:int" /> </s:sequence> </s:complexType> </s:element> - <s:element name="SommeResponse"> - <s:complexType> - <s:sequence> <s:element minOccurs="1" maxOccurs="1" name="SommeResult" type="s:int" /> </s:sequence> </s:complexType> </s:element> </s:schema> </types>

170

Karim Kalti

- <message name="SommeSoapIn"> <part name="parameters" element="s0:Somme" /> </message> - <message name="SommeSoapOut"> <part name="parameters" element="s0:SommeResponse" /> </message> - <portType name="OperationsSoap"> - <operation name="Somme"> <documentation>Cette mthode effectue la somme de deux entiers</documentation> <input message="s0:SommeSoapIn" /> <output message="s0:SommeSoapOut" /> </operation> </portType> - <binding name="OperationsSoap" type="s0:OperationsSoap"> <soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="document" /> - <operation name="Somme"> <soap:operation soapAction="www.Test.com/Somme" style="document" /> - <input> <soap:body use="literal" /> </input> - <output> <soap:body use="literal" /> </output> </operation> </binding> - <service name="Operations"> <documentation>Premier service Web</documentation> - <port name="OperationsSoap" binding="s0:OperationsSoap"> <soap:address location="http://localhost/Operations.asmx" /> </port> </service> </definitions>

Module proxy ncessaire pour le dveloppement d'un client du service Web


Le client d'un service Web est un programme qui fait appel aux mthodes exposes de ce service. De ce fait le programme client doit avoir une rfrence la classe qui implmente le service ainsi qu' ses mthodes pour pouvoir faire cet appel. L'obtention de la rfrence en question est assure par une classe appele proxy. Rle de la classe proxy La classe proxy joue le rle d'intermdiaire entre le client et le service Web demande. Dans ce cadre : Elle fournit aux programmes clients des rfrences aux mthodes exposes par le service. Ces rfrences servent appeler ces mthodes distantes (situes sur le serveur o est hberg le service). Elle ralise l'empaquetage du nom de la mthode ainsi que de ses arguments dans un message SOAP de type Request. Elle envoie ce message au serveur pour qu'il excute la mthode. Elle reoit un message SOAP de type Response contenant la valeur de retour de la mthode du service. Elle dcortique le message afin d'en extraire la valeur renvoye (au format XML) et de la traduire vers le type de donnes appropri. Rle du serveur (IIS avec la CLR) dans la mdiation entre le proxy et le service Web Le serveur : Reoit un message SOAP de type Request contenant un appel une mthode du service. Dcortique le message, en extrait le nom de la mthode et les paramtres et effectue l'appel. Rcupre la valeur de retour et effectue son empaquetage dans un message SOAP de type Response. Envoie le message au client.

171

Karim Kalti

Dfinition de la classe proxy


La classe System.Web.Services.Protocols.SoapHttpClientProtocol dispose d'un ensemble de mthodes qui implmentent une grande partie des oprations qui sont la charge du proxy client notamment l'invocation distante de mthodes et la construction et l'analyse des messages SOAP. Cette classe contient trois mthodes intressantes qui sont : o Invoke : Appelle une mthode de service Web XML de manire synchrone l'aide de SOAP. o BeginInvoke : Dbute un appel asynchrone d'une mthode de service Web XML au moyen de SOAP. o EndInvoke : Met fin un appel asynchrone d'une mthode de service Web XML au moyen de SOAP. La classe proxy ajouter au niveau de l'application cliente doit tre drive de la classe SoapHttpClientProtocol. Cette classe peut tre dfini par le programmeur ou gnre d'une manire automatique l'aide d'un utilitaire du FrameWork .NET appel WSDL.exe.

Gnration de la classe proxy L'utilitaire WSDL prend comme argument l'url du service Web pour lequel on veut crer un proxy. Pour l'exemple prcdemment prsent il faut taper : WSDL http://localhost/Operations.asmx L'utilitaire gnre alors un fichier Operations.cs qui contient la dfinition du proxy.
//-----------------------------------------------------------------------------// <autogenerated> // This code was generated by a tool. // Runtime Version: 1.1.4322.573 // // Changes to this file may cause incorrect behavior and will be lost if // the code is regenerated. // </autogenerated> //-----------------------------------------------------------------------------// // Ce // using using using using using using

code source a t automatiquement gnr par wsdl, Version=1.1.4322.573. System.Diagnostics; System.Xml.Serialization; System; System.Web.Services.Protocols; System.ComponentModel; System.Web.Services;

[System.Diagnostics.DebuggerStepThroughAttribute()] [System.ComponentModel.DesignerCategoryAttribute("code")] [System.Web.Services.WebServiceBindingAttribute(Name="OperationsSoap", Namespace="www.Test.com")] public class Operations : System.Web.Services.Protocols.SoapHttpClientProtocol { public Operations() { this.Url = "http://localhost/operations.asmx"; } [System.Web.Services.Protocols.SoapDocumentMethodAttribute("www.Test.com/Somme", RequestNamespace="www.Test.com", ResponseNamespace="www.Test.com", Use=System.Web.Services.Description.SoapBindingUse.Literal, ParameterStyle=System.Web.Services.Protocols.SoapParameterStyle.Wrapped)] public int Somme(int a, int b) { object[] results = this.Invoke("Somme", new object[] {a,b}); return ((int)(results[0])); }

172

Karim Kalti

public System.IAsyncResult BeginSomme(int a, int b, System.AsyncCallback callback, object asyncState) { return this.BeginInvoke("Somme", new object[] {a,b}, callback, asyncState); } public int EndSomme(System.IAsyncResult asyncResult) { object[] results = this.EndInvoke(asyncResult); return ((int)(results[0])); } }

Le nom de la classe proxy est celui du service. Cette classe comprend trois mthodes pour chaque mthode expose du service : une pour l'appel directe (Somme) de la mthode du service et deux pour un appel asynchrone (BeginSomme et EndSomme). Pour pouvoir exploiter la classe proxy il suffit de l'ajouter au code de l'application cliente. Cette application en question peut reprsenter n'importe quelle application qui peut faire usage du protocole HTTP.

Dveloppement d'une application cliente de type Console


L'exemple suivant montre une application de type console qui exploite le service Operations pour effectuer une opration d'addition. Le code de la classe proxy est copi dans le mme fichier que celui de la classe de la console.
using using using using using using System.Diagnostics; System.Xml.Serialization; System; System.Web.Services.Protocols; System.ComponentModel; System.Web.Services;

namespace ClientConsole { [System.Diagnostics.DebuggerStepThroughAttribute()] [System.ComponentModel.DesignerCategoryAttribute("code")] [System.Web.Services.WebServiceBindingAttribute(Name="OperationsSoap", Namespace="www.Test.com")] // La classe proxy public class Operations : System.Web.Services.Protocols.SoapHttpClientProtocol { public Operations() { this.Url = "http://localhost/operations.asmx"; } [System.Web.Services.Protocols.SoapDocumentMethodAttribute("www.Test.com/Somme", RequestNamespace="www.Test.com", ResponseNamespace="www.Test.com", Use=System.Web.Services.Description.SoapBindingUse.Literal, ParameterStyle=System.Web.Services.Protocols.SoapParameterStyle.Wrapped)] public int Somme(int a, int b) { object[] results = this.Invoke("Somme", new object[] {a,b}); return ((int)(results[0])); } public System.IAsyncResult BeginSomme(int a, int b, System.AsyncCallback callback, object asyncState) { return this.BeginInvoke("Somme", new object[] {a,b}, callback, asyncState); } public int EndSomme(System.IAsyncResult asyncResult) { object[] results = this.EndInvoke(asyncResult); return ((int)(results[0])); } }

173

Karim Kalti

// La classe qui fait appel au service class MainClass { public static void Main(string[] args) { // Instanciation du service Operations op=new Operations(); int i,j,s; Console.WriteLine("Donner un premier entier : "); i=Int32.Parse(Console.ReadLine()); Console.WriteLine("Donner un deuxime entier : "); j=Int32.Parse(Console.ReadLine()); // Appel de la mthode du service s= op.Somme(i,j); Console.WriteLine("La somme est : "+s); } } }

Le rsultat de l'excution du programme est le suivant :


Donner un premier entier : 5 Donner un deuxime entier : 6 La somme est : 11

Dveloppement d'un client de type application Web (WebForm)


L'exemple suivant montre le dveloppement d'un client de type application Web qui fait appel au service Operations.

Figure 4 : Interface du client Web

Le code de la classe proxy est plac dans un fichier appel Operations.cs. Le contenu de ce fichier est le suivant :
using using using using using using System.Diagnostics; System.Xml.Serialization; System; System.Web.Services.Protocols; System.ComponentModel; System.Web.Services;

[System.Diagnostics.DebuggerStepThroughAttribute()] [System.ComponentModel.DesignerCategoryAttribute("code")] [System.Web.Services.WebServiceBindingAttribute(Name="OperationsSoap", Namespace="www.Test.com")]

174

Karim Kalti

public class Operations : System.Web.Services.Protocols.SoapHttpClientProtocol { public Operations() { this.Url = "http://localhost/operations.asmx"; } [System.Web.Services.Protocols.SoapDocumentMethodAttribute("www.Test.com/Somme", RequestNamespace="www.Test.com", ResponseNamespace="www.Test.com", Use=System.Web.Services.Description.SoapBindingUse.Literal, ParameterStyle=System.Web.Services.Protocols.SoapParameterStyle.Wrapped)] public int Somme(int a, int b) { object[] results = this.Invoke("Somme", new object[] {a,b}); return ((int)(results[0])); } public System.IAsyncResult BeginSomme(int a, int b, System.AsyncCallback callback, object asyncState) { return this.BeginInvoke("Somme", new object[] {a,b}, callback, asyncState); } public int EndSomme(System.IAsyncResult asyncResult) { object[] results = this.EndInvoke(asyncResult); return ((int)(results[0])); } }

Le code de l'interface qui utilise cette classe proxy pour faire appel au service Web se prsente comme suit :
<%@ Page Language="C#" Src="operations.cs" %> <script runat="server"> void Page_Load(object sender, EventArgs e) { if( IsPostBack == false) { TxtBE1.Text="0"; TxtBE2.Text="0"; } } void BtnSomme_Click(object sender, EventArgs e) { int i,j, Somme; if(TxtBE1.Text!="" && TxtBE2.Text!="") { Operations op = new Operations(); i= Int32.Parse(TxtBE1.Text); j= Int32.Parse(TxtBE2.Text); Somme = op.Somme(i,j); LbResultat.Text = "La somme est :" + Somme.ToString(); } } </script> <html> <head> </head> <body> <form runat="server"> <p> <asp:Label id="LbE1" runat="server">Entier 1 : </asp:Label> <asp:TextBox id="TxtBE1" runat="server"></asp:TextBox> <br /> <asp:Label id="LbE2" runat="server">Entier 2 : </asp:Label> <asp:TextBox id="TxtBE2" runat="server"></asp:TextBox> <br /> <asp:Button id="BtnSomme" onclick="BtnSomme_Click" runat="server" Text="Somme"></asp:Button> <br /> <asp:Label id="LbResultat" runat="server">La somme est : </asp:Label> </p> </form> </body> </html>

175

Karim Kalti

Dveloppement d'un client de type application Windows (WinForm)


L'exemple suivant montre le dveloppement d'un client de type application Windows qui fait appel au service Operations.

Figure 5 : Interface du client Windows

Le code de l'application cliente est le suivant :


using using using using using using using using System; System.Drawing; System.Collections; System.ComponentModel; System.Windows.Forms; System.Data; System.Web.Services; System.Web.Services.Protocols;

namespace ClientWinForm { [System.Diagnostics.DebuggerStepThroughAttribute()] [System.ComponentModel.DesignerCategoryAttribute("code")] [System.Web.Services.WebServiceBindingAttribute(Name="OperationsSoap", Namespace="www.Test.com")] // La classe proxy public class Operations : System.Web.Services.Protocols.SoapHttpClientProtocol { public Operations() { this.Url = "http://localhost/operations.asmx"; }

[System.Web.Services.Protocols.SoapDocumentMethodAttribute("www.Test.com/Somme", RequestNamespace="www.Test.com", ResponseNamespace="www.Test.com", Use=System.Web.Services.Description.SoapBindingUse.Literal, ParameterStyle=System.Web.Services.Protocols.SoapParameterStyle.Wrapped)] public int Somme(int a, int b) { object[] results = this.Invoke("Somme", new object[] {a,b}); return ((int)(results[0])); } public System.IAsyncResult BeginSomme(int a, int b, System.AsyncCallback callback, object asyncState) { return this.BeginInvoke("Somme", new object[] {a,b}, callback, asyncState); } public int EndSomme(System.IAsyncResult asyncResult) { object[] results = this.EndInvoke(asyncResult); return ((int)(results[0])); } }

176

Karim Kalti

public class ClientWinForm : System.Windows.Forms.Form { private System.Windows.Forms.Label label1; private System.Windows.Forms.TextBox TxtBEntier1; private System.Windows.Forms.TextBox TxtBEntier2; private System.Windows.Forms.Label LbEntier2; private System.Windows.Forms.Button BtnSomme; private System.Windows.Forms.Label LbResultat; private System.ComponentModel.Container components = null; public ClientWinForm() { InitializeComponent(); } protected override void Dispose( bool disposing ) { if( disposing ) { if (components != null) { components.Dispose(); } } base.Dispose( disposing ); } private void InitializeComponent() { this.label1 = new System.Windows.Forms.Label(); this.TxtBEntier1 = new System.Windows.Forms.TextBox(); this.TxtBEntier2 = new System.Windows.Forms.TextBox(); this.LbEntier2 = new System.Windows.Forms.Label(); this.BtnSomme = new System.Windows.Forms.Button(); this.LbResultat = new System.Windows.Forms.Label(); this.SuspendLayout(); // label1 this.label1.Location = new System.Drawing.Point(16, 16); this.label1.Name = "label1"; this.label1.Size = new System.Drawing.Size(64, 16); this.label1.TabIndex = 0; this.label1.Text = "Entier 1 :"; // TxtBEntier1 this.TxtBEntier1.Location = new System.Drawing.Point(72, 16); this.TxtBEntier1.Name = "TxtBEntier1"; this.TxtBEntier1.TabIndex = 1; this.TxtBEntier1.Text = ""; // TxtBEntier2 this.TxtBEntier2.Location = new System.Drawing.Point(72, 40); this.TxtBEntier2.Name = "TxtBEntier2"; this.TxtBEntier2.TabIndex = 3; this.TxtBEntier2.Text = ""; // LbEntier2 this.LbEntier2.Location = new System.Drawing.Point(16, 40); this.LbEntier2.Name = "LbEntier2"; this.LbEntier2.Size = new System.Drawing.Size(64, 16); this.LbEntier2.TabIndex = 2; this.LbEntier2.Text = "Entier 2 :"; // BtnSomme this.BtnSomme.Location = new System.Drawing.Point(16, 64); this.BtnSomme.Name = "BtnSomme"; this.BtnSomme.TabIndex = 4; this.BtnSomme.Text = "Somme"; this.BtnSomme.Click += new System.EventHandler(this.BtnSomme_Click); // LbResultat this.LbResultat.Location = new System.Drawing.Point(16, 88); this.LbResultat.Name = "LbResultat"; this.LbResultat.TabIndex = 5; // ClientWinForm this.AutoScaleBaseSize = new System.Drawing.Size(5, 13); this.ClientSize = new System.Drawing.Size(224, 133); this.Controls.Add(this.LbResultat); this.Controls.Add(this.BtnSomme); this.Controls.Add(this.TxtBEntier2); this.Controls.Add(this.LbEntier2);

177

Karim Kalti

this.Controls.Add(this.TxtBEntier1); this.Controls.Add(this.label1); this.Name = "ClientWinForm"; this.Text = "ClientWinForm"; this.ResumeLayout(false); } [STAThread] static void Main() { Application.Run(new ClientWinForm()); } private void BtnSomme_Click(object sender, System.EventArgs e) { int i,j,s; // Instanciation de la classe du service Operations op = new Operations(); if(this.TxtBEntier1.Text!="" && this.TxtBEntier2.Text!="") { i=Int32.Parse(this.TxtBEntier1.Text); j=Int32.Parse(this.TxtBEntier2.Text); // Appel de la mthode du service s=op.Somme(i,j); this.LbResultat.Text="Le rsultat est : "+s.ToString(); } } } }

La gestion des exceptions


Lorsqu'une exception est leve dans un service Web, SOAP la remonte travers un message vers l'application cliente. Cette exception est de type System.Web.Services.Protocols.SoapException. L'exemple suivant montre la leve et l'interception d'une exception gnre par une division par zro. Exemple : Gestion d'une exception leve par une division par zro Une mthode de division est d'abord ajoute au service Web Operations.

<%@ WebService Language="C#" Class="MathOps.Operations"%> using System.Web.Services; namespace MathOps { [WebService(Namespace = "www.Test.com", Description = "Premier service Web")] public class Operations { [WebMethod(Description = "Cette mthode effectue la somme de deux entiers")] public int Somme(int a, int b) { return a + b; } [WebMethod(Description = "Cette mthode effectue la division du premier paramtre par le second")] public int Division(int a, int b) { return a / b; } } }

178

Karim Kalti

La nouvelle classe proxy gnre par WSDL pour ce service se prsente comme suit :
// la classe proxy [System.Diagnostics.DebuggerStepThroughAttribute()] [System.ComponentModel.DesignerCategoryAttribute("code")] [System.Web.Services.WebServiceBindingAttribute(Name="OperationsSoap", Namespace="www.Test.com")] public class Operations : System.Web.Services.Protocols.SoapHttpClientProtocol { public Operations() { this.Url = "http://localhost/operations.asmx";} [System.Web.Services.Protocols.SoapDocumentMethodAttribute("www.Test.com/Somme", RequestNamespace="www.Test.com", ResponseNamespace="www.Test.com", Use=System.Web.Services.Description.SoapBindingUse.Literal, ParameterStyle=System.Web.Services.Protocols.SoapParameterStyle.Wrapped)] public int Somme(int a, int b) { object[] results = this.Invoke("Somme", new object[] { a, b}); return ((int)(results[0])); } public System.IAsyncResult BeginSomme(int a, int b, System.AsyncCallback callback, object asyncState) { return this.BeginInvoke("Somme", new object[] {a, b}, callback, asyncState); } public int EndSomme(System.IAsyncResult asyncResult) { object[] results = this.EndInvoke(asyncResult); return ((int)(results[0])); } [System.Web.Services.Protocols.SoapDocumentMethodAttribute("www.Test.com/Division", RequestNamespace="www.Test.com", ResponseNamespace="www.Test.com", Use=System.Web.Services.Description.SoapBindingUse.Literal, ParameterStyle=System.Web.Services.Protocols.SoapParameterStyle.Wrapped)] public int Division(int a, int b) { object[] results = this.Invoke("Division", new object[] {a, b}); return ((int)(results[0])); } public System.IAsyncResult BeginDivision(int a, int b, System.AsyncCallback callback, object asyncState) { return this.BeginInvoke("Division", new object[] { a, b}, callback, syncState); } public int EndDivision(System.IAsyncResult asyncResult) { object[] results = this.EndInvoke(asyncResult); return ((int)(results[0])); } }

Le test du service est effectu travers un client de type application Windows dont l'interface se prsente comme suit :

Figure 6 : Interface de test d'une gestion d'exception

179

Karim Kalti

Le code du gestionnaire de l'vnement clic du bouton Division est le suivant :


private void BtnDivision_Click(object sender, System.EventArgs e) { try { int i,j,s; // Instanciation de la classe du service Operations op = new Operations(); i=Int32.Parse(this.TxtBEntier1.Text); j=Int32.Parse(this.TxtBEntier2.Text); // Appel de la mthode du service s=op.Division(i,j); this.LbResultat.Text="Le rsultat de la division est : "+s.ToString(); } catch(SoapException) { MessageBox.Show("Une erreur s'est produite au niveau du serveur","Erreur"); } }

Une division par zro engendre l'affichage d'une bote de message indiquant l'occurrence d'une erreur.

Figure 7 : Division par zro

Figure 8 : Message d'erreur affich

Traitement de l'exception au niveau du serveur Il est galement possible de traiter l'erreur au niveau du serveur dans le service Web afin de modifier le message de l'exception. Le code suivant montre une nouvelle version de la mthode Division du service Web Operations qui traite l'exception leve par la division par zro.

[WebMethod(Description = "Cette mthode effectue la division du premier paramtre par le second")] public int Division(int a, int b) { try { return a / b; } catch (System.DivideByZeroException e) { throw new System.DivideByZeroException("Attention : La division par zro est interdite"); } }

La mthode Division du service Web lve une exception de type System.DivideByZeroException. Cette exception sera remonte par SOAP jusqu'au client mais toujours sous forme d'une exception de type SoapException.

180

Karim Kalti

Le code suivant montre une nouvelle version de la fonction de traitement de l'vnement clic du bouton Division qui traite l'exception et affiche le message d'erreur provenant du serveur.
private void BtnDivision_Click(object sender, System.EventArgs e) { try { int i,j,s; // Instanciation de la classe du service Operations op = new Operations(); i=Int32.Parse(this.TxtBEntier1.Text); j=Int32.Parse(this.TxtBEntier2.Text); // Appel de la mthode du service s=op.Division(i,j); this.LbResultat.Text="Le rsultat de la division est : "+s.ToString(); } catch(SoapException ex) { MessageBox.Show(ex.Message,"Erreur"); } }

Ceci est le message d'erreur affiche dans le cas d'une division par zro.

Figure 9 : Nouveau message d'erreur affich

Communication asynchrone avec les services Web


Dans un contexte Client/Serveur l'appel d'une mthode de service Web peut avoir une dure importante. Ceci peut tre d des raisons diverses : o la nature mme des traitements qu'effectue la mthode ncessite un temps d'excution important comme par exemple les mthodes qui font des accs des bases de donnes de trs grande taille. o Le serveur sur lequel est hberg le service peut tre encombr s'il est sollicit par un trs grand nombre de clients et surtout lorsqu'il hberge plusieurs applications diffrentes. o Le rseau peut tre encombr s'il gre un trafic trs important. Pour viter les blocages dans les applications clientes lors de l'utilisation des services Web, il est plus intressant d'effectuer des appels asynchrones aux mthodes de ces services. Un appel asynchrone est un appel qui lance l'excution d'une mthode sans attendre un renvoi immdiat d'une valeur de retour. L'appel asynchrone se droule en deux tapes : o Le client initialise l'appel de la mthode. Cette action tant rapide et non bloquante, l'application cliente peut alors effectuer d'autres actions pendant que le droulement de l'excution de la mthode. o La deuxime tape se produit au gr de l'application cliente qui dcide d'aller chercher le rsultat si celui-ci est disponible. La classe proxy gnre par WSDL propose pour chaque mthode du service Web deux mthodes supplmentaires permettant d'effectuer l'appel asynchrone : BeginNomMthode et EndNomMthode. o BeginNomMthode permet d'initialiser l'appel asynchrone d'une mthode. o EndNomMthode permet de rcuprer le rsultat de l'appel.

181

Karim Kalti

L'exemple suivant montre un appel asynchrone la mthode Somme dans le gestionnaire de l'vnement clic sur le bouton Ajouter dans le client de type application Windows.
// Ajout d'attributs la classe int s; Operations op; // Gestionnaire de l'vnement clic sur le bouton Somme private void BtnSomme_Click(object sender, System.EventArgs e) { int i,j,s; // Instanciation de la classe du service op = new Operations(); if(this.TxtBEntier1.Text!="" && this.TxtBEntier2.Text!="") { i=Int32.Parse(this.TxtBEntier1.Text); j=Int32.Parse(this.TxtBEntier2.Text); // Appel de la mthode du service op.BeginSomme(i,j, new AsyncCallback(FinSomme), null); this.LbResultat.Text="Le rsultat est : "+s.ToString(); } } // Fonction appele lorsque le service Web retourne sa valeur public void FinSomme(IAsyncResult ar) { if(ar.IsCompleted) s = (int)op.EndSomme(ar); op = null; }

La mthode BeginNomMthode (BeginSomme dans l'exemple courant) prend comme premiers arguments la liste des arguments de la mthode du service Web. L'avant dernier argument et un dlgu de type AsyncCallback qui est appel lorsque l'appel asynchrone est termin. Si cet argument prend comme valeur null alors aucun dlgu n'est appel. Le dernier argument de type object reprsente des informations supplmentaires fournies par l'appelant. La mthode BeginNomMthode renvoie une valeur de type IAsyncResult. Cette classe permet de donner l'tat de l'opration asynchrone notamment travers sa proprit IsCompleted.

182

Karim Kalti

You might also like