Aller au contenu principal

Notre premier contrôleur

Notions théoriques

Rôle du contrôleur

Un contrôleur est une classe C# qui reçoit les requêtes HTTP, effectue un traitement (appel à la base de données, validation...) et retourne une réponse (vue HTML, JSON, redirection...).

Dans ASP.NET Core MVC, chaque contrôleur hérite de la classe Controller :

// Controllers/ArticlesController.cs
using Microsoft.AspNetCore.Mvc;

public class ArticlesController : Controller
{
// Chaque méthode publique = une action = une URL
public IActionResult Index()
{
return View(); // Retourne Views/Articles/Index.cshtml
}
}
Comparaison avec Symfony et Spring Boot
FrameworkDéclaration contrôleur
ASP.NET Core MVCpublic class ArticlesController : Controller
Symfonyclass ArticlesController extends AbstractController
Spring Boot@Controller public class ArticlesController

Dans les trois cas, la classe contrôleur gère les requêtes HTTP et délègue l'affichage à un système de templates.

Le type de retour IActionResult

IActionResult est l'interface commune à tous les types de réponses possibles :

MéthodeDescriptionÉquivalent HTTP
return View()Affiche une vue Razor200 OK + HTML
return View("NomVue", modele)Vue spécifique avec données200 OK + HTML
return RedirectToAction("Index")Redirige vers une action302 Redirect
return NotFound()Ressource introuvable404 Not Found
return BadRequest()Requête invalide400 Bad Request

Passer des données à la vue

Trois mécanismes permettent de transmettre des données du contrôleur à la vue :

1. ViewBag (dynamique, simple) :

ViewBag.Titre = "Liste des articles";
ViewBag.NombreArticles = 42;
return View();

2. ViewData (dictionnaire, similaire à ViewBag) :

ViewData["Titre"] = "Liste des articles";
return View();

3. Modèle fortement typé (recommandé pour les données complexes) :

var articles = new List<string> { "Article 1", "Article 2" };
return View(articles); // Le modèle est passé en paramètre
ViewBag vs Modèle typé

ViewBag et ViewData sont pratiques pour de petites informations (titre de page, message flash). Pour des données complexes (liste d'articles, objet Article), préférez toujours un modèle fortement typé — vous bénéficiez de la vérification de type à la compilation et de l'autocomplétion.

La convention de routage

Par défaut, ASP.NET Core mappe automatiquement les URLs aux contrôleurs/actions :

URL → Contrôleur → Action
/ → HomeController → Index()
/Articles → ArticlesController → Index()
/Articles/Details → ArticlesController → Details()
/Articles/Details/5 → ArticlesController → Details(5)
/Articles/Edit/3 → ArticlesController → Edit(3)
Comparaison avec Symfony et Spring Boot
// Symfony : attribut #[Route]
#[Route('/articles', name: 'articles_index')]
public function index(): Response { ... }
// Spring Boot : annotation @GetMapping
@GetMapping("/articles")
public String index(Model model) { ... }
// ASP.NET Core MVC : convention (pas d'annotation nécessaire)
// /Articles/Index → ArticlesController.Index()
public IActionResult Index() { return View(); }

Controller vs ControllerBase

ClasseUsageRetour
ControllerMVC avec vues RazorIActionResult (HTML)
ControllerBaseAPI REST sans vuesActionResult<T> (JSON)

Dans ce cours MVC, nous utilisons toujours Controller. La séance 540 abordera ControllerBase pour les API REST.

Exemple pratique

Voici un contrôleur ArticlesController complet avec trois actions :

// Controllers/ArticlesController.cs
using Microsoft.AspNetCore.Mvc;

public class ArticlesController : Controller
{
// GET /Articles ou GET /Articles/Index
public IActionResult Index()
{
// Données temporaires (avant la base de données)
var articles = new List<string>
{
"Mon premier article",
"Bienvenue sur MonBlog",
"ASP.NET Core MVC en pratique",
};

// Passage d'info complémentaire via ViewBag
ViewBag.Titre = "Tous les articles";

// Passage du modèle à la vue
return View(articles);
}

// GET /Articles/Details/5
public IActionResult Details(int id)
{
// Simulation : on retourne un article fictif
if (id <= 0)
{
return NotFound(); // 404
}

ViewBag.ArticleId = id;
return View("Details", $"Contenu de l'article #{id}");
}

// GET /Articles/Create
public IActionResult Create()
{
return View();
}
}
astuce

Nommez toujours vos contrôleurs avec le suffixe Controller : ArticlesController, HomeController. ASP.NET Core utilise cette convention pour le routing automatique.

Test de mémorisation/compréhension


De quelle classe doit hériter un contrôleur ASP.NET Core MVC avec vues Razor ?


Quelle méthode retourne une vue Razor avec un modèle de données ?


Vers quelle URL est routée l'action Details(int id) du contrôleur ArticlesController ?


Quelle méthode retourne une réponse 404 Not Found ?


Quelle est la différence principale entre Controller et ControllerBase ?


Quel mécanisme est recommandé pour passer des données complexes (liste d'objets) du contrôleur à la vue ?


TP pour réfléchir et résoudre des problèmes

Vous allez créer le contrôleur ArticlesController de MonBlog avec ses premières actions.

Étape 1 — Créer le fichier ArticlesController.cs

Créez le fichier Controllers/ArticlesController.cs avec la structure de base.


Bonne pratique - Un fichier par contrôleur

Placez chaque contrôleur dans son propre fichier dans le dossier Controllers/. Nommez le fichier exactement comme la classe : ArticlesController.cs pour ArticlesController. C'est la convention .NET universelle.

Étape 2 — Ajouter l'action Index avec une liste d'articles


Bonne pratique - Modèle typé plutôt que ViewBag

Passez les données principales en paramètre de View(). Réservez ViewBag aux données secondaires (titre de page, messages flash). Un modèle fortement typé permet à Razor d'offrir l'autocomplétion et de détecter les erreurs à la compilation.

Étape 3 — Ajouter l'action Details avec gestion du 404


Bonne pratique - Toujours valider les paramètres d'URL

Un utilisateur peut manipuler l'URL pour passer des valeurs inattendues (id négatif, id inexistant...). Validez toujours les paramètres avant d'effectuer des requêtes en base de données. Cela protège à la fois contre les erreurs et les tentatives de manipulation.

📌 Une solution