1-3 Décortiquer la requête
Comment en arrivons-nous à afficher la page d'accueil, ainsi que la page Privacy
?
1. Point d'entrée: Program.cs
Tout commence dans le fichier Program.cs
qui définit la structure de base pour les routes. Program.cs
s'avère aussi être le point d'entrée de l'application: le serveur est simplement une application console.
app.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
L'attribut pattern
définit qu'une route est du format nom-du-controleur/action/identifiant-optionnel
.
On remarque qu'il y a des valeurs par défaut:
controller=Home
action=Index
Ainsi, si aucun contrôleur n'est spécifié (racine /
du site par exemple), le contrôleur Home
est automatiquement responsable de traiter la requête.
Idem pour l'action. La fonction Index
du contrôleur sera utilisée, indépendamment de s'il s'agit de HomeController
ou d'un autre.
Allons donc inspecter ce contrôleur pour la suite!
2. Contrôleur HomeController.cs
Ouvrez le fichier HomeController.cs
sous le dossier Controllers
pour y jeter un coup d'œil.
public class HomeController : Controller
{
private readonly ILogger<HomeController> _logger;
public HomeController(ILogger<HomeController> logger)
{
_logger = logger;
}
public IActionResult Index()
{
return View();
}
public IActionResult Privacy()
{
return View();
}
[ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
public IActionResult Error()
{
return View(new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier });
}
}
La classe du contrôleur hérite de Controller
Le contrôleur Home est au fond une classe bien standard, mais qui hérite de Controller
. La classe Controller
provient de .NET Core MVC et c'est cette classe qui confère au HomeController
ses fonctionnalités et son comportement de contrôleur.
public class HomeController : Controller
L'héritage en C# est défini à l'aide du symbole :
. Une classe peut avoir seulement une classe parent, C# ne supporte pas l'héritage multiple. Cependant, une classe peut implémenter plusieurs interfaces.
public class HomeController : Controller
veut donc dire que HomeController
hérite de Controller
.
Vous pouvez faire clic droit
-> Go To
-> Go to Declaration or Usages
ou encore F12
sur un type, comme sur Controller
pour voir le code source.
Si vous voulez voir comment Controller
fonctionne, vous pouvez!
Actions Index() et Privacy()
public IActionResult Index()
{
return View();
}
Par défaut, si on ne spécifie pas la route d'une action (nous y viendrons plus tard), son URI sera le nom de l'action. Idem pour le contrôleur.
Par exemple, le HomeController sera automatiquement associé à 2 routes / URI:
/Home/Index
/Home/Privacy
Essayez ces 2 URLs dans votre navigateur, à partir de la racine du site et vous devriez obtenir les pages correspondantes.
Retour IActionResult
via une fonction View()
C'est à l'aide de la fonction View()
retournée qu'on arrive à afficher une vue.
Nous reviendrons plus tard au type de retour IActionResult
et aux différentes façons de retourner du contenu.
public IActionResult Index()
{
return View();
}
Par défaut, appeler View()
dans une fonction Index
fera en sorte que le cadriciel cherchera à retourner une vue du même nom que l'action dans le dossier associé au contrôleur sous le dossier Views.
Dans ce cas-ci, le cadriciel cherchera une vue appelée Views/Home/Index.cshtml
3. Vue associée à l'action Index
Vous trouverez sous le dossier Views/Home
un fichier Index.cshtml
.
@{
ViewData["Title"] = "Home Page";
}
<div class="text-center">
<h1 class="display-4">Welcome</h1>
<p>Learn about <a href="https://docs.microsoft.com/aspnet/core">building Web apps with ASP.NET Core</a>.</p>
</div>
cshtml
est le format de fichier pour les vues en .NET Core MVC. Il s'agit d'un fichier dans lequel on peut mettre du HTML, mais aussi du code.
On appelle ce système de templating Razor
. Nous y reviendrons plus tard en détail sur les particularités de Razor
et sa syntaxe.
Ce HTML vous est peut-être familier, c'est en effet le HTML affiché sur la page d'accueil!
4. Layout
Le fichier Index.cshtml
est relativement maigre, on ne retrouve pas d'information supplémentaire comme la navigation, par exemple.
D'où vient cette information?
Fichier _ViewStart
Sous le dossier Views
, on retrouve un fichier _ViewStart.cshtml
.
Le fichier _ViewStart.cshtml
est utilisé pour définir du code commun à toutes les vues. Il est possible d'avoir d'autres fichiers _ViewStart
dans des sous-dossiers, mais pour le moment il en existe un générique propre à toutes les vues.
Au fond, toutes les vues partageant le dossier dans lequel _ViewStart
est placé partageront le code contenu dans ce dernier.
Ce fichier contient la ligne de code suivante:
@{
Layout = "_Layout";
}
Ainsi, il spécifie que les vues utilisent le layout (gabarit HTML) appelé _Layout
.
Fichier _Layout
Remarquez la ligne @RenderBody()
, c'est à cet endroit que le contenu de la vue sera introduit.
De plus, la balise <title>
fait référence à @ViewData["Title"]
que l'on retrouvait dans Index.cshtml
.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<title>@ViewData["Title"] - Snowfall.Web.Mvc</title>
<link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.min.css"/>
<link rel="stylesheet" href="~/css/site.css" asp-append-version="true"/>
<link rel="stylesheet" href="~/Snowfall.Web.Mvc.styles.css" asp-append-version="true"/>
</head>
<body>
<header>
<nav class="navbar navbar-expand-sm navbar-toggleable-sm navbar-light bg-white border-bottom box-shadow mb-3">
<div class="container-fluid">
<a class="navbar-brand" asp-area="" asp-controller="Home" asp-action="Index">Snowfall.Web.Mvc</a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target=".navbar-collapse" aria-controls="navbarSupportedContent"
aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="navbar-collapse collapse d-sm-inline-flex justify-content-between">
<ul class="navbar-nav flex-grow-1">
<li class="nav-item">
<a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="Index">Home</a>
</li>
<li class="nav-item">
<a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="Privacy">Privacy</a>
</li>
</ul>
</div>
</div>
</nav>
</header>
<div class="container">
<main role="main" class="pb-3">
@RenderBody()
</main>
</div>
<footer class="border-top footer text-muted">
<div class="container">
© 2023 - Snowfall.Web.Mvc - <a asp-area="" asp-controller="Home" asp-action="Privacy">Privacy</a>
</div>
</footer>
<script src="~/lib/jquery/dist/jquery.min.js"></script>
<script src="~/lib/bootstrap/dist/js/bootstrap.bundle.min.js"></script>
<script src="~/js/site.js" asp-append-version="true"></script>
@await RenderSectionAsync("Scripts", required: false)
</body>
</html>
Liens vers d'autres pages
Pour faire des liens vers les pages, on peut laisser le framework faire le travail de trouver l'URL et donc la route associée à la combinaison de contrôleur et d'action.
<li class="nav-item">
<a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="Privacy">Privacy</a>
</li>
On omet l'attribut href
et on le remplace plutôt par:
asp-controller=
permet de spécifier vers quel contrôleurasp-action=
permet de préciser l'action
Au final, ce lien HTML a l'air de ceci du côté client (navigateur):
<a class="nav-link text-dark" href="/Home/Privacy">Privacy</a>