Cours
2.1 – Cycle de vie d’une application ASP.NET
Le schéma suivant représente les différentes étapes, depuis la demande effectuée par un navigateur jusqu’à la réponse obtenue par le serveur.
Nous considérons que l’application s’exécute dans IIS 7.0 en mode intégré avec une version du .NET Framework égale ou supérieure à v3.0.
Nous avons également activé l’authentification anonyme et l’authentification par formulaire.
1 La demande arrive sur le serveur. Création du contexte de la demande par dé-sérialisation de la requête http : obtention des éléments tels que infos sur client, paramètres de la demande, format de la demande, …
2 le pipeline envoie le contrôle d’authentification aux modules configurés
3 réception de l’autorisation du module d’authentification
4 Résolution du cache. Si configuré, appel de la ressource précédemment mise en cache
5 mappage du gestionnaire en fonction du nom ou de l’extension de page demandée
6 exécution du gestionnaire PageHandlerFactory pour une page .aspx, ou StaticFileModule pour les fichiers statiques
7 mise à jour du cache à partir de la réponse obtenue
8 consignation de la demande (module personnalisé)
9 envoi de la réponse au navigateur
Au cours des ce cycle de vie, différents objets vont être instanciés par ASP.NET et accessibles depuis l’application.
2.1.1 - HttpApplication
A chaque application Web s’exécutant sur IIS correspond une instance de la classe HttpApplication.
Cet objet va suivre le parcours de traitement de la requête HTTP et déclencher des événements à chaque étape vue précédemment.
Si l’on souhaite accéder à ces événements, on peut intégrer un fichier global.asax dans notre application (ajout d’un élément de type Classe d’application globale).
Cet objet implémente une version dérivée de la classe System.Web.HttpApplication
Par défaut, elle nous propose les événements les plus couramment utilisés :
-
Application_Start et Application_End
-
Application_BeginRequest et Application_AuthenticateRequest
-
Session_Start et Session_End
Mais tous les autres événements déclenchés pendant le cycle de vie de l’application sont accessibles.
Fichier global.asax
Imports System.Web.SessionState
Public Class Global_asax
Inherits System.Web.HttpApplication
Sub Application_Start(ByVal sender As Object, ByVal e As EventArgs)
' Se déclenche lorsque l'application est démarrée
End Sub
Sub Session_Start(ByVal sender As Object, ByVal e As EventArgs)
' Se déclenche lorsque la session est démarrée
End Sub
Sub Application_BeginRequest(ByVal sender As Object, ByVal e As EventArgs)
' Se déclenche au début de chaque demande
End Sub
Sub Application_AuthenticateRequest(ByVal sender As Object, ByVal e As EventArgs)
' Se déclenche lors d'une tentative d'authentification de l'utilisation
End Sub
Sub Application_Error(ByVal sender As Object, ByVal e As EventArgs)
' Se déclenche lorsqu'une erreur se produit
End Sub
Sub Session_End(ByVal sender As Object, ByVal e As EventArgs)
' Se déclenche lorsque la session se termine
End Sub
Sub Application_End(ByVal sender As Object, ByVal e As EventArgs)
' Se déclenche lorsque l'application se termine
End Sub
End Class
C’est dans cette classe que l’on peut implémenter un compteur de visites ou le nombre actuel de visiteurs en ajoutant du code dans l’événement Session_Start (qui sera déclenché pour chaque nouvelle session utilisateur).
2.1.2 - HttpContext
Cette classe contient des informations spécifiques à la demande d’application actuelle.
Elle expose la propriété statique Current qui donne accès à de nombreuses informations sur la requête en cours par l’intermédiaire de classes spécifiques : Application, Cache, Request, Response, Server, Session, …
Exemple :
Dim s As String = HttpContext.Current.Request.UserAgent
Renvoie par exemple: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:10.0.2) Gecko/20100101 Firefox/10.0.2
On peut aussi utiliser directement l’objet Context qui est l’objet HttpContext associé à la page en cours.
Dim s As String = Context.Request.UserAgent
2.1.3 – HttpRequest
Cette classe permet de lire les valeurs contenues dans la requête HTTP envoyée par le client.
Une instance de cette classe est exposée par l’objet Context de la page.
Cette instance est aussi accessible directement depuis la page via l’objet Request.
Elle expose des propriétés permettant d’accéder directement à des valeurs spécifiques de la demande (URL, paramètres d’URL, méthode http,…)
Exemple, pour récupérer la valeur transmise par l’URL par la variable monparam :
Dim s As String = Context.Request.QueryString("monparam")
ou
Dim s As String = Request.QueryString("monparam")
2.1.4 – HttpResponse
Cette classe permet d’accéder et d’écrire dans la réponse HTTP envoyée au client.
Une instance de cette classe est exposée par l’objet Context de la page.
Cette instance est aussi accessible directement depuis la page via l’objet Response.
Exemple, pour envoyer "bonjour" dans la réponse HTTP :
Context.Response.Write("Bonjour")
ou
Response.Write("Bonsoir")
2.1.5 – HttpSessionState
Cette classe permet d’accéder en lecture et écriture aux valeurs spécifiques à une session.
Une instance de cette classe est exposée par l’objet Context de la page.
Cette instance est aussi accessible directement depuis la page via l’objet Session.
Exemple :
Context.Session("param1") = "test" ' Ecrit la valeur
ou
Session("param1") = "test" ' Ecrit la valeur
Dim s As String = Session("param1") = "test" ' Lit la valeur
Une valeur enregistrée dans une variable de session a une durée de vie égale à celle de la session correspondante.
Ce type de variable est fréquemment utilisé pour écrire et lire des valeurs relatives à la session en cours.
2.2 – Cycle de vie d’une page ASP.NET
Une page ASP.NET est une instance d’une classe dérivée de la classe System.Web.UI.Page
Elle dispose donc des membres hérités de cette classe de base et comme pour toute classe, on peut lui ajouter des membres spécifiques.
On peut donc accéder à ses propriétés, méthodes et événements depuis le code behind.
Lorsqu’une page est appelée depuis le navigateur, une instance de la classe correspondante est créée.
Le contenu de la page est créé à partir de la description donnée dans la partie design (html) et à partir du code de la page en code behind.
Le traitement crée les éventuels contrôles serveurs enfants, charge les valeurs dans ces contrôles et envoie la page au navigateur client sous forme de code html.
Lors de chacune de ces étapes, l’objet Page déclenche des évènements auxquels nous pouvons nous abonner afin d’effectuer des traitements spécifiques.
2.2.1 – Les étapes du cycle de vie
Phase d’initialisation
PreInit: (événement)
• Détermine si la page est chargée pour la première fois (propriété IsPostBack du contrôle Page).
• Initialisation des controles
• Activation du suivi de modifications du ViewState sur les controles
• Chargement CSS
Init : (événement)
• Apparence chargée.
• Contrôles initialisés.
• Permet de lire / initialiser des propriétés de contrôle.
InitComplete : (événement)
• Fin de la phase d'initialisation (tous les objets sont initialisés)
Phase de chargement
Preload : (événement)
• A utiliser si on a besoin d’effectuer une action relative au chargement avant l’évènement Load.
Load : (événement)
• Charge récursivement les contrôles enfants de la page
Fonctions événements (en cas de Postback)
• Appelle la fonction correspondant à l’événement déclenché par un contrôle enfant.
LoadComplete : (événement)
• Pour les actions nécessitant que l'ensemble de la page soit chargée
Phase de rendu
Prerender : (événement)
• Dernier évènement qui permet de modifier le contenu de la page et des contrôles
• Permet de remplir les contrôles avec des données s’il y a lieu (par rapport à une source de données telle qu’une base SQL, un fichier XML …)
SaveStateComplete : (événement)
• A partir de cet évènement, toute modification de la page et/ou de ses contrôles sera ignorée.
• Permet de sauvegarder l'état des contrôles tels qu’ils seront affichés.
Render : (méthode)
• Génération du code HTML pour le navigateur.
Phase de fermeture
Unload : (événement)
• Utilisé pour fermer les connexions à toutes les sources de données et/ou vider les variables temporaires en fin vie de la page.
2.2.2 - La propriété IsPostBack
L’objet Page expose la propriété IsPostBack (Boolean) qui permet de connaitre le type de la requête HTTP actuellement demandée.
Si la requête est de type GET, IsPostBack renvoie False
Si la requête est de type POST, IsPostBack renvoie True
Cette propriété est souvent utilisée pour savoir si l’on doit charger les valeurs de certains contrôles (si requête de type GET : IsPostBack = False), ou si ces contrôles ont déjà été chargés une fois (POST : IsPostBack=True).
2.3 - Les contrôles serveurs simples
2.3.1 - Définition
Un contrôle serveur est, comme son nom l’indique, accessible depuis le serveur (afin d’extraire ou modifier les valeurs de ses propriétés, réagir à ses événements, …)
Pour cela, dans sa définition depuis le code HTML, un contrôle serveur contient toujours au moins les 2 attributs suivants :
-
runat="server".
-
Id="id_du_controle"
Les contrôles serveurs sont représentés par des classes, toutes dérivées indirectement de la classe System.Web.UI.Control :
TemplateControl est une classe abstraite (donc non instantiable) qui est utilisée pour fournir les propriétés, méthodes et événements de base à des contrôles qui en dérivent (Page et UserControl par exemple).
Il existe globalement 2 types de contrôles serveur :
-
Les contrôles Html
-
Les contrôles Web
2.3.2 - Les contrôles Html
Ils sont implémentés surtout pour permettre la portabilité des applications statiques utilisant des contrôles HTML et pour permettre d’y accéder facilement coté serveur.
Ils permettent de gérer, coté serveur, les balises HTML classiques <span>, <div>, <a>, <select>,<textarea>,<input>…
Propriétés et méthodes
Les contrôles Html dérivent au minimum des classes suivantes :
System.Object
System.Web.UI.Control
System.Web.UI.HtmlControls.HtmlControl
Chacune de ces classes de base expose des membres utilisables dans tous les HtmlControls.
Exemple de propriétés communes: Attributes, Controls, Disabled, Parent, Style, ViewState, Visible, …
Exemple de méthodes communes: FindControl(id), Focus(), GetAttribute(), SetAttribute(), …
Exemple d’événements communs: DataBinding, Init, Load, PreRender,…
Chaque contrôle de type contrôle Html dispose ensuite de ses propres membres complémentaires spécifiques à sa fonctionnalité.
Utilisation
Pour tester les HtmlControls, nous créons une nouvelle page Web Form nommée TestHtmlControls.
Coté HTML, on déclare un contrôle Html en utilisant un élément HTML classique auquel on fournit les 2 attributs id et runat="server".
Exemple :
<body>
<form id="form1" runat="server">
<h2>
<span id="monMessage" runat="server" >original</span>
</h2>
<a id="monLien" runat="server">mon lien</a>
</form>
</body>
Si nous affichons maintenant le code behind, la liste des objets de la page contient les 2 éléments monLien et MonMessage.
Ces 2 contrôles HTML sont donc représentés sous forme d’objets depuis le code serveur.
On peut y accéder par le nom qu’on leur a donné dans l’attribut id.
Ainsi, en tapant leur nom dans l’éditeur, l’Intellisense nous propose automatiquement leurs membres dès que l’on saisit un point (accesseur) derrière ce nom:
On peut par exemple accéder aux valeurs CSS du lien en utilisant la propriété Style. Ex :
monLien.Style.Item("color") = "red"
On peut aussi accéder aux événements de ce contrôle.
Si l’on souhaite réagir à l’événement ServerClick, on le choisit dans la liste :
L’éditeur pré-remplit la fonction de gestion de l’événement dans laquelle il ne nous reste plus qu’à remplir le code souhaité.
Dans cet exemple, on modifie le texte du contrôle HTML monMessage :
Exécutons notre code (avec F5 par exemple). Le premier affichage donne ceci :
Cliquons maintenant sur mon lien :
Nous venons donc de modifier un contrôle HTML <span> depuis le code behind en réagissant à un événement sur un contrôle HTML <a>.
Principaux contrôles HTML (liste non exhaustive) :
Contrôle HTML coté HTML
|
Contrôle HTML coté serveur
|
<a>
|
HtmlAnchor
|
<button>
|
HtmlButton
|
<form>
|
HtmlForm
|
<img>
|
HtmlImage
|
<input type=button>,<input type=submit>,<input type=reset>
|
HtmlInputButton
|
<input type=checkbox>
|
HtmlInputCheckBox
|
<input type=hidden>
|
HtmlInputHidden
|
<table><tr><td>
|
HtmlTable, HtmlTableRow, HtmlTableCell
|
<textarea>
|
HtmlTextArea
|
Controles sans équivalent Html… coté serveur
|
HtmlGenericControl
|
2.3.3 - Les contrôles Web
Les contrôles Web sont des contrôles comparables aux contrôles HTML, mais offrent une plus grande étendue de fonctionnalités.
De la même façon que pour les contrôles HTML, on fournira au minimum les 2 attributs id et runat="server".
Coté HTML, les contrôles serveurs Web sont tous préfixés par <asp :
En tapant ce mot clé dans l’éditeur HTML, l’intellisense vous propose une centaine de contrôles Web !
Utilisation
Pour tester les WebControls, nous créons une nouvelle page Web Form nommée TestWebControls.
Reprenons l’exemple précédent en remplaçant les contrôles HTML par des contrôles Web :
Coté HTML, à part le type des contrôles, rien n’a changé :
<body>
<form id="form1" runat="server">
<h2>
<asp:Label ID="monMessage" runat="server">original</asp:Label>
</h2>
<asp:LinkButton ID="monLien" runat="server">mon LinkButton</asp:LinkButton>
</form>
</body>
Coté serveur :
On aperçoit que pour modifier la couleur du texte du lien (qui est un <a> en sous-jacent), on a un accès direct à la propriété ForeColor qui accepte une des valeurs de l’énumération Drawing.Color.
De nombreuse propriétés CSS sont ainsi accessibles directement sans passer par l’attribut Style.
On aperçoit aussi que pour modifier le texte du label (qui est un <span> en sous-jacent), on utilise la propriété Text à la place de InnerHtml.
Public Class WebFormControlsWeb
Inherits System.Web.UI.Page
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
monLien.ForeColor = Drawing.Color.Red
End Sub
Private Sub monLien_Click(sender As Object, e As System.EventArgs) Handles monLien.Click
monMessage.Text = "On a cliqué sur le LinkButton !"
End Sub
End Class
2.3.1 - Création dynamique d’un contrôle Web
On crée dynamiquement un contrôle en instanciant sa classe et en ajoutant celle-ci à la collection des contrôles d’un contrôle conteneur.
Dim tb3 As New TextBox
tb3.ID = "TB3"
tb3.Text = "texte de départ..."
form1.Controls.Add(tb3)
Pour accéder à un contrôle créé dynamiquement, on recherche le contrôle à partir de son ID depuis le conteneur parent avec la méthode FindControl :
Dim tb As TextBox = form1.FindControl("TB3")
Dim s As String = tb.Text
Les principaux contrôles Web de base
2.3.1 Panel
C’est un conteneur qui sera rendu sous forme de <div>.
2.3.2 - Label
Ce contrôle sera rendu sous forme de <span>.
<asp:Label ID="Lb_Titre" runat="server" Text="Titre">
2.3.3 – Button
Ce contrôle sera rendu sous forme de <input type="submit">
<asp:Button ID="But_Enregistrer" runat="server" Text="Enregistrer" />
Il est possible de declarer une function déclenchée coté client lors d’un clic.
Dans ce cas, cette function sera appelée avant le renvoi de la page au serveur.
<asp:Button ID="But_Enregistrer" runat="server" Text="Enregistrer"
OnClientClick ="alert('OnClientClick');" />
2.3.4 - TextBox (single et multiline)
En mode SingleLine, ce contrôle sera rendu sous forme de <input type="text">
<asp:TextBox ID="Tb_Nom" runat="server" ></asp:TextBox>
En mode Password, ce contrôle sera rendu sous forme de <input type="password">
<asp:TextBox ID="Tb_Password" runat="server" TextMode=Password />
En mode MultiLine, ce contrôle sera rendu sous forme de <textarea >
<asp:TextBox ID="Tb_Infos" runat="server" TextMode=MultiLine />
2.3.5 – DropDownList
Ce contrôle sera rendu sous forme de <select name="…" id="…">
Et les entrées sous la forme <option selected="selected" value="1">nom de l’entrée</option>
<asp:DropDownList ID="DropDownList1" runat="server">
<asp:ListItem Text="text1" Value="1"></asp:ListItem>
</asp:DropDownList>
2.3.6 – CheckBox
Ce contrôle sera rendu sous forme de <input type="checkbox">
<asp:checkbox ID="Ckb_Vehicule" runat="server" Text="Vehicule" Checked="true" />
2.3.7 – RadioButton
Ce contrôle sera rendu sous forme de <input type="radio">
<asp:RadioButton ID="Rb_Mademoiselle" runat="server" GroupName ="Gn_Titre" Text="Mademoiselle" />
<asp:RadioButton ID="Rb_Madame" runat="server" GroupName ="Gn_Titre" Text="Madame" />
2.3.8 – Literal
Tout comme le Label, le contrôle serveur Literal va afficher du texte.
A la différence du Label, qui lui va rajouter des balises <span></span> dans le code source, le contrôle serveur Literal ne va rajouter aucun élément HTML. Ce qui veut dire qu'il est impossible de lui appliquer un style.
On peut en revanche lui appliquer un ID et donc faire appel à lui depuis le code behind pour changer ses propriétés (comme Text, Mode, …)
Propriété
|
Valeur(s)
|
Définition
|
Text
|
Chaîne de caractère
|
Permet de changer le texte qui sera affiché.
|
Mode
|
-
|
Permet de changer le mode d’affichage du texte.
|
PassThrough
|
Va afficher le texte comme si c’était du HTML (les balises HTML se trouvant dans le code sont donc prises en compte).
|
Transform
|
Permet de convertir le code pour qu'il s'affiche comme s'il était dans le code source (donc les balises HTML seront prises en compte). Mais plus que le HTML on peut aussi y mettre du XHTML (eXtensible Hypertexte Markup Langage), WML Wireless Markup Langage, cHTML (Compact Hypertexte Markup Langage) qui seront affichés / transformés en html.
|
Encode
|
Va afficher le texte brut, c'est-à-dire sans prendre en compte les balises HTML ou autres. Un texte contenant des balises HTML sera affiché avec les balises visibles sur la page.
|
|
|
|
|
Ainsi ce code :
Page.ASPX
<p>PassThrough</p>
<asp:Literal ID="Literal1" runat="server" Text="Salut <strong>tous</strong> le <sub>monde</sub> !<script type='text/javascript'>alert('Hello World !');</script>" Mode="PassThrough" /><br />
<p>Transform</p>
<asp:Literal ID="Literal2" runat="server" Text="Salut <strong>tous</strong> le <sub>monde</sub> !<script type='text/javascript'>alert('Hello World !');</script>" Mode="Transform" /><br />
<p>Encode</p>
<asp:Literal ID="Literal3" runat="server" Text="Salut <strong>tous</strong> le <sub>monde</sub> !<script type='text/javascript'>alert('Hello World !');</script>" Mode="Encode" />
Donnera ceci : Les différents mode d’affichage du contrôle serveur Literal Avec la fenêtre "Hello World !" qui s’ouvre pour PassThrough et Transform.
2.3.9 - Table, TableRow, TableCell
Ce contrôle sera rendu sous forme de <table> <tr> <td>
<asp:Table>
<asp:TableHeaderRow></asp:TableHeaderRow>
<asp:TableRow >
<asp:TableCell ></asp:TableCell>
</asp:TableRow>
<asp:TableFooterRow></asp:TableFooterRow>
</asp:Table>
Un tableau est un bon moyen pour mettre en forme/présenter des informations à l'utilisateur. Pour cela le contrôle serveur Table crée un tableau. TableRow correspond à une nouvelle ligne du tableau et TableCell correspond à une nouvelle cellule (plus exactement il fait une colonne comme en HTML). Donc dans le Table on a une balise racine Table, puis des TableRow qui contiennent des TableCell. Il existe aussi des balises comme TableHeaderRow et TableFooterRow. TableHeaderRow est le Header du tableau. Il se situe donc en haut de celui-ci (c’est le titre de chaque colonne) : il correspond aux th en HTML. Le TableFooterRow fonctionne lui aussi comme en HTML, c'est-à-dire qu’il contient des cellules normales (TableCell).
Tout comme les autres contrôles serveur Web on peut le modifier ou même le créer depuis le code behind. Pour ajouter des Rows ou des Cells depuis le code behind il faut se servir de la méthodeRows.Add qui attend un objet de type TableRow du tableau et de Cells.Add du TableRow. Plus précisément on se sert de la méthode Add() des collections Cells et Rows.
2.4 –CSS
Pour ajouter une feuille de style, on ajoute un élément de type Feuille de style dans le projet.
Pour utiliser cette feuille de style depuis une page .aspx, on ajoute la directive suivante :
<link type="text/css" href="Style1.css" rel="Stylesheet" />
2.5 – Thèmes
Les Thèmes sont utilisés pour donner une décoration identique à tous les contrôles du même type.
Pour cela, ajouter le dossier ASP.NET, Theme.
On renomme ensuite ce dossier spécial, par exemple BlueTheme.
Un theme est composé au minimum d’une fichier d’apparence auquel on peut mlui adjoindre une feuille de style.
Sélectionner le dossier BlueTheme, puis ajouter, Fichier d’aparence.
On peut renommer ce fichier, par exemple : StdControls.skin (dans lequel on modifiera l’apparence des controles standards).
Dans ce fichier, on indique le nom du type de contrôle pour lequel on souhaite donner une apparence commune et on remplit les attributs correspondants :
<asp:button runat="server" BackColor="lightblue" ForeColor="Darkblue" Font-Name="Verdana" Font-Size="10px" />
<asp:textbox runat="server" BackColor="lightblue" ForeColor="black" Font-Name="Arial" Font-Size="9px" />
Pour appliquer le thème à l’ensemble du site, on place sa déclaration de le fichier web.config
<configuration>
<system.web>
<pages theme="BlueTheme" />
</system.web>
</configuration>
Pour appliquer le thème seulement à une page, on ajoute sa déclaration au niveau des directives de page :
<%@ Page Language="vb" AutoEventWireup="false" CodeBehind="EditClient.aspx.vb" Inherits="WebApplication30.EditClient" Theme="BlueTheme" %>
Pour appliquer un thème dynamiquement pour une page, on doit le faire dans l’évènement PreInit :
Protected Sub Page_PreInit(ByVal sender As Object, _
ByVal e As System.EventArgs) _
Handles Me.PreInit
Select Case Request.QueryString("theme")
Case "Blue"
Page.Theme = "BlueTheme"
Case "Pink"
Page.Theme = "PinkTheme"
End Select
End Sub
On peut aussi ajouter une feuille de style dans un theme.
Celle-ci sera utilisée par la page si elle utilise ce theme.
Selectionner le dossier BlueTheme, puis ajouter, Feuille de style.
On peut renommer ce fichier, exemple : BlueStyle.css