IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)

Vous êtes nouveau sur Developpez.com ? Créez votre compte ou connectez-vous afin de pouvoir participer !

Vous devez avoir un compte Developpez.com et être connecté pour pouvoir participer aux discussions.

Vous n'avez pas encore de compte Developpez.com ? Créez-en un en quelques instants, c'est entièrement gratuit !

Si vous disposez déjà d'un compte et qu'il est bien activé, connectez-vous à l'aide du formulaire ci-dessous.

Identifiez-vous
Identifiant
Mot de passe
Mot de passe oublié ?
Créer un compte

L'inscription est gratuite et ne vous prendra que quelques instants !

Je m'inscris !

Apprendre à démystifier le modèle MVC des applications ASP.NET Core - partie 1
Par Hinault Romaric

Le , par Hinault Romaric

0PARTAGES

Le modèle de projet MVC (Model–view–controller) des templates des outils de développement pour .NET Core permet de créer une application avec un certain nombre d’éléments préconfigurés (ajout des packages pour ASP.NET Core MVC, mise en place du routage, création du contrôleur Home, des vues, du layout, d’une page d’accueil, etc.).




Il est assez pratique pour débuter la création d’une application MVC. Toutefois, en phase d’apprentissage, utiliser ce modèle sans une certaine connaissance va vous confronter à des éléments qui autrement vont vous sembler obscurs.

Dans ce billet, nous partirons d’un modèle de base pour mettre en place tous les éléments nécessaires pour disposer d’un projet MVC. Je vais utiliser Visual Studio Code.

Pour configurer Visual Studio Code et mettre en place le projet de démarrage, veuillez consulter le billet de blog suivant :

Configurer Visual Studio Code pour déboguer une application ASP.NET Core

Introduction à MVC

Le patron de conception MVC est désormais une référence dans le développement d’applications Web. Il proposer de regrouper les éléments de son application au sein de trois principaux composants, dont le modèle, le contrôleur et la vue.

Le modèle

Le M dans le sigle MVC fait référence au modèle. Le modèle dans cette architecture est couramment la représentation des entités qui sont manipulées par votre application. Une entité peut, par exemple, être un Etudiant. L’entité Etudiant doit disposer du nécessaire pour obtenir les informations sur un étudiant (nom, prénom, sexe, etc.).

L’entité Etudiant sera représentée dans l’application par un fichier (Etudiant.cs) contenant une classe Etudiant, avec des propriétés (nom, prénom, sexe), des accesseurs (getter) et des mutateurs (setter).
L’ensemble des fichiers du modèle va donc constituer le modèle objet (ou le modèle de classes).

Le contrôleur

Le C dans le sigle MVC fait référence au contrôleur. Le contrôleur représente un élément clé du patron de conception MVC. C’est au sein du contrôleur que les traitements des données sont effectués.
En effet, suivant les besoins de l’application, le contrôleur va utiliser le modèle pour effectuer des traitements précis, ensuite sélectionner la vue adéquate et passer le modèle à cette dernière.
Les données qui sont passées à la vue à travers le modèle seront encore sous un format brut (Liste, JSON, etc.).

La vue

Le V dans le sigle MVC fait référence à la vue. La vue va regrouper toute la logique de présentation. Il s’agit en effet d’une page Web.
La vue contient le code HTML, CSS et JavaScript nécessaire pour afficher les données selon la représentation voulue par le développeur.

En effet, une fois les données brutes reçues du contrôleur, la vue se charge de formater celles-ci et les disposer dans la page de façon agréable pour les yeux de l’utilisateur.

Cycle de vie d’une requête Web avec MVC

Pour être plus concret, lorsque l’utilisateur ouvre son navigateur et saisit un lien, sa requête est dirigée vers le contrôleur. Le contrôleur se charge des traitements en utilisant le modèle, ensuite passe la main à la vue qui va transformer le modèle en une jolie représentation avant d’afficher le contenu dans votre navigateur Web.

L’image ci-dessous donne un aperçu du processus.



À ce stade, vous vous posez certainement de nombreuses questions sur comment ces morceaux sont assemblés pour afficher du contenu dans le navigateur de l’utilisateur.

C’est à ce moment qu’un Framework orienté MVC, dont ASP.NET MVC Core, prend tout son sens. En effet tout le pipeline de la requête jusqu’à la réponse sera géré par le Framework, grâce à son mécanisme de routage.

Description du modèle de base

Notre application repose sur un modèle de base ne disposant d’aucune vue, contrôleur, librairie CSS, etc. Ce modèle se résume à deux fichiers principaux :

  • Program.cs ;
  • Startup.cs.


Le fichier Program.cs

Le fichier d’initialisation de l’application est le fichier Program.cs qui contient la méthode main :

