Après avoir vu comment installer notre environnement de développement pour ASP.NET MVC dans le précédent billet, nous allons examiner plus en détails ce qu'est un controlleur, une vue, et un modèle dans le cadre d'une application ASP.NET MVC.
La meilleure façon d'apprécier un outil de développement reste de l'utiliser. Dans ce billet, nous allons créer une simple application de saisie de données ASP.NET MVC 4. Nous procéderons étapes par étapes afin de bien voir comment une application MVC est construite. Toutefois, afin de ne pas alourdir ce billet avec trop d'explications ou de théorie, certains détails techniques seront simplement évoqués. Mais ne vous inquiétez pas, si vous débutez avec ASP.NET MVC je reviendrais sur ces différents points dans les prochains billets.
Création d'un nouveau projet ASP.NET MVC
Nous allons commencer par créer un nouveau projet MVC dans Visual Studio. Dans le fenêtre de création de projet, en sélectionnant les templates de projet Web, vous verrez que l'installation de MVC 4 a créé un nouveau template comme on peut le voir ci-dessous :
Après saisie du nom du projet et validation, une autre fenêtre apparaît. Celle-ci nous demande de choisir entre les différents types de projets que propose MVC 4 :
Comme vu au début de cette série, le template Empty crée un projet avec seulement le minimum de fichiers et les dossiers requis pour une application MVC. Le template Internet Application crée une application exemple que vous pouvez modifier, comprenant l'enregistrement des utilisateurs et l'authentification, la navigation, et un template visuel sympa (plus en tout cas qu'avec MVC 3). Le tempate Intranet Application est similaire au précédent, mais est conçu pour une utilisation avec authentification Windows. Pour notre exemple, nous allons choisir le template Empty. Pour le moment, pas besoin de cocher l'option pour utiliser HTML 5 ni un projet de tests unitaires.
Remarque : sous la liste des templates de projets disponibles, vous pouvez choisir le moteur de vue à l'aide d'une liste déroulante. Vous avez le choix entre Razor ou le moteur ASP.NET classique. Pour la suite nous utiliserons toujours Razor et je vous recommande de le faire. La partie 7 ou 8 de cette série reviendra plus en détails sur Razor et vous comprendrez rapidement que l'essayer c'est l'adopter :-)
Une fois que Visual Studio a crée le projet, vous verrez un certain nombre de fichiers et dossiers affichés dans la fenêtre de l'Explorateur de solutions. Il s'agit de la structure par défaut pour une projet MVC 4. Avant de s'y attarder, essayons déjà de lancer l'application en mode débug pour voir ce qu'il se passe avec un template de projet Empty. Comme vous pouvez le voir ci-dessous, le lancement nous donne une belle erreur 404 :
Ajout du premier Contrôleur
Avec le paradigme MVC, les demandes entrantes sont traitées par les contrôleurs. Dans ASP.NET MVC, les contrôleurs sont de simples classes C# (généralement héritant de System.Web.Mvc.Controller). Chaque méthode publique d'un contrôleur est connue comme une méthode d'action, ce qui signifie que vous pouvez l'invoquer depuis le Web via une URL pour effectuer une action. La convention MVC est de mettre les contrôleurs dans un dossier appelé "Controller", que Visual Studio nous créé par défaut, même avec le template Empty. Respecter ces conventions n'est pas une obligation la plupart du temps, mais afin de ne pas compliquer les choses pour les débutants nous les suivrons pour les prochains billets.
Pour ajouter un contrôleur à notre projet, un clic-droit sur le dossier Controllers dans la fenêtre de l'Explorateur de solutions puis Add -> Controller à partir du menu, comme on peut le voir ci-dessous :
Lorsque la boîte de dialogue pour la création d'un controlleur apparaît, nommez le HomeController comme indiqué sur l'image plus bas. Ceci est une autre convention ASP.NET MVC : les noms que nous donnons aux contrôleurs doit être descriptif et se terminer par "Controller".
La section d'options pour le Scaffolding nous permet de créer un contrôleur utilisant un modèle avec des fonctions communes. Nous n'allons pas utiliser cette fonction pour le moment, afin de partir d'un contrôleur vide. Suite au clic sur le bouton Add, Visual Studio va créer un nouveau fichier de code C# dans le dossier Controller et l'appeller HomeController.cs. Cette classe dérive de System.Web.Mvc.Controller. Nous allons la modifier afin qu'elle corresponde à ceci :
namespace IntroductionMVC4.Controllers
{
public class HomeController : Controller
{
//
// GET: /Home/
public string Index()
{
return "Hello World";
}
}
}
Nous n'avons rien créé de très excitant, mais c'est un bon moyen de démarrer avec MVC. Nous avons créé une méthode d'action nommée Index, qui renvoie la chaîne "Hello World". Si on exécute maintenant notre application en débug, on s'aperçoit qu'il n'y a plus d'erreur 404 et que le naviguateur affiche le résultat dela méthode Index comme ci-dessous :
Comprendre le routage
En plus des modèles, des vues et des contrôleurs, les applications MVC utilisent également le système de routage ASP.NET, qui décide comment les URL correspondent à un contrôleur et une action particulière. Lorsque Visual Studio crée un projet MVC, il ajoute certaines routes par défaut pour nous aider à démarrer, et ce même avec le template Empty. Si vous saisissez l'une des URL suivantes, vous remarquerez que le moteur de routage ASP.NET nous redirigera vers l'action Index du contrôleur HomeController :
- /
- /Home
- /Home/Index
Ainsi, lorsqu'un navigateur demande http://monsite/ ou http://monsite/Home, il récupère la sortie de la méthode Index du contrôleur HomeController. Actuellement, la sortie de cette méthode est une simple chaîne de caractères. Ceci montre qu'il est utile de suivre les conventions MVC. La convention veut que nous ayons un contrôleur nommé HomeController et que celui-ci soit le point de départ de notre application MVC. Si nous n'avions pas respecté la convention, nous aurions eu besoin de modifier les routes pour pointer vers le contrôleur que nous aurions créé à la place. Evidemment, nous verrons plus tard comment on peut modifier la configuration de routage dans le fichier Global.asax et la personnaliser.
Création et rendu d'une vue
Il est temps maintenant de remplacer la chaîne de caractères "Hello World" par une réponse HTML en réponse à une requête d'un client. Pour cela nous avons besoin de créer une vue. La première chose à faire consiste à modifier notre méthode d'action Index comme ci-dessous :
namespace IntroductionMVC4.Controllers
{
public class HomeController : Controller
{
//
// GET: /Home/
public ViewResult Index()
{
return View();
}
}
}
Les changements par rapport à la version précédente de la méthode Index sont indiqués en gras. Quand nous retournons un objet de type ViewResult à l'aide d'une méthode d'action, nous demandons à MVC de génerer le rendu d'une vue. Nous créons l'objet ViewResult en appelant la méthode View sans paramètres. Ceci indique à MVC de génerer le rendu par défaut de la vue pour la méthode d'action.Si vous exécutez l'application à ce stade vous pourrez constater le message d'erreur suivant :
Ce message d'erreur est plus utile qu'il n'y paraît. Il nous explique non seulement que MVC n'a pas pu trouver une vue associée à notre méthode d'action, mais il montre également où MVC a cherché cette vue. Ceci est un autre exemple d'une convention MVC : les vues sont associées à des méthodes d'action par une convention de nommage. Notre méthode d'action est appelé Index, et comme vous pouvez le voir sur l'image ci-dessus MVC essaye de trouver les différents fichiers dans le dossier Views portant ce même nom.
Pour créer une vue, le plus simple reste de faire un clic-droit directement sur la méthode d'action de notre contrôleur HomeController (soit sur le nom de la méthode, soit dans le code de celle-ci). La fenêtre de dialogue qui apparaît est la suivante :
Décochez l'option "User a layout or master page", nous n'utilisons pas pour le moment de mise en page ou de master page. Après un clic sur le bouton Add, Visual Studio va créer notre vue dans un fichier nommé Index.cshtml, dans le dossier Views/Home. Si vous observez de nouveau le message d'erreur précédent, vous verrez que nous venons de créer un fichier à un des endroits examiné par MVC lors de la requête.
Note : l'extension .cshtml ne vous est peut-être pas familière, elle représente un fichier codé en C# qui sera exécuté à l'aide du moteur Razor. Si nous aurions opté pour le moteur ASP.NET classique plutôt que Razor, nous aurions bien entendu des fichiers avec extension .aspx.
Le nouveau fichier Index.cshtml contient majoritairement du code HTML. L'exception se situe au début du fichier comme ci-dessous :
@{
Layout = null;
}
Ceci est un bloc de code qui sera interprété par le moteur Razor. Cela reste simple : il indique à Razor que nous avons choisi de ne pas utiliser une master page. Ignorons Razor pour le moment, qui fera l'objet un long billet. Modifions notre fichier Index.cshtml comme ci-dessous (modifications en gras) :
@{
Layout = null;
}
<!DOCTYPE html>
<html>
<head>
<title>Index</title>
</head>
<body>
<div>
Hello World, depuis notre vue
</div>
</body>
</html>
Le code ajouté nous permet d'afficher en HTML le "Hello World". En lançant l'application en mode débug nous obtenons ceci dans le navigateur :
Lorsque nous avons créé la méthode d'action Index, elle retournait une chaîne de caractères. Cela signifie que MVC ne faisait rien excepté de relayer cette chaîne au navigateur. Maintenant que la méthode Index renvoie un object ViewResult, nous chargeons MVC de générer le rendu HTML de la vue et de la renvoyer au navigateur. A aucun moment nous avons spécifié à MVC quelle vue devait être utilisée, de sorte qu'il utilise la convention de nommage pour en trouver une automatiquement.
On peut retourner d'autres types de résultats par les méthodes d'action en dehors des chaînes et des objets ViewResult. Par exemple, si nous retournons un RedirectResult, nous obligeons le navigateur à être redirigé vers une autre URL. Si nous retournons une HttpUnauthorizedResult, nous obligeons l'utilisateur à se connecter Ces objets sont collectivement connus comme ActionResults, et sont tous dérivés de la classe ActionResult. Ce système de résultats des méthodes d'action nous permet d'encapsuler et de réutiliser des réponses communes à des actions. Nous reviendrons sur ce sujet dans un prochain billet.
Ajouter du contenu dynamique à notre vue
Une application Web a pour but de construire et d'afficher en sortie du contenu dynamique, sinon autant faire du pur HTML. Avec MVC c'est le travail du contrôleur de construire certaines données, et c'est le travail de la vue de s'occuper du rendu HTML. Les données sont transmises par le contrôleur à la vue. Une façon de transmettre ces données depuis le contrôleur à la vue est d'utiliser l'objet ViewBag. C'est un membre de la classe de base System.Web.Mvc.Controller, et il correspond à un objet dynamique auquel on peut attribuer des propriétés arbitraires, de façon à rendre ces valeurs disponibles dans les vues. Le code suivant illustre mieux le fonctionnement du ViewBag :
public class HomeController : Controller
{
//
// GET: /Home/
public ViewResult Index()
{
int hour = DateTime.Now.Hour;
ViewBag.Bonjour = hour < 18 ? "Bonjour" : "Bonsoir";
return View();
}
}
Pour accéder dans la vue à la valeur stockée dans le ViewBag, c'est assez simple :
@{
Layout = null;
}
<!DOCTYPE html>
<html>
<head>
<title>Index</title>
</head>
<body>
<div>
@ViewBag.Bonjour tout le monde, depuis notre vue
</div>
</body>
</html>
L'ajout en gras est un bloc de code Razor qui récupère la valeur contenue dans la propriété nommée Bonjour. Il n'y a rien de spécial au sujet du nom de la propriété, nous pourrions le remplacer avec n'importe quel nom de propriété personnalisé.
Note concernant ce bout de code Razor : nous ne sommes pas obligés d'encadrer le code avec les balises @{ et }, comme c'est le cas avec les balises ASP.NET <% et %>. En effet, dans le code de la vue ci-dessus, nous commençons par le caractère @ et c'est tout. C'est l'un des avantages de Razor : il est plus lisible, plus court, et moins long à écrire. C'est exactement comme le côté obscur de la force "il est plus rapide, plus séduisant"... à la différence prêt qu'il n'est pas obscur :-)
Si nous executons le projet une nouvelle fois, nous constatons que selon l'heure à laquelle nous sommes, le rendu de la vue ne sera pas le même.
C'est tout pour aujourd'hui. Nous avons vu comment créer et à quoi sert un contrôleur ainsi qu'une vue. Dans le prochain billet nous continuerons ce projet en y ajoutant un modèle et en permettant à l'utilisateur de saisir des données, tout en utilisant le mécanisme de validation proposé par MVC pour s'assurer que les informations sont bien saisies. J'essaye de rédiger étapes par étapes afin de bien montrer les bases à ce qui débutent avec MVC, mais espère que cela reste sympa à lire :-)