Introduction rapide à ASP.NET avec Visual Studio 2010

Page 1 sur 46Lecteur de document UniversityLib

Introduction rapide à ASP.NET avec Visual Studio 2010

Web Development · notes

Voir tous les documents en développement web

Introduction rapide à ASP.NET avec Visual Studio 2010

serge.tahe at istia.univ-angers.fr, novembre 2011

http://tahe.developpez.com

1/46

1

Introduction

Nous nous proposons ici d'introduire, à l'aide de quelques exemples, les concepts importants d'ASP.NET. Cette introduction ne permet pas de comprendre les subtilités des échanges client / serveur d'une application web. Pour cela, on pourra lire d'anciens documents qui décrivent les échanges Http entre un navigateur et un serveur web :

•

Programmation ASP.NET [http://tahe.developpez.com/dotnet/aspnet/vol1] et [http://tahe.developpez.com/dotnet/aspnet/vol2]

Cette introduction est faite pour ceux qui voudraient aller vite en acceptant, dans un premier temps, de laisser dans l'ombre des points qui peuvent être importants. Ce document peut être ultérieurement approfondi par une étude de cas :

•

Construction d'une application à trois couches avec ASP.NET, C#, Spring.net et Nhibernate [http://tahe.developpez.com/dotnet/pam-aspnet/]

Les exemples ont été construits avec Visual Studio 2010 Professionnel. Des versions Express de Visual Studio 2010 sont disponibles à l'Url [http://msdn.microsoft.com/fr-fr/express/aa975050] (novembre 2011) et peuvent être téléchargées librement. On téléchargera ainsi Visual Web Developer Express 2010. Les copies d'écran de ce document sont celles de Visual Studio 2010 Professionnel . Elles pourront parfois différer des écrans de Visual Studio 2010 Express mais le lecteur devrait s'y retrouver néanmoins aisément.

2 Un projet exemple

2.1 Création du projet

1

2

3

• • •

en [1], on crée un nouveau projet avec Visual Studio en [2], on choisit un projet web en Visual C# en [3], on indique qu'on veut créer une application web ASP.NET vide

4

5

• •

en [4], on donne un nom à l'application. Un dossier sera créé pour le projet avec ce nom. en [5], on indique le dossier parent du dossier [4] du projet

http://tahe.developpez.com

2/46

6

7

8

• • •

en [6], le projet créé [Web.config] est le fichier de configuration du projet ASP.NET. [References] est la liste des Dll utilisées par le projet web. Ces Dll sont des bibliothèques de classes que le projet est amené à utiliser. En [7] la liste des Dll mises par défaut dans les références du projet. La plupart sont inutiles. Si le projet doit utiliser une Dll non listée en [7], celle-ci peut être ajoutée par [8].

2.2 La page [Default.aspx]

Créons notre première page web :

1

2

4

3

• •

• •

•

en [1], nous ajoutons un formulaire web [2] en [3], nous le nommons [Default.aspx]. Cette page est particulière. C'est elle qui est servie lorsqu'un utilisateur fait une requête à l'application sans préciser de page. Elle contient des balises HTML et des balises ASP.NET en [4], les nouveaux fichiers du projet [Default.aspx.cs] contient le code de gestion des événements provoqués par l'utilisateur sur la page [Default.aspx] affichée dans son navigateur [Default.aspx.designer.cs] contient la liste des composants ASP.NET de la page [Default.aspx]. Chaque composant ASP.NET déposé sur la page [Default.aspx] donne naissance à la déclaration de ce composant dans [Default.aspx.designer.cs].

Si on exécute le projet par [Ctrl-F5], la page [Default.aspx] est affichée dans un navigateur :

http://tahe.developpez.com

3/46

1

3

2

4

•

• •

•

en [1], l'Url du projet web. Visual Studio a un serveur web intégré qui est lancé lorsqu'on demande l'exécution d'un projet web. Il écoute sur un port aléatoire, ici 57365. Le port d'écoute est habituellement le port 80. En [1], aucune page n'est demandée. Dans ce cas, c'est la page [Default.aspx] qui est affichée, d'où son nom de page par défaut. en [2], la page [Default.aspx] est vide. dans Visual Studio, la page [Default.aspx] [3] peut être construite visuellement (onglet [Design]) ou à l'aide de balises (onglet [Source]) en [4], la page [Default.aspx] en mode [Design]. On la construit en y déposant des composants que l'on trouve dans la boîte à outils [5]. Si cette boîte n'est pas visible, on l'obtient par le menu [Affichage / Boîte à outils].

5

6

Le mode [Source] [6] donne accès au code source de la page :

1. <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs"

Inherits="Intro._Default" %>

2. 3. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

4. <html xmlns="http://www.w3.org/1999/xhtml"> 5. <head runat="server"> 6. <title></title> 7. </head> 8. <body> 9. <form id="form1" runat="server"> 10. <div> 11. </div> 12. </form> 13. </body> 14. </html>

•

la ligne 1 est une directive ASP.NET qui liste certaines propriétés de la page

•

• • • •

la directive Page s'applique à une page web. Il y a d'autres directives telles que Application, WebService, ... qui s'applique à d'autres objets ASP.NET l'attribut CodeBehind indique le fichier qui gère les événements de la page l'attribut Language indique le langage .NET utilisé par le fichier CodeBehind l'attribut Inherits indique le nom de la classe définie à l'intérieur du fichier CodeBehind l'attribut AutoEventWireUp="true" indique que la liaison entre un événement dans [Default.aspx] et son gestionnaire dans [Defaul.aspx.cs] se fait par le nom de l'événement. Ainsi l'événement Load sur la page [Default.aspx] sera traité par la méthode Page_Load de la classe Intro._Default définie par l'attribut Inherits.

•

les lignes 4-14 décrivent la page [Default.aspx] à l'aide de balises : • Html classiques telles que la balise <body> ou <div>

http://tahe.developpez.com

4/46

•

ASP.NET. Ce sont les balises qui ont l'attribut runat="server". Les balises ASP.NET sont traitées par le serveur web avant envoi de la page au client. Elles sont transformées en balises Html. Le navigateur client reçoit donc une page Html standard dans laquelle il n'existe plus de balises ASP.NET.

La page [Default.aspx] peut être modifiée directement à partir de son code source. C'est parfois plus simple que de passer par le mode [Design]. Nous modifions le code source de la façon suivante :

1. <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs"

Inherits="Intro._Default" %>

2. 3. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

4. <html xmlns="http://www.w3.org/1999/xhtml"> 5. <head runat="server"> 6. <title>Introduction ASP.NET</title> 7. </head> 8. <body> 9. <h3>Introduction à ASP.NET</h3> 10. <form id="form1" runat="server"> 11. <div> 12. </div> 13. </form> 14. </body> 15. </html>

En ligne 6, nous donnons un titre à la page grâce à la balise Html <title>. En ligne 9, nous introduisons un texte dans le corps (<body>) de la page. Si nous exécutons le projet (Ctrl-F5), nous obtenons le résultat suivant dans le navigateur :

2.3 Les fichiers [Default.aspx.designer.cs] et [Default.aspx.cs]

Le fichier [Default.aspx.designer.cs] déclare les composants de la page [Default.aspx] :

//------------------------------------------------------------------------------ // <auto-generated> // Ce code a été généré par un outil. // Version du runtime :2.0.50727.3603 // // Les modifications apportées à ce fichier peuvent provoquer un comportement incorrect et seront perdues si // le code est régénéré. // </auto-generated> //------------------------------------------------------------------------------

1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. namespace Intro { 12. 13. 14. public partial class _Default { 15. 16. /// <summary> 17. /// Contrôle form1. 18. /// </summary> 19. /// <remarks> 20. /// Champ généré automatiquement. 21. /// Pour modifier, déplacez la déclaration de champ du fichier de concepteur dans le fichier code-

behind.

22. /// </remarks> 23. protected global::System.Web.UI.HtmlControls.HtmlForm form1; 24. } 25. }

On trouve dans ce fichier la liste des composants ASP.NET de la page [Default.aspx] ayant un identifiant. Ils correspondent aux balises de [Default.aspx] ayant l'attribut runat="server" et l'attribut id. Ainsi le composant de la ligne 23 ci-dessus correspond à la balise

http://tahe.developpez.com

5/46

Publicité

<form id="form1" runat="server">

de [Default.aspx].

Le développeur interagit peu avec le fichier [Default.aspx.designer.cs]. Néanmoins ce fichier est utile pour connaître la classe d'un composant particulier. Ainsi on voit ci-dessous que le composant form1 est de type HtmlForm. Le développeur peut alors explorer cette classe pour en connaître les propriétés et méthodes. Les composants de la page [Default.aspx] sont utilisés par la classe du fichier [Default.aspx.cs] :

1. using System; 2. using System.Collections.Generic; 3. using System.Linq; 4. using System.Web; 5. using System.Web.UI; 6. using System.Web.UI.WebControls; 7. 8. namespace Intro 9. { 10. public partial class _Default : System.Web.UI.Page 11. { 12. protected void Page_Load(object sender, EventArgs e) 13. { 14. 15. } 16. } 17. }

On notera que la classe définie dans les fichiers [Default.aspx.cs] et [Default.aspx.designer.cs] est la même (ligne 10) : Intro._Default. C'est le mot clé partial qui rend possible d'étendre la déclaration d'une classe sur plusieurs fichiers, ici deux.

Ligne 10, ci-dessus, on voit que la classe [_Default] étend la classe [Page] et hérite de ses événements. L'un d'entre-eux est l'événement Load qui se produit lorsque la page est chargée par le serveur web. Ligne 12, la méthode Page_Load qui gère l'événement Load de la page. C'est généralement ici qu'on initialise la page avant son affichage dans le navigateur du client. Ici, la méthode Page_Load ne fait rien.

La classe associée à une page web, ici la classe Intro._Default, est créée au début de la requête du client et détruite lorsque la réponse au client a été envoyée. Elle ne peut donc servir à mémoriser des informations entre deux requêtes. Pour cela il faut utiliser la notion de session utilisateur.

2.4 Les événements d'une page web ASP.NET

Nous construisons la page [Default.aspx] suivante :

1. <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs"

Inherits="Intro._Default" %>

2. 3. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

4. <html xmlns="http://www.w3.org/1999/xhtml"> 5. <head runat="server"> 6. <title>Introduction ASP.NET</title> 7. </head> 8. <body> 9. <h3>Introduction à ASP.NET</h3> 10. <form id="form1" runat="server"> 11. <div> 12. <table> 13. <tr> 14. <td> 15. Nom</td> 16. <td> 17. <asp:TextBox ID="TextBoxNom" runat="server"></asp:TextBox> 18. </td> 19. <td> 20. &nbsp;</td> 21. </tr> 22. <tr> 23. <td> 24. Age</td> 25. <td>

http://tahe.developpez.com

6/46

26. <asp:TextBox ID="TextBoxAge" runat="server"></asp:TextBox> 27. </td> 28. <td> 29. &nbsp;</td> 30. </tr> 31. </table> 32. </div> 33. <asp:Button ID="ButtonValider" runat="server" Text="Valider" /> 34. <hr /> 35. <p> 36. Evénements traités par le serveur</p> 37. <p> 38. <asp:ListBox ID="ListBoxEvts" runat="server"></asp:ListBox> 39. </p> 40. </form> 41. </body> 42. </html>

Cette page peut être obtenue en modifiant directement le code source de la page ou en dessinant la page en mode [Design]. On trouvera les composants nécessaires dans la boîte à outils sous le thème Standard.

Le fichier [Default.aspx.designer.cs] est le suivant :

1. namespace Intro { 2. public partial class _Default { 3. protected global::System.Web.UI.HtmlControls.HtmlForm form1; 4. protected global::System.Web.UI.WebControls.TextBox TextBoxNom; 5. protected global::System.Web.UI.WebControls.TextBox TextBoxAge; 6. protected global::System.Web.UI.WebControls.Button ButtonValider; 7. protected global::System.Web.UI.WebControls.ListBox ListBoxEvts; 8. } 9. }

On y retrouve tous les composants ASP.NET de la page [Default.aspx] ayant un identifiant.

Nous faisons évoluer le fichier [Default.aspx.cs] comme suit :

1. using System; 2. 3. namespace Intro 4. { 5. public partial class _Default : System.Web.UI.Page 6. { 7. protected void Page_Init(object sender, EventArgs e) 8. { 9. // on note l'événement 10. ListBoxEvts.Items.Insert(0, string.Format("{0}: Page_Init",

DateTime.Now.ToString("hh:mm:ss")));

11. } 12. 13. protected void Page_Load(object sender, EventArgs e) 14. {

http://tahe.developpez.com

7/46

15. // on note l'événement 16. ListBoxEvts.Items.Insert(0, string.Format("{0}: Page_Load",

DateTime.Now.ToString("hh:mm:ss")));

17. } 18. 19. protected void ButtonValider_Click(object sender, EventArgs e) 20. { 21. // on note l'événement 22. ListBoxEvts.Items.Insert(0, string.Format("{0}: ButtonValider_Click",

DateTime.Now.ToString("hh:mm:ss")));