Code C# : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
  public static void Main(string[] args) 
        { 
            var host = new WebHostBuilder() 
                .UseKestrel() 
                .UseContentRoot(Directory.GetCurrentDirectory()) 
                .UseIISIntegration() 
                .UseStartup<Startup>() 
                .Build(); 
  
            host.Run(); 
        } 
    }

Cette méthode permet d’initialiser et démarrer l’hôte (host) de votre application. L’hôte est une instance de WebHostBuilder, ce dernier est responsable du démarrage de votre application et de la gestion du cycle de vie de celle-ci.

L’initialisation par défaut dans le Program.cs permet de spécifier le serveur Web qui sera utilisé (UseKestrel()), de définir le répertoire racine de l’application (UseContentRoot(Directory.GetCurrentDirectory())) ou encore la classe de démarrage de l’application (UseStartup<Startup>()).

Il faut noter que les projets ASP.NET Core utilisent par défaut le serveur Kestrel.

Le fichier Startup.cs

Le Startup.cs est le fichier de démarrage de l’application qui est utilisé pour enregistrer les services et injecter des modules dans le pipeline HTTP.

Ce fichier contient par défaut le code suivant :

Code C# : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
 public class Startup 
    { 
        // This method gets called by the runtime. Use this method to add services to the container. 
        // For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940 
        public void ConfigureServices(IServiceCollection services) 
        { 
        } 
  
        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. 
        public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) 
        { 
            loggerFactory.AddConsole(); 
  
            if (env.IsDevelopment()) 
            { 
                app.UseDeveloperExceptionPage(); 
            } 
  
            app.Run(async (context) => 
            { 
                await context.Response.WriteAsync("Hello World!"); 
            }); 
        } 
    }

La méthode Configure est utilisée pour spécifier comment votre application ASP.NET Core va répondre aux requêtes HTTP. Le cycle de vie d’une requête est configuré en ajoutant des middlewares à IApplicationBuilder. Nous y reviendrons.

Vous allez supprimer le code suivant dans cette méthode :

Code C# : Sélectionner tout
1
2
3
4
5
  
            app.Run(async (context) => 
            { 
                await context.Response.WriteAsync("Hello World!"); 
            });

La méthode ConfigureServices est appelée avant Configure. Cette méthode permettra d’ajouter des services au conteneur d’injection de dépendance, avant d’être utilisés dans l’application.

Ajout des packages pour MVC et la gestion des fichiers statiques

ASP.NET Core est bâti autour de la modularité. Les fonctionnalités du framework sont reparties à travers des packages qui sont disponibles via le gestionnaire de packages NuGet. Ainsi, le développeur peut intégrer à son application juste les composants du framework dont il a réellement besoin. C’est pourquoi le projet Web de base n’intègre que le package Microsoft.AspNetCore, qui est le minimum nécessaire pour une application ASP.NET Core.

Pour notre cas, nous aurons pour l’instant besoin de deux packages supplémentaires : le package qui nous permettra de bénéficier des fonctionnalités MVC de ASP.NET.Core et le package qui apportera les fonctionnalités de gestion des fichiers statistiques de ASP.NET Core.

Le package Microsoft.AspNetCore.Mvc

Ce package permet d’accéder aux fonctionnalités essentielles comme la prise en charge des contrôleurs, les vues avec le moteur de vue Razor, le routage, le formatage, etc.

Pour ajouter ce package à votre application, vous devez éditer le fichier testapp.csproj et ajouter dans la section ItemGroup, à la suite de Microsoft.AspNetCore, la référence suivante :

<PackageReference Include="Microsoft.AspNetCore.Mvc" Version="1.1.2" />

Pour ne pas avoir à jouer avec le numéro de version qui va évoluer au fil des itérations du framework vous pouvez installer le package en ligne de commandes en utilisant la commande suivante :

dotnet add package Microsoft.AspNetCore.MVC

Le package Microsoft.AspNetCore.StaticFiles

Une application Web dispose couramment de nombreux fichiers statiques, dont les images, les fichiers CSS, les fichiers HTML, JavaScript, etc. ASP.NET Core offre un package particulier pour le rendu des fichiers statiques.

Pour installer ce package, exécutez simplement la commande :

dotnet add package Microsoft.AspNetCore.StaticFiles

Votre fichier testapp.csproj devrait ressembler à ceci :

Code xml : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
13
<Project Sdk="Microsoft.NET.Sdk.Web"> 
  <PropertyGroup> 
    <TargetFramework>netcoreapp1.1</TargetFramework> 
  </PropertyGroup> 
  <ItemGroup> 
    <Folder Include="wwwroot\" /> 
  </ItemGroup> 
  <ItemGroup> 
    <PackageReference Include="Microsoft.AspNetCore" Version="1.1.1" /> 
    <PackageReference Include="Microsoft.AspNetCore.MVC" Version="1.1.2" /> 
    <PackageReference Include="Microsoft.AspNetCore.StaticFiles" Version="1.1.1" /> 
  </ItemGroup> 
