Table of Contents
L'architecture Model-View-Controller (MVC) est un modèle de conception éprouvé dans le temps qui sépare les préoccupations au sein d'une application web, ce qui facilite la gestion de la complexité, teste les composants en isolement et les fonctionnalités d'échelle au fil du temps. Dans ASP.NET Core, MVC est un citoyen de première classe, fournissant un cadre solide pour construire des applications web modernes et durables.
Comprendre le modèle MVC en profondeur
Avant de plonger dans le code, il est essentiel de comprendre comment les trois composantes de base de MVC collaborent pour traiter une demande d'utilisateur. Le modèle définit clairement les responsabilités:
- Modèle: Représente la structure des données et les règles d'affaires. Il ne sait pas comment les données sont affichées ou l'interface utilisateur. Les modèles sont généralement des classes C# simples qui encapsulent les propriétés, la logique de validation et l'accès aux données (souvent via Entity Framework Core).
- View: Renforce l'interface utilisateur. Dans ASP.NET Core, les vues sont des fichiers Razor (`.cshtml`) qui combinent le balisage HTML avec le code C# côté serveur. Les vues ne doivent afficher que des données, pas contenir une logique complexe.
- Controller: agit en tant qu'intermédiaire. Il reçoit les requêtes HTTP, décide quel modèle utiliser et sélectionne la vue appropriée pour retourner. Les contrôleurs contiennent des méthodes d'action qui mapent sur des itinéraires spécifiques.
Le flux de requête typique dans ASP.NET Core MVC : un utilisateur navigue vers une URL (par exemple, ), le middleware de routage dirige la requête vers l'action , l'action interagit avec le modèle (par exemple, récupère des produits d'une base de données), charge les données dans un modèle de vue et les transmet à la vue. La vue génère ensuite une réponse HTML renvoyée au client.
Préalables
- .NET SDK (version 6.0 ou ultérieure). Télécharger à partir de dotnet.microsoft.com.
- Visual Studio[, Visual Studio Code[, ou tout éditeur de code préféré.
- Connaissance de base des concepts de développement C# et web.
Étape 1: Création d'un nouveau projet de base de CVM ASP.NET
Vous pouvez commencer par le .NET CLI ou Visual Studio. Les deux fournissent un modèle de projet qui échafaude la structure standard de dossier MVC.
Utilisation de la ligne de commande
Ouvrez un terminal et lancez :
dotnet new mvc -n MyMvcApp
Cela crée un projet nommé dans un nouveau dossier. La structure générée comprend , , et (pour les fichiers statiques).
Utilisation de Visual Studio
Dans Visual Studio, choisissez Créer un nouveau projet → sélectionner ASP.NET Core Web App (Model-View-Controller) → configurer le nom et l'emplacement de votre projet → choisir la version .NET (par exemple, .NET 8). Les mêmes dossiers sont créés automatiquement.
Vérifier que le projet fonctionne :
cd MyMvcApp
dotnet run
Ouvrez pour voir la page d'accueil par défaut.
Étape 2 : Comprendre la structure du projet
Le projet échafaudé contient plusieurs éléments clés :
- Contrôleurs: Dossier vide où vous ajouterez des classes de contrôleur C#.
- Modèles: Placez pour vos classes de domaine et visualisez les modèles.
- Vues: A un dossier et par défaut, plus une mise en page .
- Program.cs: Mise en service de l'application, où les services (y compris MVC) sont configurés.
Ouvrez et notez les lignes qui permettent MVC:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllersWithViews();
var app = builder.Build();
...
app.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
app.Run();
Cela définit la route par défaut qui map des URLs comme à .
Étape 3: Création d'une classe de modèle
Les modèles représentent les données avec lesquelles votre application fonctionne. Commencez par créer un modèle à l'intérieur du dossier .
// Models/Product.cs
namespace MyMvcApp.Models;
public class Product
{
public int Id { get; set; }
public string Name { get; set; } = string.Empty;
public decimal Price { get; set; }
public string? Description { get; set; }
public DateTime CreatedAt { get; set; } = DateTime.UtcNow;
}
Vous pouvez enrichir les modèles avec des annotations de données pour la validation:
using System.ComponentModel.DataAnnotations;
public class Product
{
public int Id { get; set; }
[Required(ErrorMessage = "Product name is required.")]
[StringLength(100)]
public string Name { get; set; } = string.Empty;
[Range(0.01, 10000)]
public decimal Price { get; set; }
[MaxLength(500)]
public string? Description { get; set; }
[Display(Name = "Created")]
public DateTime CreatedAt { get; set; }
}
Dans une application réelle, vous ajoutez généralement un contexte de base de données (Cadre d'entité) pour persister des modèles. Pour ce guide, nous utiliserons des données en mémoire pour garder l'accent sur le flux MVC.
Étape 4: Ajout d'un contrôleur
Les contrôleurs gèrent les requêtes entrantes et orchestrent la réponse. Créez un à l'intérieur du dossier .
// Controllers/ProductsController.cs
using Microsoft.AspNetCore.Mvc;
using MyMvcApp.Models;
using System.Collections.Generic;
namespace MyMvcApp.Controllers;
public class ProductsController : Controller
{
// Simulate a data source
private static List<Product> _products = new List<Product>
{
new Product { Id = 1, Name = "Laptop", Price = 999.99m },
new Product { Id = 2, Name = "Smartphone", Price = 599.99m },
new Product { Id = 3, Name = "Tablet", Price = 399.99m }
};
// GET: /Products
public IActionResult Index()
{
return View(_products); // Pass list to the view
}
// GET: /Products/Details/5
public IActionResult Details(int id)
{
var product = _products.Find(p => p.Id == id);
if (product == null)
return NotFound();
return View(product);
}
// GET: /Products/Create
public IActionResult Create()
{
return View();
}
// POST: /Products/Create
[HttpPost]
[ValidateAntiForgeryToken]
public IActionResult Create(Product product)
{
if (ModelState.IsValid)
{
product.Id = _products.Max(p => p.Id) + 1;
product.CreatedAt = DateTime.UtcNow;
_products.Add(product);
return RedirectToAction(nameof(Index));
}
return View(product);
}
}
Points clés:
- IActionRésultat est le type de retour. Il peut être un , , , etc.
- Action nomm une carte pour afficher dans un dossier nommé d'après le contrôleur ().
- L'action comporte deux surcharges : une pour GET (affichage du formulaire) et une pour POST (manipulation de la soumission du formulaire).
- protège contre la contrefaçon de demandes croisées.
Étape 5: Création de vues avec Razor Syntax
Les vues sont en direct . La mise en page partagée est en .
Affichage de l'index – Afficher une liste
Créer :
@model IEnumerable<MyMvcApp.Models.Product>
@{
ViewData["Title"] = "Product List";
}
<h2>@ViewData["Title"]</h2>
<table class="table table-striped">
<thead>
<tr>
<th>@Html.DisplayNameFor(model => model.Id)</th>
<th>@Html.DisplayNameFor(model => model.Name)</th>
<th>@Html.DisplayNameFor(model => model.Price)</th>
<th></th>
</tr>
</thead>
<tbody>
@foreach (var item in Model)
{
<tr>
<td>@item.Id</td>
<td>@item.Name</td>
<td>@item.Price.ToString("C")</td>
<td>
<a asp-action="Details" asp-route-id="@item.Id">Details</a>
</td>
</tr>
}
</tbody>
</table>
<p>
<a asp-action="Create" class="btn btn-primary">Create New Product</a>
</p>
Conseils de rasoir[ : Utilisez pour passer du HTML au C#, et / pour générer des URL.
Détails Vue
Créer :
@model MyMvcApp.Models.Product
@{
ViewData["Title"] = "Product Details";
}
<h2>@Model.Name</h2>
<dl class="row">
<dt class="col-sm-2">@Html.DisplayNameFor(model => model.Id)</dt>
<dd class="col-sm-10">@Model.Id</dd>
<dt class="col-sm-2">@Html.DisplayNameFor(model => model.Price)</dt>
<dd class="col-sm-10">@Model.Price.ToString("C")</dd>
<dt class="col-sm-2">@Html.DisplayNameFor(model => model.Description)</dt>
<dd class="col-sm-10">@Model.Description</dd>
<dt class="col-sm-2">@Html.DisplayNameFor(model => model.CreatedAt)</dt>
<dd class="col-sm-10">@Model.CreatedAt</dd>
</dl>
<a asp-action="Index">Back to List</a>
Créer une vue avec le formulaire
Créer :
@model MyMvcApp.Models.Product
@{
ViewData["Title"] = "Create Product";
}
<h2>Create</h2>
<form asp-action="Create">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<div class="form-group">
<label asp-for="Name"></label>
<input asp-for="Name" class="form-control" />
<span asp-validation-for="Name" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Price"></label>
<input asp-for="Price" class="form-control" />
<span asp-validation-for="Price" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Description"></label>
<textarea asp-for="Description" class="form-control"></textarea>
</div>
<button type="submit" class="btn btn-primary">Create</button>
<a asp-action="Index" class="btn btn-secondary">Cancel</a>
</form>
@section Scripts {
@{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
}
Les helpers de tag Razor comme génèrent des champs de formulaire avec fixation et validation du modèle. charge des scripts de validation côté client.
Étape 6 : Ajout d'itinéraires et de routes personnalisées
MVC utilise le routage par convention par défaut. La route dans maps . Vous pouvez également ajouter le routage des attributs pour plus de contrôle. Par exemple, dans le contrôleur :
[Route("products")]
public class ProductsController : Controller
{
[Route("")] // matches /products
[Route("index")] // matches /products/index
public IActionResult Index() { ... }
[Route("{id:int}")] // matches /products/5
public IActionResult Details(int id) { ... }
}
Cette approche est utile pour les API RESTful lorsqu'elles sont combinées avec .
Étape 7 : Utilisation de modèles de vue pour des données complexes
Souvent, vous devez passer plus d'un objet de données à une vue, ou inclure des propriétés supplémentaires (comme sélectionner des listes, titres de page). C'est là que les modèles de vue entrent en jeu.
namespace MyMvcApp.Models.ViewModels;
public class ProductIndexViewModel
{
public IEnumerable<Product> Products { get; set; }
public string SearchString { get; set; } = string.Empty;
public decimal MaxPrice { get; set; } = 10000;
}
Ensuite, ajustez l'action du contrôleur pour peupler le modèle de vue et le passer à la vue. La vue utilise et accède aux propriétés en conséquence.
Étape 8: Validation de la mise en œuvre
ASP.NET Core MVC fournit une validation côté serveur et côté client via des annotations de données. Ajouter , , et des attributs personnalisés. Dans la vue , le affiche des messages d'erreur. L'attribut de l'action POST garantit que seules les présentations de formulaires authentiques sont traitées.
Pour une logique de validation personnalisée, implémentez sur votre modèle ou créez une classe de validation séparée. La documentation officielle ASP.NET Core validation documentation[ couvre ces modèles en détail.
Étape 9: Injection de dépendance dans les contrôleurs
Au lieu de coder les données, vous pouvez injecter des services (comme un dépôt ou un contexte de base de données) dans le constructeur du contrôleur.
public class ProductsController : Controller
{
private readonly IProductRepository _repository;
public ProductsController(IProductRepository repository)
{
_repository = repository;
}
public IActionResult Index()
{
var products = _repository.GetAll();
return View(products);
}
}
Enregistrez le dépôt dans :
builder.Services.AddScoped<IProductRepository, ProductRepository>();
La méthode enregistre déjà les contrôleurs pour DI. Ce modèle rend votre application plus propre et plus durable. Voir Microsoft's Dependency Injection guide[ pour plus d'informations.
Étape 10: Travailler avec les mises en page et les opinions partielles
Pour personnaliser, modifier le dans . Vous pouvez définir des sections ou utiliser des vues partielles pour les composants réutilisables de l'interface utilisateur comme les fonctions de navigation, de pied de page ou de rendu de cartes de produits.
Exemple de vue partielle :
@model Product
<div class="card">
<div class="card-body">
<h5 class="card-title">@Model.Name</h5>
<p class="card-text">Price: @Model.Price.ToString("C")</p>
<a asp-action="Details" asp-route-id="@Model.Id" class="btn btn-primary">Details</a>
</div>
</div>
Inclure-le dans toute vue avec .
Étape 11 : Gestion des erreurs et codes de statut
Les contrôleurs doivent gérer les erreurs avec grâce. Utilisez des blocs ou un gestionnaire d'exception global via un middleware. Retournez les codes d'état HTTP appropriés :
- pour 404
- pour 400
- pour les erreurs de serveur.
Vous pouvez également ajouter une vue d'erreur personnalisée : est déjà inclus dans le modèle. Définissez dans pour rediriger sur les exceptions dans la production.
Étape 12: Essai de l'application MVC
Les tests sont critiques. Utilisez xUnit et le paquet pour écrire des tests d'intégration. Exemple pour l'action :
public class ProductsControllerTests : IClassFixture<WebApplicationFactory<Program>>
{
private readonly HttpClient _client;
public ProductsControllerTests(WebApplicationFactory<Program> factory)
{
_client = factory.CreateClient();
}
[Fact]
public async Task Index_ReturnsSuccessAndCorrectContentType()
{
var response = await _client.GetAsync("/products");
response.EnsureSuccessStatusCode();
Assert.Equal("text/html; charset=utf-8",
response.Content.Headers.ContentType.ToString());
}
}
L'unité teste le contrôleur avec des services simulés pour isoler la logique. La documentation ASP.NET Core testing documentation[ fournit des exemples exhaustifs.
Meilleures pratiques et conseils avancés
- Garder les contrôleurs minces: La logique d'affaires appartient aux services/dépôts, et non aux méthodes d'action.
- Utiliser les modèles de vue: Évitez de passer directement les modèles de domaine aux vues; utilisez des modèles de vue dédiés pour façonner les données au besoin.
- Aides à gagner : Elles font un nettoyage HTML et réduisent les erreurs de fixation de forme.
- Activer la validation côté client[ : Inclure et des paquets (déjà dans .
- Utiliser des actions asynchrones pour les opérations liées à des E/S : avec .
- Sécurisez votre application: Utilisez toujours HTTPS, jetons anti-forgery sur les formulaires POST, et autorisation basée sur le rôle via .
Conclusion
En séparant les modèles, les vues et les contrôleurs, vous pouvez travailler sur chaque composant de façon indépendante et à l'échelle de votre application avec confiance. Les étapes de ce guide permettent de passer d'une création de projet à des modèles prêts à la production. Commencez par un projet simple, puis ajoutez progressivement l'intégration de la base de données, l'authentification et les fonctionnalités avancées. Le ASP.NET Core MVC panorama est une excellente ressource suivante à mesure que vous approfondissez vos connaissances.