23. } 24. } 25. }

La classe [_Default] (ligne 5) traite trois événements :

• •

•

l'événement Init (ligne 7) qui se produit lorsque la page a été initialisée l'événement Load (ligne 13) qui se produit lorsque la page a été chargée par le serveur web. L'événement Init se produit avant l'événement Load. l'événement Click sur le bouton ButtonValider (ligne 19) qui se produit lorsque l'utilisateur clique sur le bouton [Valider]

La gestion de chacun de ces trois événements consiste à ajouter un message au composant Listbox nommé ListBoxEvts. Ce message affiche l'heure de l'événement et le nom de celui-ci. Chaque message est placé en début de liste. Aussi les messages placés en haut de la liste sont les plus récents.

Lorsqu'on exécute le projet, on obtient la page suivante :

2

3

1

On voit en [1] que les événements Page_Init et Page_Load se sont produits dans cet ordre. On rappelle que l'événement le plus récent est en haut de la liste. Lorsque le navigateur demande la page [Default.aspx] directement par son Url [2], il le fait par une commande HTTP (HyperText Transfer Protocol) appelée GET. Une fois la page chargée dans le navigateur, l'utilisateur va provoquer des événements sur la page. Par exemple il va cliquer sur le bouton [Valider] [3]. Les événements provoqués par l'utilisateur une fois la page chargée dans le navigateur, déclenchent une requête à la page [Default.aspx] mais cette fois-ci avec une commande HTTP appelée POST. Pour résumer :