</Project>

À la suite de cela, vous devez restaurer les packages installés à partir du terminal de Visual Studio Code :

Dotnet restore


Middleware

Le pipeline ASP.NET Core (cycle de vie d’une requête HTTP) regroupe un ensemble d’actions qui sont exécutées suite à une requête et la réponse qui est retournée. Chaque action avec ASP.NET Core va représenter un middleware. Les middlewares représentent donc un aspect clé du Framework ASP.NET Core.

Les middlewares sont exécutés de façon séquentielle. Une fois qu’un middleware est exécuté, il passe la main au suivant.

Un middleware peut par exemple s’occuper du chargement du contenu statique, un autre de la sécurité, etc. Les middlewares utilisés par défaut par ASP.NET sont définis dans la méthode Configure du Startup.cs :

Code C# : Sélectionner tout
1
2
3
4
5
6
7
8
9
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) 
        { 
            loggerFactory.AddConsole(); 
  
            if (env.IsDevelopment()) 
            { 
                app.UseDeveloperExceptionPage(); 
            } 
        }

Le seul middleware ajouté à notre application est app.UseDeveloperExceptionPage(). Ce dernier va entrer en action lorsqu’une exception sera levée lors du débogage de l’application et affichera la page d’exception pour les développeurs.

Avant de continuer, nous devons injecter deux middlewares supplémentaires dans notre application. Ceux-ci nous permettront d’exploiter les fonctionnalités des deux packages que nous venons d’ajouter au projet.

Vous allez ajouter le code suivant dans la méthode Configure() :

Code C# : Sélectionner tout
1
2
3
4
5
6
7
8
9
  
          app.UseStaticFiles(); 
  
            app.UseMvc(routes => 
            { 
                routes.MapRoute( 
                    name: "default", 
                    template: "{controller=Home}/{action=Index}/{id?}"); 
            });

Le code complet de cette méthode est le suivant :

Code C# : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) 
        { 
            loggerFactory.AddConsole(); 
  
            if (env.IsDevelopment()) 
            { 
                app.UseDeveloperExceptionPage(); 
            } 
  
           app.UseStaticFiles(); 
  
            app.UseMvc(routes => 
            { 
                routes.MapRoute( 
                    name: "default", 
                    template: "{controller=Home}/{action=Index}/{id?}"); 
            }); 
        }

Le middleware app.UseStaticFiles() va permettre d’injecter le chargement des fichiers statiques dans le cycle de vie d’une requête HTTP.

Le second middleware (app.UseMvc()), permettra d’ajouter les fonctionnalités MVC. Il s’agit entre autres du routage, du moteur de rendu des vues, etc.

Ce middleware nécessite au préalable l’ajout du service MVC dans la méthode ConfigureServices :

Code C# : Sélectionner tout
1
2
3
4
public void ConfigureServices(IServiceCollection services) 
        { 
             services.AddMvc(); 
        }


Il est assez simple de créer son middleware personnalisé, et l’injecter dans le pipeline d’une requête ASP.NET Core pour effectuer une action particulière. Pour en savoir plus sur la création des middlewares personnalisés, vous pouvez consulter mon billet de blog suivant :

https://www.developpez.net/forums/bl...omain-routing/.

Routage

Dans la section sur le cycle de vie d’une requête HTTP avec ASP.NET Core MVC, j’ai présenté brièvement le flux de communication entre le contrôleur, le modèle et la vue. Cette description vous a probablement semblé assez superflue. Elle le sera moins si vous comprenez le mécanisme de routage de ASP.NET Core MVC.

Dans une application Web traditionnelle, une adresse URL fait référence à un fichier dans le dossier d’hébergement de l’application. Par exemple l’adresse suivante http://monapplication/clients.aspx, sera mappée avec un fichier client.aspx sur le serveur d’hébergement de l’application, qui contient du code permettant de retourner une réponse au navigateur (ça peut être la liste des clients).

Avec ASP.NET Core MVC, notre code (contenu) est reparti dans un modèle, des contrôleurs et des vues. Comment le Framework procède-t-il pour mapper une URL avec le contenu adéquat ? En effet, ce dernier dispose d’un mécanisme permettant d’interpréter une URL afin d’identifier les différents paramètres qui sont passés, pour pouvoir appeler le contrôleur adéquat, exécuter l’action qu’il faut et retourner au navigateur une réponse.

