Développement d`une application Web avec ASP .NET MVC

Transcription

Développement d`une application Web avec ASP .NET MVC
Développement d'une application Web avec ASP .NET MVC
Livre Visual Studio 2010 aux éditions ENI par James Ravaille et Julien Dollon
Développement d'une application Web avec
ASP .NET MVC
A. Introduction
A.1. Présentation
Depuis la version 3.5 du Framework .NET, Microsoft propose sous forme
d'extensions, un nouveau modèle de conception et de développement
d'applications Web, nommé ASP .NET MVC. Nous verrons qu'il ne s'agit en
aucun cas d'une technologie remplaçant la technologie ASP .NET WebForms,
que nous avons utilisé dans le chapitre précédent, mais d'une alternative. En
effet, le modèle MVC est un modèle de développement reconnu ayant fait ses
preuves dans d'autres technologies telles que les technologies J2EE et PHP.
Microsoft a simplement décidé de proposer une implémentation de ce modèle,
que nous allons étudier pour créer une application Web.
A.2. Présentation du modèle ASP .NET MVC
Le modèle ASP .NET MVC, où MVC est l'acronyme de Modèle Vue Contrôleur,
permet de créer des applications Web composée :
• D'un modèle, constitué d'un ensemble de classes permettant de créer les
objets métiers manipulés dans l'application, et d'exécuter les traitements
métiers.
• De vues constituant des éléments graphiques tels que des contrôles
utilisateurs, des pages Web ou encore des Master Pages. Ces éléments
graphiques sont implémentés de manière radicalement différente par rapport à
leurs homologues en ASP.NET WebForms.
• De contrôleurs permettant de piloter l'application, d'exécuter des actions et
fournir une vue en réponse aux requêtes reçues. L'une des fonctionnalités
fondamentales des contrôleurs est d'assurer la communication entre le modèle
et la vue.
A.3. ASP .NET VS ASP .NET MVC
A.3.a. Les différences entre les applications ASP .NET WebForms et
ASP .NET MVC
Même si leur but est identique, à savoir construire des applications Web, la
conception et le développement d'une application ASP .NET MVC est très
différente d'une application ASP .NET WebForms. Voici les principales
caractéristiques d'ASP .NET MVC qui le différencient :
Page 1 sur 41
Développement d'une application Web avec ASP .NET MVC
Livre Visual Studio 2010 aux éditions ENI par James Ravaille et Julien Dollon
• ASP .NET MVC permet de structurer davantage l’application, en créant des
composants avec des rôles bien identifiés.
• ASP .NET MVC ne supporte pas les posts-backs classiques et l'utilisation du
ViewState. L’utilisation des contrôles ASP .NET n’est pas encouragée. Même
s’il s’agit d’un facteur de ralentissement dans le développement d’une
application Web, il permet de mieux contrôler le flux XHTML renvoyé au client
Web (rendu des contrôles, données dans le flux, …). Pour échanger des
informations entre les clients Web et le serveur IIS, ASP .NET MVC utilise le
modèle REST (REpresentational State Transfer). Chaque page est divisée en
deux composants distincts (un contrôleur et une vue) qui agissent sur le même
modèle de données.
• ASP .NET MVC utilise un modèle nommé Front Controller, qui permet de
traiter les requêtes de l'application Web par l'intermédiaire du routage et d'un
contrôleur. ASP.NET MVC ne considère pas une URL comme un point de
terminaison vers un fichier d’une application. Une URL est considérée comme
un moyen d’accéder à une ressource (logique) sur le serveur, mais pas
nécessairement un fichier ASPX à exécuter. Nous aurons alors l’occasion de
voir que les URLs possèdent un format particulier de type /Controleur/action/id.
• ASP .NET MVC offre un meilleur support pour le développement dirigé par les
tests (Test Driven Development). Lors de la création d’un projet de type ASP
.NET MVC, Microsoft propose de créer un projet de test, qui permettra de
tester au fur et à mesure du développement de l’application.
A.3.b. Choisir entre ASP .NET WebForms et ASP .NET MVC
Le modèle MVC est un modèle de développement ayant fait ses preuves dans
d’autres technologies de développement d’applications Web telles que la
technologie J2EE. Quand aux pages ASP .NET Web Forms, la vue (page ASPX)
manque de souplesse dans le sens où elle doit souvent contenir trop de
traitements ne facilitant pas le découpage en couche de l’application. Le modèle
MVC permet d’agir sur la conception et le développement de l’application en
assurant un découpage en couche. Mais sa contrepartie réside dans un
développement plus coûteux en temps.
Le choix entre les pages WebForms et les pages MVC se fera en fonction de
l’évaluation des critères suivants : nombre de pages Web dans le projet,
exigence en matière d’architecture (la présence d’un architecte étant souhaitée),
connaissances des développeurs en matière d’architecture, temps alloué pour
développer le projet …
B. Exécution d'une requête HTTP
Pour créer une application avec ASP .NET MVC, il est important de comprendre
comment est traitée une requête HTTP à destination d'une page ASP.NET MVC :
Page 2 sur 41
Développement d'une application Web avec ASP .NET MVC
Livre Visual Studio 2010 aux éditions ENI par James Ravaille et Julien Dollon
1 - Un utilisateur envoie au travers d'un client Web une requête vers une
application ASP .NET MVC.
2 - Le module UrlRoutingModule intercepte la requête pour la router en fonction
des routes définies dans la table de routage (créée lors du démarrage de
l'application). Cette requête ne vise pas une page directement une page. Elle
désigne une action d'un contrôleur. Si aucune action n'est précisée dans la
requête HTTP, alors il s'agit de l'action Index par défaut qui est exécutée sur le
contrôleur. Si le contrôleur n'est pas présent, alors l'action Index est exécutée sur
le contrôleur Home. Ce contrôleur et action par défaut sont définis dans le fichier
global.asax. Le module UrlRoutingModule est défini dans le fichier de
configuration :
<httpModules>
<add name="UrlRoutingModule"
type="System.Web.Routing.UrlRoutingModule, System.Web.Routing,
Version=3.5.0.0, Culture=neutral,
PublicKeyToken=31BF3856AD364E35"/>
</httpModules>
Page 3 sur 41
Développement d'une application Web avec ASP .NET MVC
Livre Visual Studio 2010 aux éditions ENI par James Ravaille et Julien Dollon
3 ; 4 et 5 - Le contrôleur s'exécutant, peut faire appel au modèle pour consulter
de la base de données, exécuter des traitements métiers, mettre à jour des
données…
6 - Le contrôleur demande à un vue de s'exécuter, afin de présenter des
données à l'utilisateur et recueillir ses futures demandes.
C. Création de l'application MVC
C.1. Création du projet ASP.NET MVC
Après avoir lancé Visual Studio 2010, créons un nouveau projet de type
Application ASP .NET MVC.
Après avoir cliqué sur le bouton OK, la fenêtre suivante apparaît :
Page 4 sur 41
Développement d'une application Web avec ASP .NET MVC
Livre Visual Studio 2010 aux éditions ENI par James Ravaille et Julien Dollon
Cette fenêtre propose de créer un projet de test, permettant de tester notre
application ASP .NET MVC au fur et à mesure de son développement. Nous
refusons cette proposition et cliquons sur le bouton OK. Dans l'explorateur de
solutions de Visual Studio, nous observons la présence d'un ensemble de
répertoires et de fichiers :
Page 5 sur 41
Développement d'une application Web avec ASP .NET MVC
Livre Visual Studio 2010 aux éditions ENI par James Ravaille et Julien Dollon
Notre application ASP .NET MVC possède une structure particulière, que nous
allons devoir respecter. Elle est constituée :
• D'un répertoire Content, qui contiendra les éléments graphiques et de
présentation de notre application : feuilles de styles CSS et XSLT, images...
• D'un répertoire Controllers, qui contiendra tous les contrôleurs de notre
application.
• D'un répertoire Models, qui contiendra les classes qui constituent le modèle de
l'application ASP.NET MVC. Dans notre cas, le modèle est existant et
externalisé dans le projet de type bibliothèque de classes nommé
LearningCompany_DAO.
• D'un répertoire Scripts, contenant les scripts JavaScript de l'application. Par
défaut, ce répertoire contient les fichiers JavaScript composant les
Frameworks JQuery et Ajax spécifiques pour ASP .NET MVC.
• Le fichier global.asax définit le routage par défaut de notre application. Il s'agit
d'un concept déjà présent dans la version 3.5 du Framework .NET. Dans les
applications ASP .NET MVC, Microsoft l'utilise pour permettre d'exécuter une
Page 6 sur 41
Développement d'une application Web avec ASP .NET MVC
Livre Visual Studio 2010 aux éditions ENI par James Ravaille et Julien Dollon
action d'un contrôleur à partir d'une URL. Il est aussi possible de personnaliser
le routage en définissant ses propres règles. Par exemple, soit l'URL suivante :
http://www.monsite.fr/UnControleur/UneAction/UnParametre. Pour définir une
route correspondant à cette URL, nous ajoutons le bloc de code suivant la
méthode RegisterRoutes du fichier Global.asax, où routes est le paramètre de
cette méthode de type RouteCollection.
routes.MapRoute(
"NomRoute",
"UnControleur/UneAction/{UnParametre}",
new { // valeurs par défaut
UnControleur = "Formation",
UneAction = "Gestion",
UnParametre = ""
}
);
• D'un répertoire Views, contenant toutes les vues. Lors de leur création, nous
auront l'occasion de définir les caractéristiques suivantes :
Le type de la vues (!!! Revoir les noms !!!) : vues pages (pages ASP .NET à
part entière), vues de contenu (pages s'exécutant au sein d'une Master
Page) et vues partielles (aussi appelée vues contrôles utilisateurs Web).
S'il s'agit d'une vue typée ou non typée. Une vue typée permet de gérer un
objet ou une collection d'objets d'un type particulier, par exemple un type du
modèle de l'application.
Le mode de gestion, permettant de définir le comportement de la vue en
fonction de son rôle : "List" pour afficher le contenu d'une collection d'objets,
"Detail" pour consulter l'ensemble des propriétés d'un objet, "Edit" pour
modifier l'ensemble des propriétés d'un objet, …
Le répertoire Views contient un répertoire Shared, dont le rôle est particulier au
sein de l'application. Comme son nom l'indique, il contient des vues qui
partagées entre tous les contrôleurs de l'application. Lorsqu'un contrôleur
souhaite exécuter une vue, le process de recherche d'une vue est le suivant :
• La vue (page ou contrôle utilisateur) est d'abord recherchée dans le répertoire
~/Views/<nomControleur>, où le nom du contrôleur est celui du contrôleur
ayant demandé l'exécution de la vue.
• Si cette vue n'est pas trouvée, alors elle est recherchée dans le répertoire
~/Views/Shared.
C.2. Préparation de l'application
Le projet créé contient des fichiers que nous pouvons utiliser comme modèle
pour accélérer le développement de notre application. Nous allons préparer notre
projet, en supprimant les fichiers que nous n'utiliserons pas, et en indiquant ceux
dont nous modifierons le contenu. Dans la copie-écran présentée ci-dessous, les
Page 7 sur 41
Développement d'une application Web avec ASP .NET MVC
Livre Visual Studio 2010 aux éditions ENI par James Ravaille et Julien Dollon
fichiers encadrés en rouge sont ceux que nous supprimons, et les fichiers
encadrés en vert sont ceux que nous modifierons :
Ce projet va s'appuyer sur notre composant d'accès aux données
LearningCompany_DAO, afin de pour lire et modifier les données de la base de
données LearningCompany.
Page 8 sur 41
Développement d'une application Web avec ASP .NET MVC
Livre Visual Studio 2010 aux éditions ENI par James Ravaille et Julien Dollon
Pour cette raison, nous ajoutons deux références dans notre projet, référençant
les composants suivants :
• LearningCompany.dll.
• System.Data.Entity.dll. Il s'agit d'un composant du Framework .NET,
permettant de pouvoir manipuler les entités exposées par notre composant
d'accès aux données dans notre application.
Pour le bon fonctionnement de notre composant d'accès aux données, nous
devons définir dans le fichier de configuration de notre application ASP .NET
MVC, la chaîne de connexion qu'il utilise. Conformément à ses spécifications (!!!
A REVOIR, le contenu aussi !!!), il est elle doit être identifiée par le nom
"CS_DataBase" :
<connectionStrings>
<add name="CS_DataBase"
connectionString="metadata=res://*/LearningCompany.csdl|res://*/L
earningCompany.ssdl|res://*/LearningCompany.msl;provider=System.D
ata.SqlClient;provider connection string=&quot;Data
Source=localhost\sql2008;Initial Catalog=LearningCompany;Persist
Security Info=True;User
ID=userTest;Password=passwd;MultipleActiveResultSets=True&quot;"
providerName="System.Data.EntityClient"/>
</connectionStrings>
C.3. Création de l'application
C.3.a. Structure de l'application
Voici la structure de l'application que nous allons réaliser :
Page 9 sur 41
Développement d'une application Web avec ASP .NET MVC
Livre Visual Studio 2010 aux éditions ENI par James Ravaille et Julien Dollon
Ce design est composé de trois zones distinctes :
• Une zone "bandeau" contenant une présentation du centre de formation, et
permettant à un utilisateur de se connecter afin de pouvoir utiliser des
fonctionnalités avancées, de se déconnecter, et de modifier les informations le
concernant.
• Une zone "fonctionnalités" permettant
fonctionnalités de l'application, à savoir :
d'accéder
Accéder à la liste des formations par thème.
Rechercher une formation à partir d'un libellé.
à
l'ensemble
des
• Une zone "corps" affichant le contenu principal de la page, résultant des
fonctionnalités, ou d'une action même au sein du corps.
Pour implémenter cette structure, nous utiliserons une Page Maître, qui
contiendra des panneaux (contrôle de type ContentPlaceHolder), dont le contenu
du corps sera fourni lors de l'exécution des pages de contenu de l'application.
Par défaut, notre application contient déjà une Page Maître, dont le nom est
Site.Master, et contenue dans le répertoire /Views/Shared de l'application ASP
.NET MVC. Nous modifions le code XHTML de cette page, de manière à créer
trois divisions où chaque division correspond à une zone décrite ci-dessus :
<body>
<form runat="server">
<div id="Bandeau">
</div>
<div id="Fonctionnalites">
</div>
Page 10 sur 41
Développement d'une application Web avec ASP .NET MVC
Livre Visual Studio 2010 aux éditions ENI par James Ravaille et Julien Dollon
<div id="Corps">
<asp:ContentPlaceHolder ID="MainContent"
runat="server" />
</div>
</form>
</body>
Nous modifions aussi la feuille de style Site.css, afin de positionner et mettre en
forme ces divisions :
/********************************************************
*** Général.
********************************************************/
*
{
padding:0px;
margin:0px;
}
/********************************************************
*** Zones de la Master Page.
********************************************************/
#Bandeau
{
width:1000px;
height:70px;
background-color:#e7e7d9;
}
#Fonctionnalites
{
width:200px;
height:800px;
background-color:#bcb7ff;
position:relative;
float:left;
padding:5px;
}
#Corps
{
width:750px;
padding:5px;
position:relative;
float:left;
}
/********************************************************
*** Liste de puces.
********************************************************/
ul
{
padding-left:20px;
}
/********************************************************
*** Sélecteurs d'éléments.
********************************************************/
h1
{
Page 11 sur 41
Développement d'une application Web avec ASP .NET MVC
Livre Visual Studio 2010 aux éditions ENI par James Ravaille et Julien Dollon
padding-bottom:25px;
text-align:center;
}
h2
{
margin-bottom:16px;
text-align:center;
}
/********************************************************
*** Alignements.
********************************************************/
.CentrerConteneur
{
margin-left: auto;
margin-right: auto;
}
Lors de l'exécution de la page de contenu WelCom.aspx, nous obtenons le
résultat suivant :
C.3.b. Réalisation du bandeau
Le bandeau de notre application doit permettre à tout client de s'authentifier, afin
de pouvoir modifier les informations le contenant ou pouvoir effectuer une
demande d'informations complémentaire sur une formation (proposition de dates,
formateur dispensant la formation, …). Pour ce faire, nous ajoutons dans le
Page 12 sur 41
Développement d'une application Web avec ASP .NET MVC
Livre Visual Studio 2010 aux éditions ENI par James Ravaille et Julien Dollon
bandeau un lien hypertexte permettant de se connecter. Dès que l'utilisateur est
connecté, alors le texte du lien doit être modifié, afin de l'inviter à se déconnecter,
et un nouveau lien hypertexte intitulé "Mon compte" apparaît afin de lui permet de
modifier les informations le concernant.
Pour un utilisateur non connecté, le bandeau aura l'apparence suivante :
Dans le cas inverse, l'utilisateur connecté verra le bandeau suivant :
Nous aborderons l'implémentation de cette interface une fois que nous aurons
implémenté la sécurité dans notre application.
C.3.c. Réalisation de la zone des fonctionnalités
Voici le design de la zone des fonctionnalités :
La zone du libellé peut contenir tout ou partie d'un libellé d'une formation.
Lorsque l'utilisateur clique sur le bouton intitulé "OK", alors la liste des formations
correspondant dont le libellé contient le libellée recherché apparaissent dans le
corps. Par exemple, si nous recherchons les formations contenant la chaîne de
caractères "2007", le résultat suivant apparaît :
Page 13 sur 41
Développement d'une application Web avec ASP .NET MVC
Livre Visual Studio 2010 aux éditions ENI par James Ravaille et Julien Dollon
Il en va de même si nous cliquons sur un thème, excepté que les formations
affichées sont celles lui appartenant.
C.4. Identification d'un client
C.4.a. Mise en œuvre du service de gestion de la sécurité dans ASP
.NET
Avant de pouvoir déterminer quelles fonctionnalités de l'application auxquelles un
client peut accéder, nous devons l'identifier au travers d'une fenêtre de
connexion, dans laquelle il sera invité à saisir sa référence client et son mot de
passe :
En cas d'échec de l'identification, un message doit apparaître signalant que la
référence client ou le mot de passe est incorrect.
Pour implémenter l'identification des utilisateurs dans notre application, nous
utiliserons le service d'authentification proposé par ASP .NET. Ce service peut
être mis en œuvre avec un faible effort de développement. Il est possible de
l'utiliser avec une base de données SQL Server proposée par Microsoft avec un
schéma prédéfini, que nous pouvons créer avec l'outil aspnet_regsql (soit en
ligne de commande, soit via un assistant graphique). Le Framework .NET fournit
un provider nommé AspnetMembershipProvider permettant à ce service d'utiliser
cette base de données. Il est aussi possible de définir notre propre base de
données avec notre propre schéma. Ce sera le cas dans notre application. Pour
ce faire, nous commercerons par créer un provider personnalisé permettant au
service d'authentification d'utiliser notre base de données. Le schéma ci-dessous
explicite le fonctionnement de ce service :
Page 14 sur 41
Développement d'une application Web avec ASP .NET MVC
Livre Visual Studio 2010 aux éditions ENI par James Ravaille et Julien Dollon
La source de données sera la base de données de l'application. Le composant
permettant d'accéder et gérer les données sera le composant
LearningCompany_DAO. Etant donné que nous souhaitons authentifier les
clients du centre de formation, l'entité utilisée au sein de ce composant d'accès
aux données sera l'entité Client. Pour que le service de gestion de la sécurité
puisse utiliser cette entité, nous devons créer un provider personnalisé, que nous
déclarerons dans le fichier de configuration de l'application ASP.NET.
C.4.b. Création du provider personnalisé
Dans notre application ASP .NET MVC, nous créons un répertoire nommé
Securite. Dans ce répertoire, nous créons une classe nommée
OffreFormationMembershipProvider,
qui
spécialise
la
classe
System.Web.Security.MembershipProvider du Framework .NET. Il s'agit d'une
classe abstraite que toute classe constituant un provider personnalisé
d'authentification doit hériter, et redéfinir les méthodes abstraites de cette classe.
Pour les besoins de notre application nous redéfinirons uniquement la méthode
ValidateUser, qui permet de savoir si une référence client et un mot de passe
correspondent à un client enregistré dans notre base de données. Dans
l'implémentation de cette méthode, nous utiliserons la méthode statique
GetInstance de la classe Client. Si elle retourne un objet de type Client, alors
cette méthode retournera la méthode true. Si elle retourne la valeur null, alors
cette méthode retournera la méthode false.
Page 15 sur 41
Développement d'une application Web avec ASP .NET MVC
Livre Visual Studio 2010 aux éditions ENI par James Ravaille et Julien Dollon
using
using
using
using
System;
System.Collections.Generic;
System.Linq;
System.Web;
using System.Web.Security;
using LearningCompany_DAO;
namespace LearningCompany_OffreFormations.Securite
{
public class OffreFormationMembershipProvider :
MembershipProvider
{
// Autres méthodes abstraites...
public override bool ValidateUser(string aReference,
string aMotDePasse)
{
return Client.GetInstance(aReference, aMotDePasse) !=
null;
}
}
}
Chacune des méthodes abstraites jouent un rôle particulier. Pour compléter cette
classe vous devrez implémenter celles qui correspondent aux fonctionnalités du
service d'authentification ASP .NET que vous souhaitez utiliser.
C.4.c. Authentification d'un utilisateur et vérification des
autorisations
Voici un schéma présentant le processus d'identification d'un utilisateur
souhaitant exécutée une page ASP .NET sécurisée :
Page 16 sur 41
Développement d'une application Web avec ASP .NET MVC
Livre Visual Studio 2010 aux éditions ENI par James Ravaille et Julien Dollon
Un utilisateur demande l'accès à une page de l'application, en envoyant une
requête HTTP au travers d'un navigateur Web. Le processus d'authentification
commence. Il vérifie si la requête HTTP contient des preuves d'authentification
(connues sous le nom de credentials en anglais), permettant d'identifier
l'utilisateur ayant envoyée la requête. Si ces preuves ne sont pas trouvées ou
insatisfaisantes, alors l'utilisateur est automatiquement rediriger vers la page
d'identification. On remarque dans la barre d'adresse du navigateur la présence
du paramètre nommé ReturnUrl, contenant l'URL de la page vers laquelle
l'utilisateur doit être redirigé si l'identification réussie et si les autorisations sont
satisfaisantes. Tant que l'utilisateur ne saisit pas une référence client et un mot
de passe correct, il reste sur la page d'identification. Dès qu'il saisit des
informations correctes, le processus ASP .NET ajoute un cookie d'identification
crypté à la réponse HTTP qui sera faite au client (action par défaut, qu'il est
possible de paramétrer. Puis il vérifie que le compte identifié possède les
autorisations nécessaires pour accéder à la page demande. Si c'est le cas, alors
la page initialement demandée est exécutée, et le résultat de l'exécution est
renvoyé au client. Le cas échéant, il est automatiquement renvoyé vers la même
page d'identification.
Lors de l'envoi des requêtes HTTP suivantes, le cookie d'identification est
automatiquement attaché à la requête, afin que le serveur IIS puisse authentifier
l'utilisateur.
C.4.d. Enregistrement du provider personnalisé
Pour que le service d'authentification puisse utiliser le provider que nous avons
défini, nous devons l'enregistrer dans le fichier de configuration de l'application
ASP .NET MVC. Dans ce fichier, nous nous positionnons sous l'élément
System.Web et ajoutons les éléments XML suivants :
<membership defaultProvider="CustomMembershipProvider">
<providers>
<clear/>
<add name="CustomMembershipProvider"
type="LearningCompany_OffreFormations.Securite.OffreFormationMemb
ershipProvider" />
</providers>
</membership>
Ces éléments XML permettent de déclarer une instance de notre provider
OffreFormationMembershipProvider,
que
nous
nommons
CustomMembershipProvider.
C.4.e. Définition du type d'authentification
Pour utiliser le service de sécurité, toujours dans l'élément System.Web, nous
ajoutons les lignes suivantes :
<authentication mode="Forms">
Page 17 sur 41
Développement d'une application Web avec ASP .NET MVC
Livre Visual Studio 2010 aux éditions ENI par James Ravaille et Julien Dollon
<forms loginUrl="~/Connexion/Connecter" />
</authentication>
Ces lignes permettent de déclarer que nous utilisons l'authentification par
formulaire, ainsi que le l'URL permettant d'accéder au formulaire de connexion.
Cette URL est constituée du nom d'un contrôleur (Connexion) et d'une action
(Connecter). Nous détaillerons cette écriture d'URL ultérieurement dans ce
chapitre.
C.4.f. Connexion / déconnection des utilisateurs
De manière à pouvoir enregistrer un client identifié et déconnecter un client, nous
ajoutons dans le répertoire Securite de notre application, une classe que nous
nommons FormsAuthenticationService. L'implémentation de cette classe est la
suivante :
public class FormsAuthenticationService
{
public void Connecter(string aReference, bool
createPersistentCookie)
{
FormsAuthentication.SetAuthCookie(aReference,
createPersistentCookie);
}
public void Deconnecter()
{
FormsAuthentication.SignOut();
}
}
Le rôle de cette classe est d'assurer, au sein de notre application, un couplage
faible entre le service d'authentification ASP .NET et les pages et contrôles
utilisateurs qui l'utiliseront. Autrement dit, si nous utilisons un autre mécanisme
d'authentification pour nos utilisateurs, nous limitons les modifications à apporter
dans le code de l'application. Elle contient deux méthodes permettant de piloter
le service d'authentification ASP .NET :
• La méthode Connecter permet de créer un cookie d'identification crypté qui
sera automatiquement associé à la réponse renvoyée à l'utilisateur. Pour ce
faire, nous appliquons la méthode statique SetAuthCookie de la classe
FormsAuthentication, en lui fournissant la référence client permettant
d'identifier le client connecté, et une valeur booléenne indiquant si le cookie est
persistant (cookie utilisable par un même client au travers de différentes
sessions ASP .NET).
• La méthode Deconnecter permet de déconnecter un utilisateur, en supprimant
le cookie d'identification de la réponse renvoyée à l'utilisateur. Si l'utilisateur
renvoie une nouvelle requête HTTP, il sera automatiquement redirigé vers la
page d'authentification précédemment défini dans le fichier de configuration.
Page 18 sur 41
Développement d'une application Web avec ASP .NET MVC
Livre Visual Studio 2010 aux éditions ENI par James Ravaille et Julien Dollon
C.4.g. Identification d'un utilisateur
Dans le répertoire Securite, nous ajoutons une classe nommée
ClientMembershipService. L'implémentation de cette classe est la suivante :
public class ClientMembershipService
{
private MembershipProvider Provider
{
get;
set;
}
public ClientMembershipService()
{
Provider = Membership.Provider;
}
public bool CompteExiste(string aReference, string
aMotDePasse)
{
return Provider.ValidateUser(aReference, aMotDePasse);
}
}
Cette classe définit une propriété simplifiée nommé Provider, qui doit contenir
une instance du provider créé par le service d'authentification ASP.NET, à partir
des informations du provider Membership défini dans le fichier de configuration.
Pour ce faire nous ajoutons un constructeur, qui initialise cette propriété via la
propriété statique Provider de la classe System.Web.Security.Membership.
Pour déterminer si un client existe dans notre base de données à partir d'une
référence client et d'un mot de passe, nous créons une méthode acceptant en
paramètre ces informations et retournant une valeur booléenne. Dans cette
méthode nous exécutons la méthode ValidateUser sur la propriété Provider.
Cette instruction permet d'exécuter la méthode de même nom de notre provider
personnalisé. Ainsi dans cette méthode, retourne la valeur true si un client a été
trouvé à partir de la référence et du mot de passe passé en paramètre, et false le
cas échéant.
C.4.h. Gestion des autorisations
Une fois notre mécanisme d'authentification implémenté dans notre application,
nous devons gérer les autorisations. Nous souhaitons que les utilisateurs soient
authentifiés pour exécuter toutes les actions du contrôleur Client et l'action
DemanderInfos du contrôleur Formation. Pour ce faire, nous appliquons la
métadonnée System.Web.Mvc.AuthorizeAttribute au contrôleur Client et à
l'action DemanderInfos du contrôleur Formation. Cette métadonnée, appliquée à
un contrôleur, permet de s'assurer que tous les utilisateurs qui demandent
l'exécution d'une action lui appartenant doivent être authentifiés. Appliqué à une
action, cette règle s'applique uniquement sur l'action.
=> Plus d'actualité. A changer (juste une possibilité).
Page 19 sur 41
Développement d'une application Web avec ASP .NET MVC
Livre Visual Studio 2010 aux éditions ENI par James Ravaille et Julien Dollon
C.4.i. Connexion / déconnection d'un utilisateur
Dans le bandeau de l'application, le lien hypertexte permettant initialement de
s'identifier est un lien à deux états. Un premier état permet à l'utilisateur de
s'identifier ne l'est pas. Un second état permettant de demander à se
déconnecter, le lien affichant le libellé Deconnexion.
Lors de l'évolution de l'application, ce lien hypertexte peut être utilisé dans
différentes pages, tout en conservant le même comportement. Afin d'implémenter
une seule fois ce comportement dans notre application, nous ajoutons dans le
répertoire ~/Views/Shared, un contrôle utilisateur MVC, que nous nommons
AccesConnexion.ascx. Le code contenu dans ce contrôle présenté ci-dessous
implémente cette fonctionnalité :
<%@ Control Language="C#"
Inherits="System.Web.Mvc.ViewUserControl" %>
<%
if (Request.IsAuthenticated) {
%>
<%= Html.ActionLink("Déconnexion", "Deconnecter",
"Connexion")%>
<%
}
else {
%>
<%= Html.ActionLink("Connexion", "Connecter",
"Connexion")%>
<%
}
%>
La méthode ActionLink de l'objet Html (qui est une propriété héritée) génère un
lien hypertexte, qui permet d'exécuter une action d'un contrôleur. Dans notre
code, si l'utilisateur n'est pas authentifié, alors un lien hypertexte affichant le
libellé Déconnexion et permettant d'exécuter l'action Deconnecter du contrôleur
Connexion est affiché. Le cas échéant, un lien hypertexte affichant le libellé
Connexion et permettant d'exécuter l'action Connecter du contrôleur Connexion
est affiché.
Pour utiliser ce contrôle dans le bandeau de l'application, nous affichons le code
de la Master Page MVC Site.master, et nous positionnons dans la division
correspondant au bandeau. Nous ajoutons alors le bloc de code suivant :
<p>
<% Html.RenderPartial("AccesConnexion"); %>
</p>
Ce bloc de code permet d'injecter dans la page maître le rendu du contrôle
AccesConnexion.ascx lors de l'exécution de la page maître.
Page 20 sur 41
Développement d'une application Web avec ASP .NET MVC
Livre Visual Studio 2010 aux éditions ENI par James Ravaille et Julien Dollon
D. Création des contrôleurs et des vues
D.1. Présentation des contrôleurs
Notre application sera constituée des contrôleurs suivants :
• Home : contrôleur par défaut de l'application, il permet au travers de son action
Index, d'accéder à la page d'accueil de l'application ~/Home/Index.aspx.
• Client : permet d'agir sur un client, à savoir pouvoir afficher les informations le
concernant et les modifier.
• Formation : permet de pouvoir accéder à un ensemble de formations,
notamment lors de l'exécution des fonctionnalités de recherche des
formations, et de fournir des informations les concernant.
• Connexion : permet de gérer la connexion / déconnexion d'un utilisateur, en
utilisant le service d'authentification ASP .NET.
Voici un schéma indiquant les interactions entre les vues et les contrôleurs de
notre application :
D.2. Implémentation du contrôleur Home
Page 21 sur 41
Développement d'une application Web avec ASP .NET MVC
Livre Visual Studio 2010 aux éditions ENI par James Ravaille et Julien Dollon
Contenu dans le répertoire Controllers de l'application, le contrôleur Home est le
contrôleur par défaut de notre application. Il est créé en même temps que
l'application et est implémenté par la classe HomeController. Dans une
application ASP .NET MVC, toute classe contrôleur est suffixée par Controller, et
dérive de la classe System.Web.Mvc.Controller du Framework .NET. Il en sera
de même pour tous les contrôleurs que nous créerons dans notre application.
D.2.a. Implémentation de l'action Index()
L'action Index est l'action par défaut de ce contrôleur, autrement dit qu'elle est
exécutée si une route demande l'exécution du contrôleur Home sans préciser de
contrôleur. Son rôle est de retourner la vue qui lui est affectée :
[HandleError]
public class HomeController : Controller
{
public ActionResult Index()
{
return View();
}
}
La métadonnée HandleError positionnée sur le contrôleur est utilisée pour
faciliter la gestion des erreurs dans les contrôleurs.
Cette action redirige l'utilisateur vers la vue ~/Views/Home/Index.aspx. Cette vue
affiche un message de bienvenue :
<%@ Page Language="C#"
MasterPageFile="~/Views/Shared/Site.Master"
Inherits="System.Web.Mvc.ViewPage" %>
<asp:Content ID="indexTitle" ContentPlaceHolderID="TitleContent"
runat="server">
LearningCompany - Présentation
</asp:Content>
<asp:Content ID="indexContent" ContentPlaceHolderID="MainContent"
runat="server">
<h2>Bienvenue chez Learning Company</h2>
<p>
Veuillez rechercher des formations via leur libellé ou
leur référence, ou cliquer sur un thème dans la liste ci-contre.
</p>
</asp:Content>
En exécutant l'URL http://localhost:xxxx/, nous obtenons le résultat suivant (nous
n'afficherons que le corps de la page) :
Page 22 sur 41
Développement d'une application Web avec ASP .NET MVC
Livre Visual Studio 2010 aux éditions ENI par James Ravaille et Julien Dollon
Cette action sur ce contrôleur est exécutée par défaut, en vertu de la route
définie dans le fichier global.asax (!!! A revoir !!!).
D.2.b. Implémentation de l'action ErreurDonnees()
Lors de la gestion des données, des erreurs de données peuvent se produire.
Par exemple, nous pouvons modifier une donnée qui a été supprimée par un
autre utilisateur. Dès qu'une erreur de donnée se produira, nous nous
contenterons de rediriger l'utilisateur vers une page lui indiquant que l'action
demandée n'est pas possible. Cette implémentation est la suivante :
public ActionResult ErreurDonnees()
{
return View();
}
Puis pour associer une vue à ce contrôle, nous affichons le menu contextuel au
sein de cette action, et nous cliquons sur l'élément "Ajouter une vue…". La
fenêtre suivante apparaît :
Page 23 sur 41
Développement d'une application Web avec ASP .NET MVC
Livre Visual Studio 2010 aux éditions ENI par James Ravaille et Julien Dollon
Nous créons une simple vue, qui est une page de contenu non fortement typée.
Après avoir cliqué sur le bouton "Ajouter", une page ASP .NET MVC nommée
ErreurDonnees.aspx
est
créée
dans
le
répertoire
~/Views/Home.
L'implémentation de cette page est la suivante :
<%@ Page Title="" Language="C#"
MasterPageFile="~/Views/Shared/Site.Master"
Inherits="System.Web.Mvc.ViewPage" %>
<asp:Content ID="Content1" ContentPlaceHolderID="TitleContent"
runat="server">
Erreur de données
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent"
runat="server">
<h2>Erreur de données</h2>
<p>Une erreur de données s'est produite.</p>
</asp:Content>
D.3. Création du contrôleur Connexion
Dans le répertoire Controllers de notre application, nous ajoutons un répertoire
nommé Securite, dans lequel nous créons un contrôleur nommé Connexion :
Dans la classe obtenue, nous supprimons toutes les actions existant par défaut.
D.3.a. L'action Connecter ()
Le contrôleur Connexion permet à l'application ASP .NET de pour gérer la
sécurité de l'application au travers du service d'authentification ASP .NET. Nous
allons commencer par définir deux propriétés simplifiées :
Page 24 sur 41
Développement d'une application Web avec ASP .NET MVC
Livre Visual Studio 2010 aux éditions ENI par James Ravaille et Julien Dollon
• Une
première
propriété,
nommée
FormsAuth
et
de
type
FormsAuthenticationService, permettant de pouvoir connecter / déconnecter
un utilisateur.
• Une seconde propriété, nommée MembershipService et de type
ClientMembershipService, permettant de déterminer si les informations
fournies par l'utilisateur au travers du formulaire de connexion correspondent à
un client enregistré dans la base de données de l'application.
private FormsAuthenticationService FormsAuth
{
get;
set;
}
private ClientMembershipService MembershipService
{
get;
set;
}
Nous initialisons ces deux propriétés dans un constructeur que nous créons :
public ConnexionController()
{
this.FormsAuth = new FormsAuthenticationService();
this.MembershipService = new ClientMembershipService();
}
Nous ajoutons une action nommée Connecter permettant de rediriger l'utilisateur
vers la vue lui permettant de s'identifier :
public ActionResult Connecter()
{
return View();
}
Nous créons la vue associée à cette action. Cette vue est une vue de contenu,
qui n'est pas fortement typée et ne définit pas un mode de gestion particulier
d'une connexion. L'implémentation de cette vue est la suivante :
<%@ Page Title="" Language="C#"
MasterPageFile="~/Views/Shared/Site.Master"
Inherits="System.Web.Mvc.ViewPage" %>
<asp:Content ID="Content1" ContentPlaceHolderID="TitleContent"
runat="server">
Connecter
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent"
runat="server">
<h2>Connexion</h2>
Page 25 sur 41
Développement d'une application Web avec ASP .NET MVC
Livre Visual Studio 2010 aux éditions ENI par James Ravaille et Julien Dollon
<%= Html.ValidationSummary("", new { style = "width:100%;
text-align:center; margin-top:25px; " })%>
<% using (Html.BeginForm())
{ %>
<table style="width:400px; margin-top:50px;"
class="CentrerConteneur">
<tr>
<td>
<label for="Reference">Référence :</label>
</td>
<td>
<%= Html.TextBox("Reference") %>
</td>
</tr>
<tr>
<td>
<label for="MotDePasse">Mot de passe
:</label>
</td>
<td>
<%= Html.Password("MotDePasse")%>
</td>
</tr>
<tr>
<td colspan="2" style="text-align:center; ">
<input type="submit" value="Valider" />
</td>
</tr>
</table>
<% } %>
</asp:Content>
Pour valider les informations saisies par l'utilisateur, nous devons ajouter dans le
contrôleur Connexion une action dont le nom est Connecter, mais exécutable en
mode HTTP POST.
D.3.b. L'action Connecter (string, string)
Cette action permet de vérifier qu'un compte client existe à partir de la référence
client et du mot de passe saisie par l'utilisateur. Si tel est le cas, alors nous
marquons cet utilisateur comme authentifier et redirigeons l'utilisateur vers la
page de présentation de l'application, en demandant à exécuter l'action Index du
contrôle Home. Le cas échéant, nous restons sur cette même de connexion et
affichons le message " Référence ou mot de passe incorrect.".
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Connecter(string Reference, string
MotDePasse)
{
bool bClientExiste;
ActionResult oActionResult = this.View();
bClientExiste = MembershipService.CompteExiste(Reference,
MotDePasse);
if (bClientExiste)
{
FormsAuth.Connecter(Reference, false);
Page 26 sur 41
Développement d'une application Web avec ASP .NET MVC
Livre Visual Studio 2010 aux éditions ENI par James Ravaille et Julien Dollon
oActionResult = this.RedirectToAction("Index", "Home");
}
else
{
ModelState.AddModelError("_FORM", "Référence ou mot de
passe incorrect.");
}
return oActionResult;
}
D.3.c. L'action Deconnecter ()
Cette action permet à tout utilisateur de se déconnecter, afin de ne plus être
identifié par l'application. Une fois cette action réalisée, nous redirigeons
l'utilisateur vers la page de présentation de l'application, en demandant à
exécuter l'action Index du contrôle Home :
public ActionResult Deconnecter()
{
FormsAuth.Deconnecter();
return RedirectToAction("Index", "Home");
}
D.4. Création du contrôleur Client
Dans le répertoire Controllers de notre application, nous ajoutons un répertoire
nommé Clients, dans lequel nous ajoutons un contrôleur nommé Client :
Ce contrôleur permet de gérer les différentes actions effectuées sur les clients,
répondant aux besoins de notre application. Pour ce faire, nous définirons dans
ce contrôleur trois actions : Edit (mode http Get), Edit (mode Post) et EndEdit.
D.4.a. Création de l'action Edit ()
Page 27 sur 41
Développement d'une application Web avec ASP .NET MVC
Livre Visual Studio 2010 aux éditions ENI par James Ravaille et Julien Dollon
Cette action permet d'afficher les informations du client identifié, afin qu'il puisse
les modifier. Cette action pourra être exécutée au travers d'une requête HTTP
Get. Le client identifié est obtenu via la référence client contenu dans la propriété
Name de l'objet User.Identity. Pour ce faire, il charge les informations concernant
le client en mémoire, et les transmet à la vue à laquelle il sera associé.
public ActionResult Edit()
{
Client oClient;
oClient = Client.GetInstance(User.Identity.Name);
return View(oClient);
}
Pour créer une vue à partir de cette action, nous affichons le menu contextuel
dans son implémentation, et cliquons sur l'élément Ajouter une vue (!!!A
REVOIR!!!). La fenêtre suivante apparaît :
Pour faciliter la correspondance entre l'action et la vue, le nom de la vue doit
avoir le même nom que l'action, afin. Cette vue doit permet de modifier les
informations concernant le client identifié. Nous décidons de créer une vue
fortement typée en cliquant sur la case à cocher Créer une vue fortement typée
(!!!A REVOIR!!!), en choisissant la classe LeanongCompany_DAO.Client dans la
Page 28 sur 41
Développement d'une application Web avec ASP .NET MVC
Livre Visual Studio 2010 aux éditions ENI par James Ravaille et Julien Dollon
liste des types de données pour les vues, et le mode Edit comme contenu de la
vue. Aussi cette vue doit être une vue de contenu, dans le sens où son contenu
doit venir alimenter la Master Page de l'application. Cette vue contiendra alors un
contrôle Content, qui référencera le contrôle ContentPlaceHolder nommé
MainContent de la Master page Site.Master.
Après avoir cliqué sur le bouton Ajouter, le fichier Edit.aspx est créé dans le
répertoire ~/Views/Client, où Client correspond au nom du contrôleur l'ayant créé.
Nous appliquons à ce fichier les modifications suivantes :
• Nous modifions le titre de la page et du formulaire.
• Pour des raisons esthétiques, nous supprimons le fieldset contenant
l'ensemble des informations du client, et définissons du code CSS pour mettre
en forme les libellés, que nous renommons.
• Nous supprimons le code permettant de modifier l'identifiant et la référence du
client.
• Nous modifions le paramètre de l'instruction Html.ValidationSummary, en
spécifiant le libellé "Modification non enregistrées".
• Nous modifions le libelle du bouton permettant d'enregistrer ces informations
en modifiant la propriété value du contrôle input de type submit à Enregistrer.
• Nous supprimons le lien hypertext au bas de la page permettant d'accéder à la
liste des clients (sans objet dans notre application car cette liste n'existe pas).
• Enfin, définissons une largeur pour chacun des champs.
Nous obtenons ainsi le code de la vue suivante :
<%@ Page Title="" Language="C#"
MasterPageFile="~/Views/Shared/Site.Master"
Inherits="System.Web.Mvc.ViewPage<LearningCompany_DAO.Client>" %>
<asp:Content ID="Content1" ContentPlaceHolderID="TitleContent"
runat="server">
Fiche Client
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent"
runat="server">
<style type="text/css">
p label {
float: left;
width: 150px;
text-align: left;
padding: 0 0.5 0 0;
font-weight: bold;
}
</style>
<h2>Fiche Client</h2>
<%= Html.ValidationSummary("Modification non
enregistrées.")%>
<% using (Html.BeginForm()) {%>
<p style="margin-top:15px;">
<label for="RaisonSociale">Raison Sociale :</label>
Page 29 sur 41
Développement d'une application Web avec ASP .NET MVC
Livre Visual Studio 2010 aux éditions ENI par James Ravaille et Julien Dollon
<%= Html.TextBox("RaisonSociale",
Model.RaisonSociale, new {style = "width:300px; " })%>
<%= Html.ValidationMessage("RaisonSociale", "*") %>
</p>
<p style="margin-top:15px;">
<label for="Adresse">Adresse :</label>
<%= Html.TextBox("Adresse", Model.Adresse, new {
style = "width:500px; " })%>
<%= Html.ValidationMessage("Adresse", "*") %>
</p>
<p style="margin-top:15px;">
<label for="CodePostal">Code postal :</label>
<%= Html.TextBox("CodePostal", Model.CodePostal, new
{ style = "width:50px; " })%>
<%= Html.ValidationMessage("CodePostal", "*") %>
</p>
<p style="margin-top:15px;">
<label for="Ville">Ville :</label>
<%= Html.TextBox("Ville", Model.Ville, new { style =
"width:200px; " })%>
<%= Html.ValidationMessage("Ville", "*") %>
</p>
<p style="margin-top:15px;">
<label for="Telephone">Téléphone :</label>
<%= Html.TextBox("Telephone", Model.Telephone, new {
style = "width:100px; " })%>
<%= Html.ValidationMessage("Telephone", "*") %>
</p>
<p style="margin-top:15px;">
<label for="Email">E-mail :</label>
<%= Html.TextBox("Email", Model.Email, new { style =
"width:250px; " })%>
<%= Html.ValidationMessage("Email", "*") %>
</p>
<p style="margin-top:15px;">
<label for="UrlSiteWeb">Url du site Web :</label>
<%= Html.TextBox("UrlSiteWeb", Model.UrlSiteWeb, new
{ style = "width:400px; " })%>
<%= Html.ValidationMessage("UrlSiteWeb", "*") %>
</p>
<p style="margin-top:15px;">
<label for="MotDePasse">Mot de passe :</label>
<%= Html.TextBox("MotDePasse", Model.MotDePasse, new
{ style = "width:150px; " })%>
<%= Html.ValidationMessage("MotDePasse", "*") %>
</p>
<p style="margin-top:15px;">
<input type="submit" value="Enregistrer" />
</p>
<% } %>
</asp:Content>
Détaillons ce bloc d'instructions. Pour chacun des champs de données affichés,
nous définissons un libellé, une zone de texte et du code de validation
permettant de valider les données saisies par l'utilisateur. Le libellé est défini
dans un contrôle XHTML de type Label. Les champs de saisie sont générés via
l'instruction Html.TextBox, acceptant un en paramètre l'identifiant du champ de
données, la valeur à afficher et diverses propriétés telles que le style.
La validation des données est prise en charge par l'instruction
Html.ValidateMessage(…). Elle permet d'afficher un message en lieu et place de
cette instruction si une erreur de validation est signalée lors du traitement des
données côté serveur. La méthode Html.ValidationSummary(…) affiche les
erreurs dans une liste de puces, où chaque puce indique une erreur.
Page 30 sur 41
Développement d'une application Web avec ASP .NET MVC
Livre Visual Studio 2010 aux éditions ENI par James Ravaille et Julien Dollon
Nous obtenons ainsi la vue suivante :
En cliquant sur le bouton Enregistrer, nous exécutons une action portant le
même nom que l'action ayant fournie cette vue, située dans le même contrôleur.
La particularité de cette action est qu'elle doit être appelée en mode POST, afin
de pouvoir transmettre les informations contenues dans les contrôles de saisie
du formulaire.
D.4.b. Création de l'action Edit (FormCollection collection)
Cette action permet de mettre à jour les informations concernant le client
identifié. Le client identifié est obtenu via la référence client contenu dans la
propriété Name de l'objet User.Identity. Cette action pourra être exécutée au
travers d'une requête HTTP POST. Son paramètre nommé collection permet de
lire les informations saisies par l'utilisateur dans le formulaire ayant demandé
l'exécution de cette action, pour valorisé les propriétés du client.
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Edit(string Reference, FormCollection
collection)
{
// Variables locales.
Client oClient;
ActionResult oResult;
// Chargement du client.
oClient = Client.GetInstance(Reference);
oResult = RedirectToAction("EndEdit");
if (oClient != null)
{
// Vérification des données.
if (!Regex.Match(collection["CodePostal"],
@"^\d{5}$").Success)
{
ModelState.AddModelError("CodePostal", "Format de
code postal incorrect.");
Page 31 sur 41
Développement d'une application Web avec ASP .NET MVC
Livre Visual Studio 2010 aux éditions ENI par James Ravaille et Julien Dollon
}
if (!ModelState.IsValid)
{
oResult = View(oClient);
}
else
{
// Modification de l'objet métier.
oClient.Adresse = collection["adresse"];
oClient.CodePostal = collection["CodePostal"];
oClient.Email = collection["Email"];
oClient.MotDePasse = collection["MotDePasse"];
oClient.RaisonSociale = collection["RaisonSociale"];
oClient.Telephone = collection["Telephone"];
oClient.UrlSiteWeb = collection["UrlSiteWeb"];
oClient.Ville = collection["Ville"];
// Enregistrement du client dans la base de données.
ContexteDAO.Enregistrer();
}
}
else
{
// Erreur de données.
oResult = RedirectToAction("ErreurDonnees", "Index");
}
// Retour.
return oResult;
}
Aucune vue n'est créée pour cette action. L'instruction return
RedirectToAction("EndEdit"); permet de demander l'exécution de l'action EndEdit
, lui élégant la vue à retourner à l'utilisateur. Voici l'implémentation de cette action
:
public ActionResult EndEdit()
{
return View();
}
Si le client que nous souhaitons mettre à jour n'existe plus dans la base de
données, alors déléguons la vue à retourner à l'utilisateur à l'action
ErreurDonnees du contrôleur Index.
De la même manière que précédemment, nous créons une nouvelle vue
associée à cette action. Cette vue est une page de contenu n'étant pas fortement
typée :
Page 32 sur 41
Développement d'une application Web avec ASP .NET MVC
Livre Visual Studio 2010 aux éditions ENI par James Ravaille et Julien Dollon
Cette vue est une page de contenu, non typée et sans action particulière. De
manière analogue à la création de la vue précédente, nous obtenons le bloc de
code suivant :
<%@ Page Title="" Language="C#"
MasterPageFile="~/Views/Shared/Site.Master"
Inherits="System.Web.Mvc.ViewPage<LearningCompany_DAO.Client>" %>
<asp:Content ID="Content1" ContentPlaceHolderID="TitleContent"
runat="server">
Modification de vos informations
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent"
runat="server">
<h2>Modification de vos informations</h2>
Les informations vous concernant ont été enregistrées.
</asp:Content>
Le résultat de l'exécution de cette vue est le suivant :
Page 33 sur 41
Développement d'une application Web avec ASP .NET MVC
Livre Visual Studio 2010 aux éditions ENI par James Ravaille et Julien Dollon
D.5. Création du contrôleur Formation
Dans le répertoire Controllers de notre application, nous ajoutons un répertoire
nommé Formations, dans lequel nous ajoutons un contrôleur nommé Formation :
Ce contrôleur permet de gérer les différentes actions effectuées sur les
formations proposées par le centre de formation, répondant aux besoins de notre
application. Pour ce faire, nous définirons dans ce contrôleur quatre actions,
détaillées ci-dessous.
D.5.a. Création de l'action RechercheListeFormations (string)
Cette action permet de rechercher une liste de formations, à partir d'un libellé
passé en paramètre. Le nom de ce paramètre doit avoir le même nom qu'un
champ du formulaire invoquant cette action au travers d'une requête HTTP
POST. L'implémentation de cette action est la suivante :
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult RechercheListeFormations(string TxtLibelle)
{
List<Formation> oListeFormations;
oListeFormations = Formation.GetListeInstances(TxtLibelle);
return View(oListeFormations);
}
La liste des formations trouvées sont fournies à une vue permettant d'afficher les
informations qu'elles contiennent. Nous créons cette vue de manière analogue à
la vue précédente. Cette vue doit être une page de contenu, et fortement typée
afin de pouvoir afficher une liste de formations.
Page 34 sur 41
Développement d'une application Web avec ASP .NET MVC
Livre Visual Studio 2010 aux éditions ENI par James Ravaille et Julien Dollon
Une page nommée RechercheListeFormations.apx est créée dans le répertoire
~/Views/Formation. Nous modifions son code en apportant les modifications
suivantes :
• Nous modifions le titre de la page et du formulaire.
• Dans le tableau affichant les informations sur les formations, nous supprimons
les colonnes affichant leur identifiant et leur description. Nous renommons
aussi le titre des colonnes afin de leur donner un libellé plus "fonctionnel".
Nous supprimons aussi la colonne permettant de modifier les informations
concernant une formation.
• Nous ajoutons une colonne supplémentaire, contenant un lien hypertext dont
le libellé est Détail, permettant de consulter le détail de chaque formation.
Lorsqu'un utilisateur clique sur un de ces liens, une requête HTTP de type
GET est envoyée au serveur Web, afin d'exécuter l'action Detail du contrôleur
Formation, en passant en paramètre l'identifiant de la formation visée. Pour
créer ce lien, nous utilisons la méthode ActionLink de l'objet Html.
• Nous ajoutons du code C# permettant d'afficher le message "Aucune formation
n'a été trouvée" dans le cas où aucune formation n'est fournie par le
contrôleur.
Nous obtenons ainsi le bloc de code suivant :
Page 35 sur 41
Développement d'une application Web avec ASP .NET MVC
Livre Visual Studio 2010 aux éditions ENI par James Ravaille et Julien Dollon
<%@ Page Title="" Language="C#"
MasterPageFile="~/Views/Shared/Site.Master"
Inherits="System.Web.Mvc.ViewPage<IEnumerable<LearningCompany_DAO
.Formation>>" %>
<asp:Content ID="Content1" ContentPlaceHolderID="TitleContent"
runat="server">
Liste des formations
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent"
runat="server">
<h2>Liste des formations</h2>
<% if (Model.Count() > 0)
{ %>
<table style="width:80%; " class="CentrerConteneur">
<tr>
<th></th>
<th>
Référence
</th>
<th>
Libellé
</th>
<th>
Durée
</th>
</tr>
<% foreach (var item in Model)
{ %>
<tr>
<td>
<%= Html.ActionLink("Détail", "Detail", new {
aIdentifiantFomation = item.Identifiant })%>
</td>
<td style="text-align:center; ">
<%= Html.Encode(item.Reference)%>
</td>
<td>
<%= Html.Encode(item.Libelle)%>
</td>
<td style="text-align:center; ">
<%= Html.Encode(item.NombreJours)%>
</td>
</tr>
<% } %>
</table>
<% }
else
{
Response.Write("Aucune formation n'a été trouvée.");
}
%>
</asp:Content>
Par exemple, si l'utilisateur clique sur une catégorie présente dans la zone des
fonctionnalités de l'application, la liste des formations lui appartenant sont
affichées :
Page 36 sur 41
Développement d'une application Web avec ASP .NET MVC
Livre Visual Studio 2010 aux éditions ENI par James Ravaille et Julien Dollon
D.5.b. Création de l'action RechercheListeFormations (int?)
Cette action permet d'afficher la liste des formations d'un thème, dont l'identifiant
est passé en paramètre.
public ActionResult RechercheListeFormations(int?
aIdentifiantTheme)
{
Theme oTheme;
List<Formation> oListeFormations = null;
if (aIdentifiantTheme.HasValue)
{
oTheme = Theme.GetInstance(aIdentifiantTheme.Value);
oListeFormations = oTheme.GetListeFormations();
}
return View(oListeFormations);
}
La vue retournée est la même que pour la précédente action.
D.5.c. Détail d'une formation
• Tout client, identifié ou non, peut consulter le détail d'une formation. Seuls les
clients identifiés auront la possibilité d'effectuer une demande d'informations
complémentaires, au travers d'un lien hypertext intitulé "Demander infos" :
Page 37 sur 41
Développement d'une application Web avec ASP .NET MVC
Livre Visual Studio 2010 aux éditions ENI par James Ravaille et Julien Dollon
• En cliquant sur ce lien hypertext, une demande sera enregistrée dans la base
de données, et la page suivante sera affichée :
Cette page confirme la prise de la demande d'information, fournit le nom du
commercial qui la traitera.
D.5.d. Création de l'action Detail (int?)
Cette action permet de pouvoir consulter le détail d'une formation à partir de son
identifiant. Dans le contrôleur Formation, nous ajoutons le bloc de code suivant :
public ActionResult Detail(int? aIdentifiantFomation)
{
Formation oFormation = null;
if (aIdentifiantFomation.HasValue)
{
oFormation =
Formation.GetInstance(aIdentifiantFomation.Value);
}
return View(oFormation);
}
Nous créons une vue permettant d'afficher l'ensemble des informations
concernant une formation. Cette vue est une page de contenu, permettant
d'afficher le détail d'une formation. Nous apportons au code de la vue générée
les modifications suivantes :
• Nous modifions le titre de la page et du formulaire.
• Nous ajoutons du style CSS permettant de mettre en forme les libellés des
champs de saisie du formulaire. Nous les renommons pour des raisons
esthétiques.
• Nous supprimons les champs Identifiant et Description.
• Si l'utilisateur est authentifié, alors nous ajoutons un lien hypertext dont le
libellé est Demander Infos, permettant d'enregistrer dans la table !!! A
Spécifier !!! une demande d'information. Ce lien hypertext envoi alors une
requête de type HTTP GET afin d'exécuter l'action DemanderInfos du
contrôleur Formation, en passant en paramètre l'identifiant de la formation.
• Nous supprimons les liens hypertextes "Edit" et "Back to List".
Nous obtenons ainsi le bloc de code suivant :
Page 38 sur 41
Développement d'une application Web avec ASP .NET MVC
Livre Visual Studio 2010 aux éditions ENI par James Ravaille et Julien Dollon
<%@ Page Title="" Language="C#"
MasterPageFile="~/Views/Shared/Site.Master"
Inherits="System.Web.Mvc.ViewPage<LearningCompany_DAO.Formation>"
%>
<asp:Content ID="Content1" ContentPlaceHolderID="TitleContent"
runat="server">
Détail d'une formation
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent"
runat="server">
<style type="text/css">
p label {
float: left;
width: 100px;
text-align: left;
padding: 0 0.5 0 0;
font-weight: bold;
}
</style>
<h2>Détail d'une formation</h2>
<p>
<label>Référence :</label>
<%= Html.Encode(Model.Reference) %>
</p>
<p style="margin-top:15px;">
<label>Libellé :</label>
<%= Html.Encode(Model.Libelle) %>
</p>
<p style="margin-top:15px;">
<label>Durée :</label>
<%= Html.Encode(Model.NombreJours) %>
</p>
<p style="margin-top:15px;">
<label>Description :</label>
<%= Html.Encode(Model.Description) %>
</p>
<%
if (Request.IsAuthenticated)
{
%>
<br />
<%
Response.Write(Html.ActionLink("Demander Infos",
"DemanderInfos", "Formation", new {
aIdentifiantFomation=Model.Identifiant}, null));
}
%>
</asp:Content>
Pour un utilisateur authentifié, l'affichage du détail d'une formation sera le suivant
:
Page 39 sur 41
Développement d'une application Web avec ASP .NET MVC
Livre Visual Studio 2010 aux éditions ENI par James Ravaille et Julien Dollon
D.5.e. Création de l'action DemanderInfos (int?)
Cette action permet à un utilisateur identifié par l'application, de pouvoir effectuer
une demande d'information sur une formation. L'implémentation de cette action
est la suivante :
[Authorize]
public ActionResult DemanderInfos(int? aIdentifiantFomation)
{
Formation oFormation = null;
Client oClient;
ActionResult oActionResult = null;
if (aIdentifiantFomation.HasValue)
{
oFormation =
Formation.GetInstance(aIdentifiantFomation.Value);
oClient = Client.GetInstance(User.Identity.Name);
oClient.DemanderInformations(oFormation);
ViewData["Commercial"] = oClient.Commercial;
oActionResult = this.View("AcceptationDemandeFormation");
}
return oActionResult;
}
La métadonnée [Autorize] de cette action permet d'indiquer que l'utilisateur
demandant son exécution doit être identifié pour l'exécuter. Si ce n'est pas le cas,
il sera automatiquement redirigé vers le formulaire de connexion de l'application.
Une fois la demande d'information enregistrée, nous souhaitons transmettre à la
vue qui sera associée à cette action l'ensemble des informations sur le
commercial, responsable du compte client. Pour ce faire, nous utilisons l'objet
ViewData, qui correspond à un contexte de données, dans lequel nous déclarons
une variable nommée "Commercial", qui contiendra un objet de type Commercial.
De la même manière que précédemment, nous créons une vue associée à cette
action. Cette vue est une vue de contenu non typée, ne définissant aucun mode
de gestion. L'implémentation de cette vue est la suivante :
Page 40 sur 41
Développement d'une application Web avec ASP .NET MVC
Livre Visual Studio 2010 aux éditions ENI par James Ravaille et Julien Dollon
<%@ Page Title="" Language="C#"
MasterPageFile="~/Views/Shared/Site.Master"
Inherits="System.Web.Mvc.ViewPage" %>
<asp:Content ID="Content1" ContentPlaceHolderID="TitleContent"
runat="server">
Prise en compte de votre demande
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent"
runat="server">
<h2>Prise en compte de votre demande</h2>
Votre demande d'informations a été prise en compte. Elle sera
traitée dans les meilleurs délais.
<br /><br />
Elle sera traitée par
<%=((LearningCompany_DAO.Commercial)ViewData["Commercial"]).NomPr
enom %>.
</asp:Content>
Au travers du contexte de données ViewData, nous accédons à l'objet de type
Commercial, afin d'afficher son nom et prénom. L'utilisateur sait donc quelle
personne prend en charge sa demande.
Page 41 sur 41

Documents pareils