• •

le chargement initial d'une page P dans un navigateur est faite par une opération HTTP GET les événements qui se produisent ensuite sur la page produisent à chaque fois une nouvelle requête vers la même page P mais cette fois avec une commande HTTP POST. Il est possible pour une page P de savoir si elle a été demandée avec une commande GET ou une commande POST, ce qui lui permet de se comporter différemment si c'est nécessaire, ce qui est la plupart du temps le cas.

Demande initiale d'une page ASPX : GET

http://tahe.developpez.com

8/46

Navigateur

Serveur web

Html

1

2

Page ASPX

• •

en [1], le navigateur demande la page ASPX via une commande HTTP GET sans paramètres. en [2], le serveur web lui envoie en réponse le flux HTML traduction de la page ASPX demandée.

Traitement d'un événement produit sur la page affichée par le navigateur : POST

Navigateur

Serveur web

Html

1

2

Page ASPX

•

•

en [1], lors d'un événement sur la page Html, le navigateur demande la page ASPX déjà acquise avec une opération GET, cette fois avec une commande HTTP POST accompagnée de paramètres. Ces paramètres sont les valeurs des composants qui se trouvent à l'intérieur de la balise <form> de la page HTML affichée par le navigateur. On appelle ces valeurs, les valeurs postées par le client. Elles vont être exploitées par la page ASPX pour traiter la demande du client. en [2], le serveur web lui envoie en réponse le flux HTML traduction de la page ASPX demandée initialement par le POST ou bien d'une autre page s'il y a eu transfert de page ou redirection de page.