L’identification des différents paramètres dans l’URL saisie se fait suivant une table de routage que vous pouvez personnaliser. Lorsque vous créez une nouvelle application ASP.NET Core MVC, vous devez définir un itinéraire par défaut. Ce que nous avons fait en ajouter le middleware MVC dans le fichier Startup.cs :

Code C# : Sélectionner tout
1
2
3
4
5
6
app.UseMvc(routes => 
            { 
                routes.MapRoute( 
                    name: "default", 
                    template: "{controller=Home}/{action=Index}/{id?}"); 
            });

Ce bout de code permet de créer la table de routage avec une route par défaut.

Une route par défaut est définie par :
  • un nom, qui doit être unique dans la table de routage ;
  • un format d’URL ;
  • des valeurs par défaut.


Le format de l’itinéraire par défaut est controller/action/id. Contrôleur représente le nom du contrôleur qui sera instancié par le Framework ; action la méthode d’action de ce contrôleur qui sera exécutée et id le paramètre qui sera passé à la méthode d’action. Le « ? » permet de signaler que le paramètre est optionnel.

Par exemple si nous saisissons l’adresse suivante :

  • http://localhost/Student/Details/1, le Framework procédera à l’instanciation du contrôleur StudentController et fera appel à la méthode d’action Details, en passant comme valeur 1 au paramètre ID. Le code StudentController.Details(1) sera donc exécuté ;
  • http://localhost/Student/, le Framework procédera à l’instanciation du contrôleur StudentController et ne trouvant pas le nom de la méthode d’action, fera appelle à la valeur par défaut qui est Index. Cette dernière sera donc appelée ;
  • http://localhost/, le framework dans ce cas utilisera les valeurs par défaut et procédera à l’instanciation du contrôleur HomeController et fera appel à la méthode d’action Index.


Ci-dessous un exemple de code du contrôleur HomeController avec la méthode d’action Index :

Code C# : Sélectionner tout
1
2
3
4
5
6
public class HomeController : Controller 
 { 
 public ActionResult Index(int id) 
 { 
 return View(); 
 }

Il faut noter que le nom de l’hôte (localhost) n’est pas pris en compte.

Création du contrôleur et la vue

Après une brève incursion dans le monde du routage de ASP.NET Core MVC, continuons avec la mise en place de notre application. Les connaissances acquises ci-haut nous seront d’une grande utilité dans la création de nos contrôleurs et vues.

Création du contrôleur

Dans Visual Studio Code, vous allez ajouter un nouveau dossier Controllers à la racine du dossier. Pour le faire, vous devez simplement cliquer sur le dossier en question dans l’explorateur de fichier, ensuite sur l’icône de création d’un nouveau dossier et enfin saisir le nom du fichier.


Dans ce dossier, vous allez ajouter un nouveau fichier HomeController.cs (sélection du dossier, clic droit, ensuite Nouveau fichier).

Dans ce fichier, vous allez ajouter le code suivant :

Code C# : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Threading.Tasks; 
using Microsoft.AspNetCore.Mvc; 
  
namespace testapp.Controllers 
{ 
    public class HomeController : Controller 
    { 
        public IActionResult Index() 
        { 
            return View(); 
        } 
  
        public IActionResult About() 
        { 
  
            return View(); 
        } 
  
        public IActionResult Contact() 
        { 
            return View(); 
        } 
  
        public IActionResult Error() 
        { 
            return View(); 
        } 
    } 
}


Dans ce contrôleur, j’ai défini quatre actions. Donc, nous avons potentiellement quatre pages correspondantes pouvant être affichées dans un navigateur.

Création des vues

Par convention, un contrôleur est associé à un dossier portant le même nom sans le suffixe Controller. Ce dossier doit contenir des fichiers de vue portant le même nom que chaque méthode d’action. Ce dossier doit être créé dans un dossier Views à la racine du projet. Par exemple, pour notre HomeController, nous aurons les fichiers de vues suivantes :


Vous allez donc créer dans votre application le dossier Views. Dans celui-ci, vous allez créer le dossier Home. Ensuite, dans ce dossier, vous allez ajouter le fichier Index.cstml.

Dans celui-ci, ajoutez le code HTML suivant :

Code html : Sélectionner tout
1
2
3
4
5
6
7
8
9
<!DOCTYPE html> 
<html> 
    <head> 
         <title>Accueil - TestApp</title> 
    </head> 
    <body> 
        <h1>Hello World</h1> 
    </body> 
</html>

Lancez le débogage de votre application en appuyant sur F5. Notre page d’index sera affichée dans le navigateur.


Les valeurs par défaut de la table de routage ont été utilisées pour faire appel à la méthode d’action Index du HomeController. D’où l’affichage de cette page.

Dans la prochaine partie, nous verrons la communication entre le contrôleur et la vue. Restez connecté !

Une erreur dans cette actualité ? Signalez-nous-la !