Gérer les requêtes avec des contrôleurs dans ASP.NET Core MVC
Par Steve Smith et Scott Addie
Les contrôleurs, les actions et les résultats des actions sont une part fondamentale dans la façon dont les développeurs créent des applications avec ASP.NET Core MVC.
Qu’est-ce qu’un contrôleur ?
Un contrôleur est utilisé pour définir et regrouper un ensemble d’actions. Une action (ou méthode d’action) est une méthode sur un contrôleur qui gère les demandes. Les contrôleurs regroupent de façon logique des actions similaires. Cette agrégation des actions permet l’application collective de jeux de règles communs, comme le routage, la mise en cache et les autorisations. Les demandes sont mappées à des actions via un routage. Les contrôleurs sont activés et supprimés en fonction des requêtes.
Par convention, les classes de contrôleur :
- Se trouvent dans le dossier Controllers au niveau de la racine du projet.
- Héritez de
Microsoft.AspNetCore.Mvc.Controller
.
Un contrôleur est une classe instanciable, habituellement publique, dans laquelle au moins une des conditions suivantes est vraie :
- Le nom de classe a comme suffixe
Controller
. - La classe hérite d’une classe dont le nom est suivi du suffixe
Controller
. - L’attribut
[Controller]
est appliqué à la classe.
Une classe de contrôleur ne doit pas avoir d’attribut [NonController]
associé.
Les contrôleurs doivent suivre le principe de dépendances explicites. Il existe deux approches pour implémenter ce principe. Si plusieurs actions de contrôleur nécessitent le même service, envisagez d’utiliser l’injection de constructeur pour demander ces dépendances. Si le service est nécessaire pour une seule méthode d’action, envisagez d’utiliser l’injection d’action pour demander la dépendance.
Dans le Modèle-Vue-Contrôleur, un contrôleur est responsable du traitement initial de la demande et de l’instanciation du modèle. En règle générale, les décisions métier doivent être prises dans le modèle.
Le contrôleur prend le résultat du traitement du modèle (le cas échéant) et retourne la vue appropriée et les données associées à cette vue, ou bien le résultat de l’appel d’API. Pour en savoir plus, consultez Vue d’ensemble d’ASP.NET Core MVC et Bien démarrer avec ASP.NET Core MVC et Visual Studio.
Le contrôleur est une abstraction au niveau de l’interface utilisateur. Ses responsabilités sont de garantir que les données de la demande sont valides et de choisir la vue (ou le résultat d’API) à retourner. Dans les applications bien construites, il n’inclut pas directement l’accès aux données ni la logique métier. Au lieu de cela, le contrôleur délègue à des services la gestion de ces responsabilités.
Définition des actions
Les méthodes publiques sur un contrôleur, sauf celles avec l’attribut [NonAction]
, sont des actions. Les paramètres sur les actions sont liés aux données des demandes et sont validés avec la liaison de modèle. La validation du modèle est effectuée pour tout ce qui est lié au modèle. La valeur de la propriété ModelState.IsValid
indique si la liaison de modèle et la validation ont réussi.
Les méthodes d’action doivent contenir la logique nécessaire pour mapper une demande à un problème métier. Les problèmes métier doivent généralement être représentés comme des services auxquels le contrôleur accède via l’injection de dépendances. Les actions mappent ensuite le résultat de l’action métier à un état de l’application.
Les actions peuvent retourner des valeurs de n’importe quel type, mais elles retournent souvent une instance de IActionResult
(ou de Task<IActionResult>
pour les méthodes asynchrones) qui produit une réponse. La méthode d’action est responsable du choix du type de réponse. Le résultat de l’action constitue la réponse.
Méthodes helper des contrôleurs
Les contrôleurs héritent généralement de la classe Controller, bien que ce ne soit pas obligatoire. Le fait de dériver de Controller
fournit l’accès à trois catégories de méthodes helper :
1. Méthodes aboutissant à un corps de réponse vide
Aucune en-tête de réponse HTTP Content-Type
n’est présente, étant donné que le corps de la réponse n’a pas de contenu à décrire.
Il existe deux types de résultats dans cette catégorie : Redirection et Code d’état HTTP.
Code d’état HTTP
Ce type retourne un code d’état HTTP.
BadRequest
,NotFound
etOk
sont des méthodes helper de ce type. Par exemple,return BadRequest();
produit un code d’état 400 quand elle est exécutée. Quand des méthodes commeBadRequest
,NotFound
etOk
sont surchargées, elles ne sont plus qualifiées comme répondeurs de code d’état HTTP, étant donné que la négociation du contenu est en cours.Rediriger
Ce type retourne une redirection vers une action ou une destination (avec
Redirect
,LocalRedirect
,RedirectToAction
ouRedirectToRoute
). Par exemple,return RedirectToAction("Complete", new {id = 123});
redirige versComplete
, en passant un objet anonyme.Le type de résultat Redirection diffère du type Code d’état HTTP principalement par l’ajout d’un en-tête de réponse HTTP
Location
.
2. Méthodes aboutissant à un corps de réponse de non-vide avec un type de contenu prédéfini
La plupart des méthodes helper de cette catégorie incluent une propriété ContentType
, qui vous permet de définir l’en-tête de réponse Content-Type
pour décrire le corps de la réponse.
Il existe deux types de résultats dans cette catégorie : Vue et Réponse mise en forme.
Afficher
Ce type retourne une vue qui utilise un modèle pour rendre le HTML. Par exemple,
return View(customer);
passe un modèle à la vue pour la liaison de données.Réponse mise en forme
Ce type retourne un format JSON ou un format d’échange de données similaire pour représenter un objet d’une manière spécifique. Par exemple,
return Json(customer);
sérialise l’objet fourni au format JSON.File
etPhysicalFile
sont des méthodes courantes de ce type. Par exemple,return PhysicalFile(customerFilePath, "text/xml");
retourne PhysicalFileResult.
3. Méthodes aboutissant à un corps de réponse non-vide mise en forme selon un type de contenu négocié avec le client
Cette catégorie est plus connue sous le nom de Négociation de contenu. La négociation de contenu s’applique chaque fois qu’une action retourne un type ObjectResult ou quelque chose d’autre qu’une implémentation de IActionResult. Une action qui retourne une implémentation autre que IActionResult
(par exemple object
) retourne également une Réponse mise en forme.
BadRequest
, CreatedAtRoute
et Ok
sont des méthodes helper de ce type. return BadRequest(modelState);
, return CreatedAtRoute("routename", values, newobject);
et return Ok(value);
sont des exemples respectifs de ces méthodes. Notez que BadRequest
et Ok
effectuent une négociation de contenu seulement quand ils reçoivent une valeur ; si aucune valeur ne leur est passée, ils délivrent à la place des types de résultats Code d’état HTTP. La méthode CreatedAtRoute
effectue quant à elle toujours une négociation de contenu, car ses surcharges nécessitent toutes qu’une valeur soit passée.
Problèmes transversaux
En règle générale, les applications partagent des parties de leur flux de travail. C’est par exemple le cas d’une application qui exige une authentification pour l’accès au panier d’achat ou qui met en cache les données de certaines pages. Pour exécuter la logique avant ou après une méthode d’action, utilisez un filtre. L’utilisation de Filtres sur les problèmes transversaux peut réduire la duplication.
La plupart des attributs des filtres, comme [Authorize]
, peuvent être appliqués au niveau du contrôleur ou de l’action, selon le niveau de granularité souhaité.
La gestion des erreurs et la mise en cache des réponses sont souvent des problèmes transversaux :
De nombreux problèmes transversaux peuvent être gérés en utilisant des filtres ou un intergiciel (middleware) personnalisé.