Revenons à notre page exemple :

2

3

1

4

• •

en [2], la page a été obtenue par un GET. en [1], on voit les deux événements qui se sont produits lors de ce GET

Si, ci-dessus, l'utilisateur clique sur le bouton [Valider] [3], la page [Default.aspx] va être demandée avec un POST. Ce POST sera accompagné de paramètres qui seront les valeurs de tous les composants inclus dans la balise <form> de la page [Default.aspx] : les deux TextBox [TextBoxNom, TextBoxAge], le bouton [ButtonValider], la liste [ListBoxEvts]. Les valeurs postées pour les composants sont les suivantes :

http://tahe.developpez.com

9/46

• • •

TextBox : la valeur saisie Button : le texte du bouton, ici le texte "Valider" Listbox : le texte du message sélectionné dans le ListBox

En réponse du POST, on obtient la page [4]. C'est de nouveau la page [Default.aspx]. C'est le comportement normal, à moins qu'il y ait transfert ou redirection de page par les gestionnaires d'événements de la page. On peut voir que deux nouveaux événements se sont produits :

• •

l'événement Page_Load qui s'est produit lors du chargement de la page l'événement ButtonValider_Click qui s'est produit à cause du clic sur le bouton [Valider]

On peut remarquer que :

•

•

•

•

•

Publicité

l'événement Page_Init ne s'est pas produit sur l'opération HTTP POST alors qu'il s'était produit sur l'événement HTTP GET l'événement Page_Load se produit tout le temps, que ce soit sur un GET ou un POST. C'est dans cette méthode qu'on a en général besoin de savoir si on a affaire à un GET ou à un POST. à l'issue du POST, la page [Default.aspx] a été renvoyée au client avec les modifications apportées par les gestionnaires d'événements. C'est toujours ainsi. Une fois les événements d'une page P traités, cette même page P est renvoyée au client. Il y a deux façons d'échapper à cette règle. Le dernier gestionnaire d'événement exécuté peut

• •

transférer le flux d'exécution à une autre page P2. rediriger le navigateur client vers une autre page P2.

Dans les deux cas, c'est la page P2 qui est renvoyée au navigateur. Les deux méthodes présentent des différences sur lesquelles nous reviendrons. l'événement ButtonValider_Click s'est produit après l'événement Page_Load. C'est donc ce gestionnaire qui peut prendre la décision du transfert ou de la redirection vers une page P2. la liste des événements [4] a gardé les deux événements affichés lors du chargement initial GET de la page [Default.aspx]. C'est surprenant lorsqu'on sait que la page [Default.aspx] a été recréée lors du POST. On devrait retrouver la page [Default.aspx] avec ses valeurs de conception avec donc un ListBox vide. L'exécution des gestionnaires Page_Load et ButtonValider_Click devrait y mettre ensuite deux messages. Or on en trouve quatre. C'est le mécanisme du VIEWSTATE qui explique cela. Lors du GET initial, le serveur web envoie la page [Default.aspx] avec une balise HTML <input type="hidden" ...> appelé champ caché (ligne 10 ci-dessous).

1. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

2. <html xmlns="http://www.w3.org/1999/xhtml"> 3. <head><title> 4. Introduction ASP.NET 5. </title></head> 6. <body> 7. <h3>Introduction à ASP.NET</h3> 8. <form name="form1" method="post" action="default.aspx" id="form1"> 9. <div> 10. <input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE"

value="/wEPDwUKLTMzMTEyNDMxMg9kFgICAw9kFgICBw8QZBAVAhMwNjoxNjozNjogUGFnZV9Mb2FkEzA2OjE2OjM2OiBQYWd lX0luaXQVAhMwNjoxNjozNjogUGFnZV9Mb2FkEzA2OjE2OjM2OiBQYWdlX0luaXQUKwMCZ2dkZGRW1AnTL8f/q7h2MXBLxctKD 1UKfg==" />

11. </div> 12. ..............................

Dans le champ d'id "__VIEWSTATE" le serveur web met sous forme codée la valeur de tous les composants de la page. Il le fait aussi bien sur le GET initial que sur les POST qui suivent. Lorsqu'un POST sur une page P se produit :

•

• •

•

• • •

le navigateur demande la page P en envoyant dans sa requête les valeurs de tous les composants qui sont à l'intérieur de la balise <form>. Ci-dessus, on peut voir que le composant "__VIEWSTATE" est à l'intérieur de la balise <form>. Sa valeur est donc envoyée au serveur lors d'un POST. la page P est instanciée et initialisée avec ses valeurs de construction le composant "__VIEWSTATE" est ensuite utilisé pour redonner aux composants les valeurs qu'ils avaient lorsque la page P avait été envoyée précédemment. C'est ainsi par exemple, que la liste des événements [4] retrouve les deux premiers messages qu'elle avait lorsqu'elle a été envoyée en réponse au GET initial du navigateur. les composants de la page P prennent ensuite pour valeurs, les valeurs postées par le navigateur. A ce moment là, le formulaire de la page P est dans l'état où l'utilisateur l'a posté. l'événement Page_Load est traité. Ici il rajoute un message à la liste des événements[4]. l'événement qui a provoqué le POST est traité. Ici ButtonValider_Click rajoute un message à la liste des événements[4]. la page P est renvoyée. Les composants ont pour valeur :

http://tahe.developpez.com

10/46

• •

soit la valeur postée, c.a.d. la valeur que le composant avait dans le formulaire lorsque celui a été posté au serveur soit une valeur donnée par l'un des gestionnaires d'événements.

Dans notre exemple,

• •

les deux composants TextBox retrouveront leur valeur postée car les gestionnaires d'événements n'y touchent pas la liste des événements [4] retrouve sa valeur postée, c.a.d. tous les événements déjà inscrits dans la liste, plus deux nouveaux événements créés par les méthodes Page_Load et ButtonValider_Click.

Le mécanisme du VIEWSTATE peut être activé ou inhibé au niveau de chaque composant. Inhibons-le pour le composant [ListBoxEvts] (clic droit sur ListBoxEvts / Propriétés) :

1

2

3

• •

en [1], le VIEWSTATE du composant [ListBoxEvts] est inhibé. Celui des TextBox [2] est activé par défaut. en [3], les deux événements renvoyés après le GET initial

4

5

6

7

8

• •

en [4], on a rempli le formulaire et on clique sur le bouton [Valider]. Un POST vers la page [Default.aspx] va être fait. en [6], le résultat renvoyé après un Clic sur le bouton [Valider]

• •

le mécanisme du VIEWSTATE activé explique que les TextBox [7] aient gardé leur valeur postée en [4] le mécanisme du VIEWSTATE inhibé explique que le composant [ListBoxEvts] [8] n'ait pas gardé son contenu [5].

http://tahe.developpez.com

11/46

2.5 Gestion des valeurs postées

Nous allons nous intéresser ici aux valeurs postées par les deux TextBox lorsque l'utilisateur clique sur le bouton [Valider]. La page [Default.aspx] en mode [Design] évolue comme suit :

2

1

Le code source de l'élément rajouté en [1] est le suivant :

1. <p> 2. Eléments postés au serveur : 3. <asp:Label ID="LabelPost" runat="server"></asp:Label> 4. </p>

Nous utiliserons le composant [LabelPost] pour afficher les valeurs saisies dans les deux TextBox [2]. Le code du gestionnaire d'événements [Default.aspx.cs] évolue comme suit :

