Vous êtes sur la page 1sur 15

Module au choix : Programmation .

Net/C# ENIT AU 2020/2021

ASP.NET Core MVC

Dans ce tutoriel nous allons créer une application web de gestion de voitures de collection en
ASP.NET Core MVC avec un modèle, un contrôleur et des vues

1. Créer une application Web ASP.NET Core MVC

Dans le menu fichier de Visual Studio, sélectionnez nouveau > projet.


Créez une application web ASP.NET Core, puis sélectionnez Suivant.

Nommez le projet GestionVoitures.

Dans la fenêtre qui suit choisissez le modèle "Application web (Model-View-Controller)" puis Créer

1/15
Module au choix : Programmation .Net/C# ENIT AU 2020/2021

Le projet de démarrage suivant est créé :

2. Exécuter l'application

Vous disposez maintenant d'une application web fonctionnelle créée selon le modèle MVC, cette
application de base constitue un bon point de départ, Vous pouvez la tester : appuyez sur Ctrl+F5
pour exécuter sans le débogueur.
Visual Studio affiche la boîte de dialogue suivante :

Sélectionnez Oui si vous faites confiance au certificat SSL d’IIS Express.

2/15
Module au choix : Programmation .Net/C# ENIT AU 2020/2021

La boîte de dialogue suivante s’affiche :

 Sélectionnez Oui si vous acceptez d’approuver le certificat de développement.


Visual Studio démarre IIS Express et exécute l’application. La barre d’adresses
affiche localhost:port# au lieu de quelque chose qui ressemble à example.com. La raison en est
que localhost est le nom d’hôte standard de l’ordinateur local. Localhost traite uniquement les
requêtes web de l’ordinateur local. Quand Visual Studio crée un projet web, un port aléatoire est
utilisé pour le serveur web.
L'architecture MVC sépare le programme en 3 couches : Modèle, Vue et Contrôleur.
Le modèle contient des classes qui représentent les données de l'application
La vue affiche l'interface utilisateur de l'application
Les contrôleurs gèrent les demandes de l'utilisateur, récupèrent les données du modèle et
appellent les vues qui retournent à l'utilisateur une réponse en fonction de ses entrées
Préserver cette séparation de rôles permet de créer un code clair, testable et facile à gérer

3. Comprendre le système de routage des requêtes dans ASP.NET Core :

Une url comme https://localhost:1234/Toto/Blabla a comme données de routage "Toto" (le


contrôleur) et "Blabla" (la méthode d'action à appeler sur le contrôleur "Toto").

https://localhost:1234/Voiture/Edite/55 est donc une demande de modification adressée au


contrôleur "Voiture" pour lui demander de modifier la voiture 55

Le format de routage des requêtes est défini dans la méthode Configure() du fichier Startup.cs :

routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");

4. Ajouter un contrôleur

 Allez dans l'explorateur de solutions


 Faites un clique droit sur Contrôleurs > Ajouter > Contrôleur

3/15
Module au choix : Programmation .Net/C# ENIT AU 2020/2021

 Choisissez "Contrôleur MVC - vide" dans la fenêtre qui suit

 Tapez le nom du contrôleur: "VoituresController"

 Collez le code suivant dans VoituresController.cs :


using Microsoft.AspNetCore.Mvc;
using System.Text.Encodings.Web;

namespace Voitures.Controllers
{
public class VoituresController : Controller
{
public string Index()
{
return "Liste des voitures";
}

4/15
Module au choix : Programmation .Net/C# ENIT AU 2020/2021

public string ListeCollectionneurs()


{
return "Liste des collectionneurs de vieilles voitures";
}
}
}
Dans votre navigateur tapez "https://localhost:44333/Voitures" dans la barre d'adresses (remplacez
44333 par le bon numéro de port) : vous atterrirez sur la méthode d'action "Index" du contrôleur
"Voitures" et vous obtiendrez comme réponse :

