Remarque
L’accès à cette page requiert une autorisation. Vous pouvez essayer de vous connecter ou de modifier des répertoires.
L’accès à cette page requiert une autorisation. Vous pouvez essayer de modifier des répertoires.
Par Steve Smith
ASP.NET Core MVC définit un modèle d’application représentant les composants d’une application MVC. Lisez et manipulez ce modèle pour modifier le comportement des éléments MVC. Par défaut, MVC suit certaines conventions pour déterminer quelles classes sont considérées comme des contrôleurs, quelles méthodes sur ces classes sont des actions et comment les paramètres et le routage se comportent. Personnalisez ce comportement en fonction des besoins d’une application en créant des conventions personnalisées et en les appliquant globalement ou en tant qu’attributs.
Modèles et fournisseurs (IApplicationModelProvider)
Le modèle d’application Core MVC ASP.NET inclut des interfaces abstraites et des classes d’implémentation concrètes qui décrivent une application MVC. Ce modèle est le résultat de la découverte des contrôleurs, actions, paramètres d’action, itinéraires et filtres de l’application en fonction des conventions par défaut. En travaillant avec le modèle d’application, modifiez une application pour suivre différentes conventions du comportement MVC par défaut. Les paramètres, noms, itinéraires et filtres sont tous utilisés comme données de configuration pour les actions et les contrôleurs.
Le modèle d’application MVC core ASP.NET a la structure suivante :
- ApplicationModel
- Contrôleurs (ControllerModel)
- Actions (Modèle d'Action)
- Paramètres (ParameterModel)
- Actions (Modèle d'Action)
- Contrôleurs (ControllerModel)
Chaque niveau du modèle a accès à une collection commune Properties , et les niveaux inférieurs peuvent accéder et remplacer les valeurs de propriété définies par des niveaux supérieurs dans la hiérarchie. Les propriétés sont enregistrées dans le ActionDescriptor.Properties lorsqu'elles sont créées les actions. Ensuite, lorsqu’une demande est gérée, toutes les propriétés ajoutées ou modifiées sont accessibles via ActionContext.ActionDescriptor. L’utilisation de propriétés est un excellent moyen de configurer des filtres, des classeurs de modèles et d’autres aspects du modèle d’application en fonction de l’action.
Note
La ActionDescriptor.Properties collection n’est pas thread safe (pour les écritures) après le démarrage de l’application. Les conventions sont le meilleur moyen d’ajouter des données en toute sécurité à cette collection.
ASP.NET Core MVC charge le modèle d’application à l’aide d’un modèle de fournisseur, défini par l’interface IApplicationModelProvider . Cette section décrit quelques-uns des détails de l’implémentation interne de la façon dont ce fournisseur fonctionne. L’utilisation du modèle de fournisseur est un sujet avancé, principalement pour l’utilisation du framework. La plupart des applications doivent utiliser des conventions, et non le modèle de fournisseur.
Implémentations de l’interface IApplicationModelProvider s'« enroulent » mutuellement, où chaque implémentation appelle OnProvidersExecuting dans l’ordre croissant en fonction de leur propriété Order. La OnProvidersExecuted méthode est ensuite appelée dans l’ordre inverse. L’infrastructure définit plusieurs fournisseurs :
Tout d’abord (Order=-1000) :
DefaultApplicationModelProvider
Ensuite (Order=-990) :
AuthorizationApplicationModelProviderCorsApplicationModelProvider
Note
L’ordre dans lequel deux fournisseurs ayant la même valeur pour Order sont appelés n’est pas défini et ne doit pas être pris en compte.
Note
IApplicationModelProvider est un concept avancé destiné à être étendu par les auteurs de framework. En général, les applications doivent utiliser des conventions et les frameworks doivent utiliser des fournisseurs. La distinction clé est que les fournisseurs s’exécutent toujours avant les conventions.
Le DefaultApplicationModelProvider établit de nombreux comportements par défaut utilisés par ASP.NET Core MVC. Ses responsabilités sont les suivantes :
- Ajout de filtres globaux au contexte
- Ajout de contrôleurs au contexte
- Ajout de méthodes de contrôleur public en tant qu’actions
- Ajout de paramètres de méthode d’action au contexte
- Application de l’itinéraire et d’autres attributs
Certains comportements intégrés sont implémentés par le DefaultApplicationModelProvider. Ce fournisseur est chargé de construire le ControllerModel, qui à son tour référence les instances ActionModel, PropertyModel et ParameterModel. La DefaultApplicationModelProvider classe est un détail d’implémentation de framework interne qui peut changer à l’avenir.
AuthorizationApplicationModelProvider est responsable de l’application du comportement associé aux attributs AuthorizeFilter et AllowAnonymousFilter. Pour plus d’informations, consultez Autorisation simple dans ASP.NET Core.
Le CorsApplicationModelProvider implémente le comportement associé à IEnableCorsAttribute et IDisableCorsAttribute. Pour plus d’informations, consultez Activer les demandes d’origine croisée (CORS) dans ASP.NET Core.
Les informations sur les fournisseurs internes du framework décrits dans cette section ne sont pas disponibles via le navigateur d’API .NET. Toutefois, les fournisseurs peuvent être inspectés dans la source de référence ASP.NET Core (dépôt GitHub dotnet/aspnetcore). Utilisez la recherche GitHub pour rechercher les fournisseurs par nom et sélectionner la version de la source avec la liste déroulante Switch branches/tags .
Conventions
Le modèle d’application définit des abstractions de convention qui offrent un moyen plus simple de personnaliser le comportement des modèles que de remplacer l’ensemble du modèle ou du fournisseur. Ces abstractions sont la méthode recommandée pour modifier le comportement d’une application. Les conventions permettent d’écrire du code qui applique dynamiquement des personnalisations. Bien que les filtres fournissent un moyen de modifier le comportement de l’infrastructure, les personnalisations permettent de contrôler le fonctionnement de l’ensemble de l’application.
Les conventions suivantes sont disponibles :
- IApplicationModelConvention
- IControllerModelConvention
- IActionModelConvention
- IParameterModelConvention
Les conventions sont appliquées en les ajoutant aux options MVC ou en implémentant des attributs et en les appliquant aux contrôleurs, actions ou paramètres d’action (similaires aux filtres). Contrairement aux filtres, les conventions sont exécutées uniquement lorsque l’application démarre, et non dans le cadre de chaque requête.
Note
Pour plus d’informations sur les conventions de routage Pages et du fournisseur de modèles d’application, consultez les conventions de routage et d’application des pages dans ASP.NET Core.
Modifier le ApplicationModel
La convention suivante permet d’ajouter une propriété au modèle d’application :
using Microsoft.AspNetCore.Mvc.ApplicationModels;
namespace AppModelSample.Conventions
{
public class ApplicationDescription : IApplicationModelConvention
{
private readonly string _description;
public ApplicationDescription(string description)
{
_description = description;
}
public void Apply(ApplicationModel application)
{
application.Properties["description"] = _description;
}
}
}
Les conventions de modèle d’application sont appliquées en tant qu’options lorsque MVC est ajouté à Startup.ConfigureServices:
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc(options =>
{
options.Conventions.Add(new ApplicationDescription("My Application Description"));
options.Conventions.Add(new NamespaceRoutingConvention());
});
}
Les propriétés sont accessibles à partir de la collection ActionDescriptor.Properties au sein des actions du contrôleur.
public class AppModelController : Controller
{
public string Description()
{
return "Description: " + ControllerContext.ActionDescriptor.Properties["description"];
}
}
Modifier la ControllerModel description
Le modèle de contrôleur peut également inclure des propriétés personnalisées. Les propriétés personnalisées remplacent les propriétés existantes par le même nom spécifié dans le modèle d’application. L’attribut de convention suivant ajoute une description au niveau du contrôleur :
using System;
using Microsoft.AspNetCore.Mvc.ApplicationModels;
namespace AppModelSample.Conventions
{
public class ControllerDescriptionAttribute : Attribute, IControllerModelConvention
{
private readonly string _description;
public ControllerDescriptionAttribute(string description)
{
_description = description;
}
public void Apply(ControllerModel controllerModel)
{
controllerModel.Properties["description"] = _description;
}
}
}
Cette convention est appliquée en tant qu’attribut sur un contrôleur :
[ControllerDescription("Controller Description")]
public class DescriptionAttributesController : Controller
{
public string Index()
{
return "Description: " + ControllerContext.ActionDescriptor.Properties["description"];
}
Modifier la ActionModel description
Une convention d’attribut distincte peut être appliquée à des actions individuelles, en remplaçant le comportement déjà appliqué au niveau de l’application ou du contrôleur :
using System;
using Microsoft.AspNetCore.Mvc.ApplicationModels;
namespace AppModelSample.Conventions
{
public class ActionDescriptionAttribute : Attribute, IActionModelConvention
{
private readonly string _description;
public ActionDescriptionAttribute(string description)
{
_description = description;
}
public void Apply(ActionModel actionModel)
{
actionModel.Properties["description"] = _description;
}
}
}
L’application de ceci à une action au sein du contrôleur montre comment elle remplace la convention au niveau du contrôleur :
[ControllerDescription("Controller Description")]
public class DescriptionAttributesController : Controller
{
public string Index()
{
return "Description: " + ControllerContext.ActionDescriptor.Properties["description"];
}
[ActionDescription("Action Description")]
public string UseActionDescriptionAttribute()
{
return "Description: " + ControllerContext.ActionDescriptor.Properties["description"];
}
}
Modifier le ParameterModel
La convention suivante peut être appliquée aux paramètres d’action pour modifier leur BindingInfo. La convention suivante nécessite que le paramètre soit un paramètre d’itinéraire. D’autres sources de liaison potentielles, telles que les valeurs de chaîne de requête, sont ignorées :
using System;
using Microsoft.AspNetCore.Mvc.ApplicationModels;
using Microsoft.AspNetCore.Mvc.ModelBinding;
namespace AppModelSample.Conventions
{
public class MustBeInRouteParameterModelConvention : Attribute, IParameterModelConvention
{
public void Apply(ParameterModel model)
{
if (model.BindingInfo == null)
{
model.BindingInfo = new BindingInfo();
}
model.BindingInfo.BindingSource = BindingSource.Path;
}
}
}
L’attribut peut être appliqué à n’importe quel paramètre d’action :
public class ParameterModelController : Controller
{
// Will bind: /ParameterModel/GetById/123
// WON'T bind: /ParameterModel/GetById?id=123
public string GetById([MustBeInRouteParameterModelConvention]int id)
{
return $"Bound to id: {id}";
}
}
Pour appliquer la convention à tous les paramètres d’action, ajoutez MustBeInRouteParameterModelConvention à MvcOptions dans Startup.ConfigureServices:
options.Conventions.Add(new MustBeInRouteParameterModelConvention());
Modifier le ActionModel nom
La convention suivante modifie le ActionModelnom de l’action à laquelle elle est appliquée. Le nouveau nom est fourni en tant que paramètre pour l’attribut. Ce nouveau nom est utilisé par le routage, ce qui affecte l’itinéraire utilisé pour atteindre cette méthode d’action :
using System;
using Microsoft.AspNetCore.Mvc.ApplicationModels;
namespace AppModelSample.Conventions
{
public class CustomActionNameAttribute : Attribute, IActionModelConvention
{
private readonly string _actionName;
public CustomActionNameAttribute(string actionName)
{
_actionName = actionName;
}
public void Apply(ActionModel actionModel)
{
// this name will be used by routing
actionModel.ActionName = _actionName;
}
}
}
Cet attribut est appliqué à une méthode d’action dans le HomeController.
// Route: /Home/MyCoolAction
[CustomActionName("MyCoolAction")]
public string SomeName()
{
return ControllerContext.ActionDescriptor.ActionName;
}
Même si le nom de la méthode est SomeName, l’attribut remplace la convention MVC de l’utilisation du nom de la méthode et remplace le nom MyCoolActionde l’action par . Ainsi, la route utilisée pour atteindre cette action est /Home/MyCoolAction.
Note
Cet exemple de cette section est essentiellement identique à l’utilisation de l’élément intégré ActionNameAttribute.
Convention de routage personnalisée
Utilisez un IApplicationModelConvention pour personnaliser le fonctionnement du routage. Par exemple, la convention suivante intègre les espaces de noms des contrôleurs dans leurs routes, en remplaçant . dans l’espace de noms par / dans la route :
using Microsoft.AspNetCore.Mvc.ApplicationModels;
using System.Linq;
namespace AppModelSample.Conventions
{
public class NamespaceRoutingConvention : IApplicationModelConvention
{
public void Apply(ApplicationModel application)
{
foreach (var controller in application.Controllers)
{
var hasAttributeRouteModels = controller.Selectors
.Any(selector => selector.AttributeRouteModel != null);
if (!hasAttributeRouteModels
&& controller.ControllerName.Contains("Namespace")) // affect one controller in this sample
{
// Replace the . in the namespace with a / to create the attribute route
// Ex: MySite.Admin namespace will correspond to MySite/Admin attribute route
// Then attach [controller], [action] and optional {id?} token.
// [Controller] and [action] is replaced with the controller and action
// name to generate the final template
controller.Selectors[0].AttributeRouteModel = new AttributeRouteModel()
{
Template = controller.ControllerType.Namespace.Replace('.', '/') + "/[controller]/[action]/{id?}"
};
}
}
// You can continue to put attribute route templates for the controller actions depending on the way you want them to behave
}
}
}
La convention est ajoutée en tant qu’option dans Startup.ConfigureServices:
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc(options =>
{
options.Conventions.Add(new ApplicationDescription("My Application Description"));
options.Conventions.Add(new NamespaceRoutingConvention());
});
}
Conseil / Astuce
Ajoutez des conventions à l’intergiciel en utilisant l’approche suivante MvcOptions. L’espace {CONVENTION} réservé est la convention à ajouter :
services.Configure<MvcOptions>(c => c.Conventions.Add({CONVENTION}));
L’exemple suivant applique une convention aux itinéraires qui n’utilisent pas le routage d’attributs où le contrôleur a Namespace dans son nom.
using Microsoft.AspNetCore.Mvc;
namespace AppModelSample.Controllers
{
public class NamespaceRoutingController : Controller
{
// using NamespaceRoutingConvention
// route: /AppModelSample/Controllers/NamespaceRouting/Index
public string Index()
{
return "This demonstrates namespace routing.";
}
}
}
Utilisation du modèle d’application dans WebApiCompatShim
ASP.NET Core MVC utilise un ensemble différent de conventions de ASP.NET API web 2. À l’aide de conventions personnalisées, vous pouvez modifier le comportement d’une application MVC core ASP.NET afin qu’elle soit cohérente avec celle d’une application API web. Microsoft envoie le WebApiCompatShim package NuGet spécifiquement à cet effet.
Note
Pour plus d’informations sur la migration de ASP.NET API web, consultez Migrer de ASP.NET API web vers ASP.NET Core.
Pour utiliser le shim de compatibilité de l’API web :
- Ajoutez le
Microsoft.AspNetCore.Mvc.WebApiCompatShimpackage au projet. - Ajoutez les conventions à MVC en appelant AddWebApiConventions :
Startup.ConfigureServices
services.AddMvc().AddWebApiConventions();
Les conventions fournies par le shim sont appliquées uniquement aux parties de l’application qui ont eu certains attributs appliqués. Les quatre attributs suivants sont utilisés pour contrôler quels contrôleurs doivent avoir leurs conventions modifiées par les conventions du shim :
- UseWebApiActionConventionsAttribute
- UseWebApiOverloadingAttribute
- UseWebApiParameterConventionsAttribute
- UseWebApiRoutesAttribute
Conventions d’action
UseWebApiActionConventionsAttribute est utilisé pour mapper la méthode HTTP aux actions en fonction de leur nom (par exemple, Get mapper à HttpGet). Elle s’applique uniquement aux actions qui n’utilisent pas le routage d’attributs.
Surcharge
UseWebApiOverloadingAttribute est utilisé pour appliquer la WebApiOverloadingApplicationModelConvention convention. Cette convention ajoute un OverloadActionConstraint au processus de sélection d'actions, limitant les actions candidates à celles pour lesquelles la demande remplit tous les paramètres obligatoires.
Conventions de paramètre
UseWebApiParameterConventionsAttribute est utilisé pour appliquer la convention d’action WebApiParameterConventionsApplicationModelConvention . Cette convention spécifie que les types simples utilisés comme paramètres d’action sont liés par défaut à partir de l’URI, tandis que les types complexes sont liés à partir du corps de la requête.
Routes
UseWebApiRoutesAttribute contrôle si la convention du WebApiApplicationModelConvention contrôleur est appliquée. Lorsqu’elle est activée, cette convention est utilisée pour ajouter la prise en charge des zones à l’itinéraire et indique que le contrôleur se trouve dans la api zone.
Outre un ensemble de conventions, le package de compatibilité inclut une System.Web.Http.ApiController classe de base qui remplace celle fournie par l’API web. Cela permet à vos contrôleurs d'API web, écrits pour l'API web et qui héritent de `ApiController`, de fonctionner correctement lors de l'exécution sur ASP.NET Core MVC. Tous les UseWebApi* attributs répertoriés précédemment sont appliqués à la classe de contrôleur de base. **
Le ApiController expose des propriétés, des méthodes et des types de résultats qui sont compatibles avec ceux trouvés dans l’API web.
Utiliser ApiExplorer pour documenter une application
Le modèle d’application expose une ApiExplorerModel propriété à chaque niveau qui peut être utilisée pour parcourir la structure de l’application. Cela peut être utilisé pour générer des pages d’aide pour les API web à l’aide d’outils tels que Swagger. La ApiExplorer propriété expose une IsVisible propriété qui peut être définie pour spécifier les parties du modèle de l’application qui doivent être exposées. Configurez ce paramètre à l’aide d’une convention :
using Microsoft.AspNetCore.Mvc.ApplicationModels;
namespace AppModelSample.Conventions
{
public class EnableApiExplorerApplicationConvention : IApplicationModelConvention
{
public void Apply(ApplicationModel application)
{
application.ApiExplorer.IsVisible = true;
}
}
}
À l’aide de cette approche (et des conventions supplémentaires si nécessaire), la visibilité de l’API est activée ou désactivée à n’importe quel niveau au sein d’une application.