1. using System; 2. 3. namespace Intro 4. { 5. public partial class _Default : System.Web.UI.Page 6. { 7. protected void Page_Init(object sender, EventArgs e) 8. { 9. // on note l'événement 10. ListBoxEvts.Items.Insert(0, string.Format("{0}: Page_Init",

DateTime.Now.ToString("hh:mm:ss")));

11. } 12. 13. protected void Page_Load(object sender, EventArgs e) 14. { 15. // on note l'événement 16. ListBoxEvts.Items.Insert(0, string.Format("{0}: Page_Load",

DateTime.Now.ToString("hh:mm:ss")));

17. } 18. 19. protected void ButtonValider_Click(object sender, EventArgs e) 20. { 21. // on note l'événement 22. ListBoxEvts.Items.Insert(0, string.Format("{0}: ButtonValider_Click",

DateTime.Now.ToString("hh:mm:ss")));

23. // on affiche le nom et l'âge 24. LabelPost.Text = string.Format("nom={0}, age={1}", TextBoxNom.Text.Trim(),

TextBoxAge.Text.Trim());

25. } 26. } 27. }

Ligne 24, on met à jour le composant LabelPost :

http://tahe.developpez.com

12/46

•

•

•

LabelPost est de type [System.Web.UI.WebControls.Label] (cf Default.aspx.designer.cs). Sa propriété Text représente le texte affiché par le composant. TextBoxNom et TextBoxAge sont de type [System.Web.UI.WebControls.TextBox]. La propriété Text d'un composant TextBox est le texte affiché dans la zone de saisie. la méthode Trim() élimine les espaces qui peuvent précéder ou suivre une chaîne de caractères

Comme il a été expliqué précédemment, lorsque la méthode ButtonValider_Click est exécutée, les composants de la page ont la valeur qu'ils avaient lorsque la page a été postée par l'utilisateur. Les propriétés Text des deux TextBox ont donc pour valeur les textes saisis par l'utilisateur dans le navigateur.

Voici un exemple :

1

2

3

4

5

• • • •

•

en [1], les valeurs postées en [2], la réponse du serveur. en [3], les TextBox ont retrouvé leur valeur postée par le mécanisme du VIEWSTATE activé en [4], les messages du composant ListBoxEvts sont issus des méthodes Page_Init, Page_Load, ButtonValider_Click et d'un VIEWSTATE inhibé en [5], le composant LabelPost a obtenu sa valeur par la méthode ButtonValider_Click. On a bien récupéré les deux valeurs saisies par l'utilisateur dans les deux TextBox [1].

On voit ci-dessus que la valeur postée pour l'âge est la chaîne "yy", une valeur illégale. Nous allons rajouter à la page des composants appelés validateurs. Ils servent à vérifier la validité de données postées. Cette validité peut être vérifiée à deux endroits :

•

•

sur le client. Une option de configuration du validateur permet de demander ou non que les tests soient faits sur le navigateur. Ils sont alors faits par du code JavaScript embarqué dans la page Html. Lorsque l'utilisateur fait un POST des valeurs saisies dans le formulaire, celles-ci sont tout d'abord vérifiées par le code Javascript. Si l'un des tests échoue, le POST n'est pas effectué. On évite ainsi un aller-retour avec le serveur rendant ainsi la page plus réactive. sur le serveur. Si les tests côté client peuvent être facultatifs, côté serveur ils sont obligatoires qu'il y ait eu vérification ou non côté client. En effet, lorsqu'une page reçoit des valeurs postées, elle n'a pas possibilité de savoir si elles ont été vérifiées par le client avant leur envoi. Côté serveur, le développeur doit donc toujours vérifier la validité des données postées.

La page [Default.aspx] évolue comme suit :

1. <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs"

Inherits="Intro._Default" %>

2. 3. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

4. <html xmlns="http://www.w3.org/1999/xhtml"> 5. <head runat="server">

http://tahe.developpez.com

13/46