Tapez maintenant https://localhost:44333/Voitures/ListeCollectionneurs : vous atterrirez sur la


méthode d'action "ListeCollectionneurs" du contrôleur "Voitures" et vous obtiendrez comme
réponse :

Nous voulons maintenant les collectionneurs de la marque de voitures Peugeot année 1975
Nous allons devoir passer deux arguments à la méthode ListeCollectionneurs() : marque et année

public string ListeCollectionneurs(string marque, int annee)


{
return $"Liste des collectionneurs de la voiture {marque} année {annee}";
}
 Dans votre navigateur tapez maintenant
https://localhost:44333/Voitures/ListeCollectionneurs?marque=peugeot&annee=1975
Vous devriez voir le message suivant :

5/15
Module au choix : Programmation .Net/C# ENIT AU 2020/2021

Jusqu'à maintenant nous avons demandé au contrôleur de retourner le résultat directement à


l'utilisateur mais l'architecture MVC implique l'utilisation de vues pour bien séparer les rôles

5. Ajouter une vue

Nous utiliserons Rasor pour créer un modèle de vue .cshtml


 Allez dans le dossier "Views" et ajoutez un nouveau dossier que vous appellerez "Voitures"
 Dans le dossier "Voitures" ajoutez un nouvel élément de type "Vue Razor"

 Collez le code suivant dans Views/Voitures/Index.cshtml :

@{
ViewData["Title"] = "Index";
}
<h2>Belle vue</h2>
<p>Liste des collectionneurs</p>

Pour charger cette vue nous allons modifier la méthode d'action Index du contrôleur
VoituresController comme ceci :

public IActionResult Index()


{
return View();
}

6/15
Module au choix : Programmation .Net/C# ENIT AU 2020/2021

Vous pouvez tester en appelant le contrôleur à l'adresse suivante :


https://localhost:44333/Voitures

La vue Index.cshtml a bien été chargée !

Nous allons maintenant ajouter une option "Liste" dans le menu principal de l'application
Ouvrez la page layout du site Views/Shared/_Layout.cshtml et ajoutez un lien href après le lien
"Home" :
<li><a asp-area="" asp-controller="Voitures" asp-action="Index">
Liste</a></li>

Vous avez remarqués les attributs "asp-controller" et "asp-action" dans les liens hrefs du menu ?
Ces attributs disent simplement à MVC quelle méthode d'action exécuter sur quel contrôleur

Les Layouts vous permettent de spécifier votre HTML dans un emplacement unique une fois pour
toute, puis de l'appliquer à plusieurs pages, MVC va chercher le fichier HTML de la vue demandée et
va l'intégrer à l'emplacement de la directive @RenderBody() du layout avant d'envoyer le résultat au
navigateur

Notre application MVC a une vue "V" et un contrôleur "C", mais pas encore de modèle "M"

Dans une application MVC le contrôleur récupère les données d'une source de données à travers un
modèle de données et détermine quelle vue envoyer au navigateur, les modèles de vue Razor ne
doivent pas exécuter de logique métier

Avant de créer le modèle de données, il est important que vous compreniez le mécanisme de
passage de données du contrôleur à la vue.

7/15
Module au choix : Programmation .Net/C# ENIT AU 2020/2021

6. Passage de données à la vue depuis le contrôleur

Nous allons modifier la méthode d'action "ListeCollectionneurs" du contrôleur "VoituresController" :


public IActionResult ListeCollectionneurs(string marque, int annee)
{
ViewData["Marque"] = marque;
ViewData["Annee"] = annee;
return View();
}

Le dictionnaire ViewData contient maintenant les données que nous voulons passer à la vue, à
savoir : la marque et l'année.

Dans le dossier "Voitures" ajoutez un nouvel élément de type "Vue Razor" et appelez-le :
ListeCollectionneurs.cshtml et collez dedans ceci :