6. <title>Introduction ASP.NET</title> 7. </head> 8. <body> 9. <h3>Introduction à ASP.NET</h3> 10. <form id="form1" runat="server"> 11. <div> 12. <table> 13. <tr> 14. <td> 15. Nom</td> 16. <td> 17. <asp:TextBox ID="TextBoxNom" runat="server"></asp:TextBox> 18. </td> 19. <td> 20. <asp:RequiredFieldValidator ID="RequiredFieldValidatorNom" runat="server" 21. ControlToValidate="TextBoxNom" Display="Dynamic" 22. ErrorMessage="Donnée obligatoire !"></asp:RequiredFieldValidator> 23. </td> 24. </tr> 25. <tr> 26. <td> 27. Age</td> 28. <td> 29. <asp:TextBox ID="TextBoxAge" runat="server"></asp:TextBox> 30. </td> 31. <td> 32. <asp:RequiredFieldValidator ID="RequiredFieldValidatorAge" runat="server" 33. ControlToValidate="TextBoxAge" Display="Dynamic" 34. ErrorMessage="Donnée obligatoire !"></asp:RequiredFieldValidator> 35. <asp:RangeValidator ID="RangeValidatorAge" runat="server" 36. ControlToValidate="TextBoxAge" Display="Dynamic" 37. ErrorMessage="Tapez un nombre entre 1 et 150 !" MaximumValue="150" 38. MinimumValue="1" Type="Integer"></asp:RangeValidator> 39. </td> 40. </tr> 41. </table> 42. </div> 43. <asp:Button ID="ButtonValider" runat="server" onclick="ButtonValider_Click" 44. Text="Valider" CausesValidation="False"/> 45. <hr /> 46. <p> 47. Evénements traités par le serveur</p> 48. <p> 49. <asp:ListBox ID="ListBoxEvts" runat="server" EnableViewState="False"> 50. </asp:ListBox> 51. </p> 52. <p> 53. Eléments postés au serveur : 54. <asp:Label ID="LabelPost" runat="server"></asp:Label> 55. </p> 56. <p> 57. Eléments validés par le serveur : 58. <asp:Label ID="LabelValidation" runat="server"></asp:Label> 59. </p> 60. <asp:Label ID="LabelErreursSaisie" runat="server" ForeColor="Red"></asp:Label> 61. </form> 62. </body> 63. </html>

Les validateurs ont été rajoutés aux lignes 20, 32 et 35. Ligne 58, un composant Label est utilisé pour afficher les valeurs postées valides. Ligne 60, un un composant Label est utilisé pour afficher un message d'erreur s'il y a des erreurs de saisie.

La page [Default.aspx] peut être également construite en mode [Design]. Les nouveaux composants peuvent être trouvés dans la boîte à outils sous le thème Validation.

Publicité

http://tahe.developpez.com

14/46

1

2

3

4

• •

•

les composants [1] et [2] sont de type RequiredFieldValidator. Ce validateur vérifie qu'un champ de saisie est non vide. le composant [3] est de type RangeValidator. Ce validateur vérifie qu'un champ de saisie contient une valeur entre deux bornes. en [4], les propriétés du validateur [1].

Nous allons présenter les deux types de validateurs au travers de leurs balises dans le code de la page [Default.aspx] :

<asp:RequiredFieldValidator ID="RequiredFieldValidatorNom" runat="server" ControlToValidate="TextBoxNom" Display="Dynamic" ErrorMessage="Donnée obligatoire !"></asp:RequiredFieldValidator>

• •

• •

ID : l'identifiant du composant ControlToValidate : le nom du composant dont la valeur est vérifiée. Ici on veut que le composant TextBoxNom n'ait pas une valeur vide (chaîne vide ou suite d'espaces) ErrorMessage : message d'erreur à afficher dans le validateur en cas de donnée invalide. EnableClientScript : booléen indiquant si le validateur doit être exécuté également côté client. Cet attribut a la valeur True par défaut lorsqu'il n'est pas explicitement positionné comme ci-dessus.

• Display : mode d'affichage du validateur. Il y a deux modes :

• •

static (défaut) : le validateur occupe de la place sur la page même s'il n'affiche pas de message d'erreur dynamic : le validateur n'occupe pas de place sur la page s'il n'affiche pas de message d'erreur.

<asp:RangeValidator ID="RangeValidatorAge" runat="server" ControlToValidate="TextBoxAge" Display="Dynamic" ErrorMessage="Tapez un nombre entre 1 et 150 !" MaximumValue="150" MinimumValue="1" Type="Integer"></asp:RangeValidator>

Type : le type de la donnée vérifiée. Ici l'âge est un entier.

• • MinimumValue, MaximumValue : les bornes dans lesquelles doit se trouver la valeur vérifiée

La configuration du composant qui provoque le POST joue un rôle dans le mode de validation. Ici ce composant est le bouton [Valider] :

<asp:Button ID="ButtonValider" runat="server" onclick="ButtonValider_Click" Text="Valider" CausesValidation="True" />

•

CausesValidation : fixe le mode automatique ou nom des validations côté serveur. Cet attribut a la valeur par défaut "True" s'il n'est pas explicitement mentionné. Dans ce cas,

•

côté client, les validateurs ayant EnableClientScript à True sont exécutés. Le POST n'a lieu que si tous les validateurs côté client réussissent.

http://tahe.developpez.com

15/46

•

côté serveur, tous les validateurs présents sur la page sont automatiquement exécutés avant le traitement de l'événement qui a provoqué le POST. Ici, ils seraient exécutés avant l'exécution de la méthode ButtonValider_Click. Dans cette méthode, il est possible de savoir si toutes les validations ont réussi ou non. Page.IsValid est "True" si elles ont toutes réussi, "False" sinon. Dans ce dernier cas, on peut arrêter le traitement de l'événement qui a provoqué le POST. La page postée est renvoyée telle qu'elle a été saisie. Les validateurs ayant échoué affichent alors leur message d'erreur (attribut ErrorMessage).

Si CausesValidation a la valeur False, alors

• •

côté client, aucun validateur n'est exécuté côté serveur, c'est au développeur de demander lui-même l'exécution des validateurs de la page. Il le fait avec la méthode Page.Validate(). Selon le résultat des validations, cette méthode positionne la propriété Page.IsValid à "True" ou "False".

Dans [Default.aspx.cs] le code de traitement de ButtonValider_Click évolue comme suit :

1. protected void ButtonValider_Click(object sender, EventArgs e) 2. { 3. // on note l'événement 4. ListBoxEvts.Items.Insert(0, string.Format("{0}: ButtonValider_Click",

DateTime.Now.ToString("hh:mm:ss")));

5. // on affiche le nom et l'âge 6. LabelPost.Text = string.Format("nom={0}, age={1}", TextBoxNom.Text.Trim(),

TextBoxAge.Text.Trim());

7. // la page est-elle valide ? 8. Page.Validate(); 9. if (!Page.IsValid) 10. { 11. // msg d'erreur global 12. LabelErreursSaisie.Text = "Veuillez corriger les erreurs de saisie..."; 13. LabelErreursSaisie.Visible = true; 14. return; 15. } 16. // on cache le msg d'erreur 17. LabelErreursSaisie.Visible = false; 18. // on affiche le nom et l'âge validés 19. LabelValidation.Text = string.Format("nom={0}, age={1}", TextBoxNom.Text.Trim(),

TextBoxAge.Text.Trim());

20. }

Dans le cas où le bouton [Valider] a son attribut CausesValidation à True et les validateurs leur attribut EnableClientScript à True, la méthode ButtonValider_Click n'est exécutée que lorsque les valeurs postées sont valides. On peut se demander alors le sens du code que l'on trouve à partir de la ligne 8. Il faut alors se rappeler qu'il est toujours possible d'écrire un client programmé qui poste des valeurs non vérifiées à la page [Default.aspx]. Donc celle-ci doit toujours refaire les tests de validité.

•

• •

ligne 8 : lance l'exécution de tous les validateurs de la page. Dans le cas où le bouton [Valider] a son attribut CausesValidation à True, ceci est fait automatiquement et il n'y a pas lieu de le refaire. Il y a ici redondance. lignes 9-15 : cas où l'un des validateurs a échoué lignes 16-19 : cas où tous les validateurs ont réussi

Voici deux exemples d'exécution :

http://tahe.developpez.com

16/46

1

2

3

5

4

6

7

•

en [1], un exemple d'exécution dans le cas où :

• •

le bouton [Valider] a sa propriété CausesValidation à True les validateurs ont leur propriété EnableClientScript à True

Les messages d'erreurs [2] ont été affichés par les validateurs exécutés côté client par le code Javascript de la page. Il n'y a pas eu de POST vers le serveur comme le montre le label des éléments postés [3]. en [4], un exemple d'exécution dans le cas où :

•

• •

le bouton [Valider] a sa propriété CausesValidation à False les validateurs ont leur propriété EnableClientScript à False

Les messages d'erreurs [5] ont été affichés par les validateurs exécutés côté serveur. Comme le montre [6], il y a bien eu un POST vers le serveur. En [7], le message d'erreur affiché par la méthode [ButtonValider_Click] dans le cas d'erreurs de saisie.

8

9

10

http://tahe.developpez.com

17/46

•

en [8] un exemple obtenu avec des données valides. [9,10] montrent que les éléments postés ont été validés. Lorsqu'on fait des tests répétés, il faut mettre à False la propriété EnableViewState du label [LabelValidation] afin que le message de validation ne reste pas affiché au fil des exécutions.

2.6 Gestion des données de portée Application

Revenons sur l'architecture d'exécution d'une page ASPX :

Navigateur

Serveur web

Html

1

2

Page ASPX

La classe de la page ASPX est instanciée au début de la requête du client et détruite à la la fin de celle-ci. Aussi elle ne peut servir à mémoriser des données entre deux requêtes. On peut vouloir mémoriser deux types de données :

•

•

des données partagées par tous les utilisateurs de l'application web. Ce sont en général des données en lecture seule. Trois fichiers sont utilisés pour mettre en oeuvre ce partage de données :

• •

[Web.Config] : le fichier de configuration de l'application [Global.asax, Global.asax.cs] : p