@{
ViewData["Title"] = "Liste des collectionneurs";
}
<h2>Liste des collectionneurs</h2>
<ul>
@for (int i = (int)ViewData["annee"]; i <= DateTime.Now.Year - 20; i++)
{
<li>de <b>@ViewData["marque"]</b> année @i</li>
}
</ul>

Exécutez la méthode d'action "ListeCollectionneurs" du contrôleur "Voitures" en lui passant les


paramètres marque et année :
https://localhost:44333/Voitures/ListeCollectionneurs?marque=peugeot&annee=1975

 Supprimez maintenant le contrôleur Voitures et les vues Index et ListeCollectionneurs, nous


allons les générer automatiquement lors de la prochaine étape :
\Controllers\VoituresController.cs
\Views\Voitures\Index.cshtml
\Views\Voitures\ListeCollectionneurs.cshtml
 Supprimez aussi l'entrée "Liste" du menu

8/15
Module au choix : Programmation .Net/C# ENIT AU 2020/2021

7. Ajouter un modèle

Nous allons utiliser le framework de mapping relationnel d'objets: Entity Framework Core
 Ajoutez une classe "Voiture.cs" dans le dossier Models (Ce sera notre modèle de données)

using System;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;

namespace Voitures.Models
{
public class Voiture
{
public int Id { get; set; }
public string Nom { get; set; }
public string Marque { get; set; }
[Column(TypeName = "decimal(18, 2)")]
public decimal Prix { get; set; }
[Display(Name = "Date de fabrication")]
[DataType(DataType.Date)]
public DateTime DateFabrication { get; set; }
}
}
Nous avons utilisé l'attribut DataType sur le champ DateFabrication pour spécifier le type de données
Date au lieu de DateTime, l'utilisateur n'a pas besoin de saisir l'heure à laquelle la voiture a été
fabriquée
L'attribut Display spécifie un nom alternatif à afficher pour le nom du champ (dans le cas présent,
"Date de fabrication" au lieu de "DateFabrication").
L'attribut Column est nécessaire pour qu'Entity Framework Core puisse mapper le champ Prix en
devise dans la base de données
Nous avons notre classe de définition, nous allons maintenant générer le modèle pour les opérations
CRUD de base (création, lecture, mise à jour et suppression)
Dans l'explorateur de solutions faites un clique droit sur Contrôleurs > Ajouter > Nouvel élément
généré automatiquement

Sélectionnez "Contrôleur MVC avec vues utilisant Entity Framework"

9/15
Module au choix : Programmation .Net/C# ENIT AU 2020/2021

 Renseignez les informations demandées dans la boîte de dialogue


o Classe de modèle : Voiture (Voitures.Models)
o Classe de contexte de données : Voitures.Models.VoituresDBContext

o Nom du contrôleur : VoituresController

10/15
Module au choix : Programmation .Net/C# ENIT AU 2020/2021

Visual Studio a créé :


 Une classe de contexte de données Entity Framework Core (Data/VoituresDBContext.cs)
 Un contrôleur (Controllers/VoituresController.cs)
 Des fichiers de vues Razor pour les opérations CRUD (Views/Voitures/*.cshtml)

Maintenant il faut ajouter une migration initiale


Attention : il faut ajouter la migration initiale seulement si la base de données n'existe pas ; c'est
notre cas maintenant
 Démarrez la "Console du gestionnaire de package" Outils > Gestionnaire de package NuGet >
Console du gestionnaire de package

 Tapez les commandes suivantes à l'invite de commandes :

Add-Migration Initial
Update-Database

La commande Add-Migration va générer le code de création du schéma de la base de données, ce


schéma est basé sur le modèle de données que vous avez spécifié dans la classe Voiture.cs

11/15
Module au choix : Programmation .Net/C# ENIT AU 2020/2021

La commande Update-Database exécute la méthode Up() de la classe Migrations/###_InitialCreate.cs


cela va entraîner la création de la base de données

Allez voir dans Startup.cs : le contexte de la base de données est inscrit au démarrage de l'application
par un mécanisme d'injection de dépendances, il sera passé ultérieurement aux contrôleurs des
pages Rasor qui en ont besoin

La chaine de connexion sql est stockée dans appsettings.json


Allez voir VoituresController.cs

Le contexte de base de données a été passé au contrôleur car il sera utilisé dans chacune des
méthodes CRUD

12/15
Module au choix : Programmation .Net/C# ENIT AU 2020/2021

 Examinez maintenant le contenu du fichier de vue : Views/Voitures/Index.cshtml :

@model IEnumerable<GestionVoitures.Models.Voiture>
...
@foreach (var item in Model) {

L'instruction @model en haut du fichier de vue sert à spécifier le type d'objet attendu par la vue et
permet d'accéder aux voitures que le contrôleur a passées à la vue en utilisant un objet fortement
typé (Model)
Dans le menu Affichage, ouvrez l'Explorateur d'objets SQL Server et vérifiez que la base de données
VoituresDBContext a bien été créée

8. Peupler la base de données

Maintenant nous allons peupler la base de données avec une liste de voitures
 Créez une classe SeedData.cs dans Models

using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using System;
using System.Linq;

namespace GestionVoitures.Models
{
public static class SeedData
{
public static void Initialize(IServiceProvider serviceProvider)
{
using (var context = new VoituresDBContext(
serviceProvider.GetRequiredService<
DbContextOptions<VoituresDBContext>>()))
{
// Chercher n'importe quelle voiture.
if (context.Voiture.Any())
{
return; // la base de données est déjà peuplée
}

context.Voiture.AddRange(
new Voiture
{
Nom = "Mustang",
Marque = "Ford",
Prix = 10000,

13/15
Module au choix : Programmation .Net/C# ENIT AU 2020/2021

DateFabrication = DateTime.Parse("1966-1-12")
},
new Voiture
{
Nom = "T",
Marque = "Ford",
Prix = 10000,
DateFabrication = DateTime.Parse("1911-1-12")
},
new Voiture
{
Nom = "4L",
Marque = "Renault",
Prix = 10000,
DateFabrication = DateTime.Parse("1968-1-12")
},
new Voiture
{
Nom = "1000",
Marque = "Sicma",
Prix = 10000,
DateFabrication = DateTime.Parse("1968-1-12")
},
new Voiture
{
Nom = "Traction",
Marque = "Citroen",
Prix = 10000,
DateFabrication = DateTime.Parse("1938-1-12")
}
);
context.SaveChanges();
}
}
}

Remplacez la fonction main() de Program.cs par ceci :


using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore;
using Microsoft.AspNetCore.Hosting;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;

namespace GestionVoitures
{
public class Program
{
public static void Main(string[] args)
{
var host = CreateWebHostBuilder(args).Build();
using (var scope = host.Services.CreateScope())
{
var services = scope.ServiceProvider;
try
{
var context =
services.GetRequiredService<GestionVoitures.Models.VoituresDBContext>();
context.Database.Migrate();
GestionVoitures.Models.SeedData.Initialize(services);
}
catch (Exception ex)

14/15
Module au choix : Programmation .Net/C# ENIT AU 2020/2021

var logger = services.GetRequiredService<ILogger<Program>>();


logger.LogError(ex, "Une erreur lors de la population de la base de
données");
}
}
host.Run();
}

public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>


WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>();
}
}

Exécutez le programme
La base de données a été peuplée avec AddRange, si la base est déjà peuplée il ne se passera rien
Dans le menu Affichage, ouvrez l'Explorateur d'objets SQL Server et vérifiez que la base de données a
bien été peuplée

Maintenant démarrez l'application : https://localhost:0000/Voitures


L'application affiche normalement les données de la base

15/15

Vous aimerez peut-être aussi