Vues dans ASP.NET Core MVC

Article rédigé par Steve Smith et Dave Brock

Ce document explique l’utilisation des vues dans les applications ASP.NET Core MVC. Pour plus d’informations sur les pages Razor, consultez Présentation des pages Razor dans ASP.NET Core.

Selon le schéma MVC (Modèle-Vue-Contrôleur), la vue gère la présentation des données et les interactions utilisateur dans l’application. Une vue est un modèle HTML dans lequel est incorporé un balisage Razor. Le balisage Razor est du code qui interagit avec le balisage HTML pour générer une page web qui est envoyée au client.

Dans ASP.NET Core MVC, les vues sont des fichiers .cshtml qui utilisent le langage de programmation C# dans le balisage Razor. En règle générale, les fichiers de vue sont regroupés dans des dossiers nommés correspondant aux différents contrôleurs de l’application. Ces dossiers sont eux-mêmes regroupés sous le dossier Views situé à la racine de l’application :

Le dossier Vues dans l’Explorateur de solutions de Visual Studio est ouvert avec le dossier Home ouvert pour montrer les fichiers About.cshtml, Contact.cshtml et Index.cshtml

Le contrôleur Home est représenté par un dossier Home à l’intérieur du dossier Views. Le dossier Home contient les vues des pages web About, Contact et Index (page d’accueil). Quand un utilisateur demande l’une de ces trois pages web, les actions dans le contrôleur Home déterminent laquelle des trois vues est utilisée pour générer une page web et la retourner à l’utilisateur.

Utilisez des dispositions pour rendre les sections de page web homogènes et réduire la répétition de code. Les dispositions contiennent souvent l’en-tête, des éléments de menu et de navigation, ainsi que le pied de page. L’en-tête et le pied de page renferment généralement le code de balisage réutilisable pour divers éléments de métadonnées, et les liens vers des ressources de script et de style. Les dispositions vous permettent de limiter l’usage de ce balisage réutilisable dans vos vues.

Les vues partielles réduisent la répétition de code grâce à la gestion des parties réutilisables dans les vues. Par exemple, une vue partielle est utile dans le cas d’une biographie d’auteur publiée sur un site web de blog qui doit s’afficher dans plusieurs vues. Une biographie d’auteur présente un contenu de vue standard et ne nécessite pas d’exécution de code particulier pour générer le contenu à afficher sur la page web. Le contenu de la biographie d’auteur est fourni à la vue uniquement par la liaison de données. C’est pourquoi l’utilisation d’une vue partielle pour ce type de contenu est la solution la plus appropriée.

Les composants de vue sont similaires aux vues partielles dans le sens où ils vous permettent aussi de réduire la répétition de code. La différence est qu’ils sont plutôt conçus pour du contenu de vue qui nécessite l’exécution de code sur le serveur pour afficher la page web. Les composants de vue sont utiles quand le contenu affiché doit interagir avec une base de données, comme c’est le cas pour un panier d’achat sur un site web. Les composants de vue ne dépendent pas d’une liaison de données pour pouvoir générer la sortie d’une page web.

Avantages de l’utilisation des vues

Les vues facilitent l’implémentation du principe de conception basé sur la séparation des préoccupations (separation of concerns) au sein d’une application MVC. En effet, elles permettent de séparer le balisage de l’interface utilisateur des autres parties de l’application. Une application conçue selon ce principe présente une plus grande modularité, ce qui offre plusieurs avantages :

  • L’application est plus facile à gérer, car elle est mieux organisée. Les vues sont généralement regroupées par fonctionnalité dans l’application. Vous pouvez ainsi trouver plus rapidement les vues associées quand vous utilisez une fonctionnalité.
  • Les différentes parties de l’application sont faiblement couplées. Vous pouvez générer et mettre à jour les vues de l’application séparément de la logique métier et des composants d’accès aux données. Vous pouvez modifier les vues de l’application sans avoir nécessairement besoin de mettre à jour d’autres parties de l’application.
  • Il est plus facile de tester les parties de l’interface utilisateur de l’application, car les vues constituent des unités individuelles séparées.
  • Du fait d’une meilleure organisation, vous risquez moins de répéter par inadvertance certaines sections de l’interface utilisateur.

Création d’une vue

Les vues spécifiques à un contrôleur sont créées dans le dossier Views/[ControllerName]. Les vues communes à plusieurs contrôleurs sont créées dans le dossier Views/Shared. Pour créer une vue, ajoutez un nouveau fichier et attribuez-lui le même nom que son action de contrôleur associée, avec l’extension de fichier .cshtml. Pour créer une vue qui correspond à l’action About dans le contrôleur Home, créez un fichier About.cshtml dans le dossier Views/Home :

@{
    ViewData["Title"] = "About";
}
<h2>@ViewData["Title"].</h2>
<h3>@ViewData["Message"]</h3>

<p>Use this area to provide additional information.</p>

Le balisage Razor commence par le symbole @. Pour exécuter des instructions C#, placez le code C# dans des blocs de code Razor délimités par des accolades ({ ... }). L’exemple ci-dessus montre comment attribuer la valeur « About » à ViewData["Title"]. Vous pouvez afficher des valeurs dans le code HTML simplement en référençant chaque valeur avec le symbole @. Le code ci-dessus donne un exemple de contenu des éléments <h2> et <h3>.

Le contenu de la vue illustré ci-dessus est uniquement une partie de la page web entière qui est affichée à l’utilisateur. Le rest de la disposition de la page et les autres aspects communs de la vue sont spécifiés dans d’autres fichiers de vue. Pour en savoir plus, consultez l’article Disposition.

Comment les contrôleurs spécifient-ils les vues ?

Les vues sont généralement retournées par des actions sous forme d’objet ViewResult, qui est un type d’objet ActionResult. Votre méthode d’action peut créer et retourner un ViewResult directement, mais cela n’est pas le plus fréquent. Étant donné que la plupart des contrôleurs héritent de Controller, utilisez simplement la méthode d’assistance View pour retourner le ViewResult :

HomeController.cs :

public IActionResult About()
{
    ViewData["Message"] = "Your application description page.";

    return View();
}

Quand cette action est retournée, la vue About.cshtml figurant dans la dernière section s’affiche dans la page web comme ceci :

Page About affichée dans le navigateur Edge

La méthode d’assistance View a plusieurs surcharges. Vous pouvez éventuellement spécifier :

  • Une vue explicite à retourner :

    return View("Orders");
    
  • Un modèle à passer à la vue :

    return View(Orders);
    
  • Une vue et un modèle :

    return View("Orders", Orders);
    

Détection de la vue

Quand une action doit retourner une vue, un processus appelé détection de la vue s’enclenche. Ce processus détermine quel fichier de vue est utilisé en fonction du nom de la vue.

Le comportement par défaut de la méthode View (return View();) est de retourner une vue du même nom que la méthode d’action à partir de laquelle elle est appelée. Par exemple, le nom de la méthode ActionResult About du contrôleur est utilisé pour rechercher un fichier de vue nommé About.cshtml. Le runtime commence par rechercher la vue dans le dossier Views/[ControllerName]. S’il ne trouve pas de vue correspondante, il recherche ensuite la vue dans le dossier Shared.

Peu importe si vous retournez implicitement ViewResult avec return View(); ou si vous passez explicitement le nom de la vue à la méthode View avec return View("<ViewName>");. Dans les deux cas, la détection de la vue recherche un fichier de vue correspondant dans cet ordre :

  1. Views/\[ControllerName]/\[ViewName].cshtml
  2. Views/Shared/\[ViewName].cshtml

Vous pouvez spécifier le chemin du fichier de vue au lieu du nom de la vue. Si vous utilisez un chemin absolu à partir de la racine de l’application (commençant éventuellement par « / » ou « ~/ »), vous devez indiquer l’extension .cshtml :

return View("Views/Home/About.cshtml");

Vous pouvez également utiliser un chemin relatif pour spécifier des vues situées dans des répertoires différents. Dans ce cas, n’indiquez pas l’extension .cshtml. Dans HomeController, vous pouvez retourner la vue Index du dossier de vues Manage avec un chemin relatif :

return View("../Manage/Index");

De même, vous pouvez indiquer le dossier spécifique du contrôleur actif avec le préfixe « ./ » :

return View("./About");

Les vues partielles et les composants de vue utilisent des mécanismes de détection presque identiques.

Vous pouvez personnaliser la convention par défaut de recherche des vues dans l’application à l’aide d’un IViewLocationExpander personnalisé.

La détection des vues recherche les fichiers de vue d’après le nom de fichier. Si le système de fichiers sous-jacent respecte la casse, les noms de vue respectent probablement la casse eux aussi. Pour garantir la compatibilité entre les systèmes d’exploitation, utilisez la même casse pour les noms de contrôleur et d’action et pour les noms de leurs dossiers et fichiers de vues associés. Si vous utilisez un système de fichiers qui respecte la casse et que vous voyez un message d’erreur indiquant qu’un fichier de vue est introuvable, vérifiez que le nom du fichier de vue demandé et le nom du fichier de vue réel ont une casse identique.

Suivez les bonnes pratiques en matière d’organisation de la structure des fichiers de vue. Votre structure doit refléter au mieux les relations entre les contrôleurs, les actions et les vues pour être plus claire et facile à gérer.

Transmettre des données à des vues

Plusieurs approches sont possibles pour passer des données aux vues :

  • Données fortement typées : viewmodel
  • Données faiblement typées
    • ViewData (ViewDataAttribute)
    • ViewBag

Données fortement typées (viewmodel)

L’approche la plus fiable consiste à spécifier un type de modèle dans la vue. Ce modèle est communément appelé ViewModel. Vous passez une instance de type ViewModel à la vue à partir de l’action.

L’utilisation d’un ViewModel pour passer des données à une vue vous permet d’effectuer un contrôle de type fort dans la vue. Le terme typage fort (ou fortement typé) signifie que chaque variable et constante a un type défini explicitement (par exemple, string, int ou DateTime). La validité des types utilisés dans une vue est contrôlée au moment de la compilation.

Visual Studio et Visual Studio Code répertorient les membres de classe fortement typés à l’aide d’une fonctionnalité appelée IntelliSense. Quand vous voulez afficher les propriétés d’un ViewModel, tapez le nom de variable pour le ViewModel suivi d’un point (.). Cela vous permet d’écrire du code plus rapidement et avec moins d’erreurs.

Spécifiez un modèle à l’aide de la directive @model. Utilisez le modèle avec @Model :

@model WebApplication1.ViewModels.Address

<h2>Contact</h2>
<address>
    @Model.Street<br>
    @Model.City, @Model.State @Model.PostalCode<br>
    <abbr title="Phone">P:</abbr> 425.555.0100
</address>

Pour fournir le modèle à la vue, le contrôleur le passe en tant que paramètre :

public IActionResult Contact()
{
    ViewData["Message"] = "Your contact page.";

    var viewModel = new Address()
    {
        Name = "Microsoft",
        Street = "One Microsoft Way",
        City = "Redmond",
        State = "WA",
        PostalCode = "98052-6399"
    };

    return View(viewModel);
}

Il n’y a pas de restrictions relatives aux types de modèles que vous pouvez fournir à une vue. Nous vous recommandons d’utiliser des ViewModels POCO (Plain Old CLR Object), avec peu ou pas de méthodes de comportement définies. En règle générale, les classes ViewModel sont stockées dans le dossier Models ou dans un dossier ViewModels distinct à la racine de l’application. Le ViewModel Address utilisé dans l’exemple ci-dessus est un ViewModel OCT stocké dans un fichier nommé Address.cs :

namespace WebApplication1.ViewModels
{
    public class Address
    {
        public string Name { get; set; }
        public string Street { get; set; }
        public string City { get; set; }
        public string State { get; set; }
        public string PostalCode { get; set; }
    }
}

Rien ne vous empêche d’utiliser les mêmes classes pour vos types de ViewModel et vos types de modèle métier. Toutefois, l’utilisation de modèles distincts vous permet de changer les vues indépendamment de la logique métier et des composants d’accès aux données de votre application. La séparation des modèles et des ViewModel est également un gage de sécurité si vous avez des modèles qui utilisent la liaison de données et la validation pour les données envoyées à l’application par l’utilisateur.

Données faiblement typées (ViewData, attribut [ViewData] et ViewBag)

ViewBag n’est pas disponible par défaut pour une utilisation dans les classes PageModel deRazor Pages.

En plus des vues fortement typées, les vues ont accès à une collection de données faiblement typées (ou librement typées). Contrairement aux types forts, les types faibles (ou types libres) ne nécessitent pas de déclarer explicitement le type de données utilisé. Vous pouvez utiliser la collection de données faiblement typées pour passer de petites quantités de données entre les contrôleurs et les vues.

Passer des données entre... Exemple
Un contrôleur et une vue Remplissage d’une liste déroulante avec des données.
Une vue et une disposition Définition du contenu de l’élément <title> dans la disposition à partir d’un fichier de vue.
Une vue partielle et une vue Widget qui affiche des données en fonction de la page web demandée par l’utilisateur.

Cette collection peut être référencée par les propriétés ViewData ou ViewBag sur les contrôleurs et les vues. La propriété ViewData est un dictionnaire d’objets faiblement typés. La propriété ViewBag est un wrapper autour de ViewData qui fournit des propriétés dynamiques pour la collection ViewData sous-jacente. Remarque : les recherches de clés respectent la casse pour ViewData et ViewBag.

ViewData et ViewBag sont résolues dynamiquement au moment de l’exécution. Dans la mesure où elles n’effectuent pas de contrôle de type à la compilation, ces deux propriétés sont généralement davantage sujettes aux erreurs qu’un ViewModel. Pour cette raison, certains développeurs préfèrent ne jamais utiliser les propriétés ViewData et ViewBag, ou les utiliser le moins possible.

ViewData

ViewData est un objet ViewDataDictionary accessible via des clés string. Vous pouvez stocker et utiliser des données de type chaîne directement, sans avoir à les caster, mais vous devez effectuer un cast des autres valeurs de l’objet ViewData vers des types spécifiques lors de leur extraction. Vous pouvez utiliser ViewData pour passer des données des contrôleurs aux vues et au sein même des vues, y compris les vues partielles et les dispositions.

L’exemple suivant utilise un objet ViewData dans une action pour définir les valeurs d’un message d’accueil et d’une adresse :

public IActionResult SomeAction()
{
    ViewData["Greeting"] = "Hello";
    ViewData["Address"]  = new Address()
    {
        Name = "Steve",
        Street = "123 Main St",
        City = "Hudson",
        State = "OH",
        PostalCode = "44236"
    };

    return View();
}

Utilisation des données dans une vue :

@{
    // Since Address isn't a string, it requires a cast.
    var address = ViewData["Address"] as Address;
}

@ViewData["Greeting"] World!

<address>
    @address.Name<br>
    @address.Street<br>
    @address.City, @address.State @address.PostalCode
</address>

Attribut [ViewData]

Une autre approche qui utilise l’objet ViewDataDictionary est ViewDataAttribute. Les valeurs des propriétés définies sur des contrôleurs ou sur des modèles de page Razor marqués avec l’attribut [ViewData] sont stockées dans le dictionnaire et chargées à partir de celui-ci.

Dans l’exemple suivant, le contrôleur Home contient une propriété Title marquée avec [ViewData]. La méthode About définit le titre de la vue About :

public class HomeController : Controller
{
    [ViewData]
    public string Title { get; set; }

    public IActionResult About()
    {
        Title = "About Us";
        ViewData["Message"] = "Your application description page.";

        return View();
    }
}

Dans la disposition, le titre est lu à partir du dictionnaire ViewData :

<!DOCTYPE html>
<html lang="en">
<head>
    <title>@ViewData["Title"] - WebApplication</title>
    ...

ViewBag

ViewBag n’est pas disponible par défaut pour une utilisation dans les classes PageModel deRazor Pages.

ViewBag est un objet Microsoft.AspNetCore.Mvc.ViewFeatures.Internal.DynamicViewData qui fournit un accès dynamique aux objets stockés dans ViewData. ViewBag est parfois plus pratique à utiliser, car il ne nécessite pas de cast. L’exemple suivant montre comment utiliser ViewBag pour obtenir le même résultat qu’avec l’objet ViewData ci-dessus :

public IActionResult SomeAction()
{
    ViewBag.Greeting = "Hello";
    ViewBag.Address  = new Address()
    {
        Name = "Steve",
        Street = "123 Main St",
        City = "Hudson",
        State = "OH",
        PostalCode = "44236"
    };

    return View();
}
@ViewBag.Greeting World!

<address>
    @ViewBag.Address.Name<br>
    @ViewBag.Address.Street<br>
    @ViewBag.Address.City, @ViewBag.Address.State @ViewBag.Address.PostalCode
</address>

Utilisation simultanée de ViewData et de ViewBag

ViewBag n’est pas disponible par défaut pour une utilisation dans les classes PageModel deRazor Pages.

Comme ViewData et ViewBag font référence à la même collection ViewData sous-jacente, vous pouvez utiliser ViewData et ViewBag simultanément, en les combinant et en les associant pour lire et écrire des valeurs.

Définissez le titre avec ViewBag et la description avec ViewData au début d’une vue About.cshtml :

@{
    Layout = "/Views/Shared/_Layout.cshtml";
    ViewBag.Title = "About Contoso";
    ViewData["Description"] = "Let us tell you about Contoso's philosophy and mission.";
}

Lisez les propriétés, mais inversez l’utilisation de ViewData et ViewBag. Dans le fichier _Layout.cshtml, obtenez le titre et la description avec ViewData et ViewBag, respectivement :

<!DOCTYPE html>
<html lang="en">
<head>
    <title>@ViewData["Title"]</title>
    <meta name="description" content="@ViewBag.Description">
    ...

Souvenez-vous que les chaînes ne nécessitent pas de cast pour ViewData. Vous pouvez utiliser @ViewData["Title"] sans cast.

L’utilisation simultanée de ViewData et ViewBag est possible, de la même manière que la combinaison et l’association des propriétés de lecture et d’écriture. Le balisage suivant est affiché :

<!DOCTYPE html>
<html lang="en">
<head>
    <title>About Contoso</title>
    <meta name="description" content="Let us tell you about Contoso's philosophy and mission.">
    ...

Résumé des différences entre ViewData et ViewBag

ViewBag n’est pas disponible par défaut pour une utilisation dans les classes PageModel deRazor Pages.

  • ViewData
    • Dérivé de ViewDataDictionary, cet objet fournit des propriétés de dictionnaire potentiellement utiles, telles que ContainsKey, Add, Remove et Clear.
    • Les clés contenues dans le dictionnaire sont des chaînes ; les espaces blancs sont donc autorisés. Exemple : ViewData["Some Key With Whitespace"]
    • Les autres types que string doivent être castés dans la vue pour utiliser ViewData.
  • ViewBag
    • Dérivé de Microsoft.AspNetCore.Mvc.ViewFeatures.Internal.DynamicViewData, cet objet permet de créer des propriétés dynamiques avec la notation par points (@ViewBag.SomeKey = <value or object>). Aucun cast n’est nécessaire. La syntaxe de ViewBag facilite son ajout aux contrôleurs et aux vues.
    • Simplifie la vérification des valeurs Null. Exemple : @ViewBag.Person?.Name

Quand utiliser ViewData ou ViewBag

ViewData et ViewBag constituent deux approches appropriées pour passer de petites quantités de données entre les contrôleurs et les vues. Choisissez celle qui vous convient le mieux. Vous pouvez combiner et associer les objets ViewData et ViewBag. Toutefois, il est recommandé d’utiliser une seule approche pour faciliter la lecture et la gestion du code. Les deux approches sont résolues dynamiquement au moment de l’exécution et sont donc susceptibles d’engendrer des erreurs d’exécution. C’est la raison pour laquelle certains développeurs préfèrent ne pas les utiliser.

Vues dynamiques

Les vues qui ne déclarent pas de modèle de type à l’aide de @model mais qui reçoivent une instance de modèle (par exemple, return View(Address);) peuvent référencer dynamiquement les propriétés de l’instance :

<address>
    @Model.Street<br>
    @Model.City, @Model.State @Model.PostalCode<br>
    <abbr title="Phone">P:</abbr> 425.555.0100
</address>

Cette fonctionnalité offre beaucoup de flexibilité, mais elle ne fournit pas de protection de la compilation ou la fonction IntelliSense. Si la propriété n’existe pas, la génération de la page web échoue au moment de l’exécution.

Autres fonctionnalités de vue

Les Tag Helpers permettent d’ajouter facilement un comportement côté serveur dans des balises HTML existantes. Leur utilisation vous évite d’avoir à écrire du code personnalisé ou des méthodes d’assistance dans les vues. Les Tag Helpers sont appliqués comme attributs aux éléments HTML et sont ignorés par les éditeurs qui ne peuvent pas les traiter. Vous pouvez ainsi modifier et afficher le balisage des vues dans divers outils.

La génération d’un balisage HTML personnalisé est possible avec de nombreux HTML Helpers intégrés. Si vous avez une logique d’interface utilisateur plus complexe, gérez-la avec les composants de vue. Les composants de vue sont conçus sur le même principe de séparation des préoccupations (SoC) que les contrôleurs et les vues. Ils vous évitent de devoir utiliser des actions et des vues pour le traitement des données utilisées par les éléments d’interface utilisateur communs.

Comme de nombreux autres aspects d’ASP.NET Core, les vues prennent en charge l’injection de dépendances, ce qui permet aux services d’être injectés dans les vues.

Isolation CSS

Isolez les styles CSS en pages, vues et composants individuels afin de réduire ou d’éviter :

  • Les dépendances sur les styles globaux qui peuvent être difficiles à gérer.
  • Les conflits de style dans du contenu imbriqué.

Pour ajouter un fichier CSS délimité pour une page ou une vue, placez les styles CSS dans un fichier .cshtml.css compagnon correspondant au nom du fichier .cshtml. Dans l’exemple suivant, un fichier Index.cshtml.cssfournit des styles CSS qui sont appliqués seulement à la page ou à la vue Index.cshtml.

Pages/Index.cshtml.css (Razor Pages) ou Views/Index.cshtml.css (MVC) :

h1 {
    color: red;
}

L’isolation CSS se produit au moment de la build. Le framework réécrit les sélecteurs CSS pour qu’ils correspondent au balisage rendu par les pages ou les vues de l’application. Les styles CSS réécrits sont regroupés et produits sous la forme d’une ressource statique. {APP ASSEMBLY}.styles.css L’espace réservé {APP ASSEMBLY} est le nom de l’assembly du projet. Un lien vers les styles CSS regroupés est placé dans la disposition de l’application.

Dans le contenu <head> du fichier Pages/Shared/_Layout.cshtml de l’application (Razor Pages) ou de Views/Shared/_Layout.cshtml (MVC), ajoutez ou vérifiez la présence du lien vers les styles CSS regroupés :

<link rel="stylesheet" href="~/{APP ASSEMBLY}.styles.css" />

Dans l’exemple suivant, le nom de l’assembly de l’application est WebApp :

<link rel="stylesheet" href="WebApp.styles.css" />

Les styles définis dans un fichier CSS délimité sont appliqués seulement à la sortie rendue du fichier correspondant. Dans l’exemple précédent, les déclarations CSS h1 définies ailleurs dans l’application ne sont pas en conflit avec le style de titre de Index. Les règles d’héritage et de cascade des styles CSS restent en vigueur pour les fichiers CSS délimités. Par exemple, les styles appliqués directement à un élément <h1> du fichier Index.cshtml remplacent les styles du fichier CSS délimité dans Index.cshtml.css.

Remarque

Pour garantir l’isolation du style CSS lors du regroupement, l’importation de CSS dans des blocs de code Razor n’est pas prise en charge.

L’isolation CSS s’applique seulement aux éléments HTML. L’isolation CSS n’est pas prise en charge pour les Tag Helpers.

Dans le fichier CSS regroupé, chaque page, vue ou composant Razor est associé à un identificateur d’étendue au format b-{STRING}, où l’espace réservé {STRING} est une chaîne de dix caractères générée par le framework. L’exemple suivant fournit le style pour l’élément <h1> précédent dans la page Index d’une application Razor Pages :

/* /Pages/Index.cshtml.rz.scp.css */
h1[b-3xxtam6d07] {
    color: red;
}

Dans la page Index où le style CSS est appliqué à partir du fichier regroupé, l’identificateur d’étendue est ajouté en tant qu’attribut HTML :

<h1 b-3xxtam6d07>

L’identificateur est unique pour une application. Au moment de la build, un bundle de projet est créé avec la convention {STATIC WEB ASSETS BASE PATH}/Project.lib.scp.css, où l’espace réservé {STATIC WEB ASSETS BASE PATH} est le chemin de base des ressources web statiques.

Si d’autres projets sont utilisés, comme des packages NuGet ou des bibliothèques de classes Razor, le fichier regroupé :

  • Fait référence aux styles en utilisant des importations CSS.
  • N’est pas publié en tant que ressource web statique de l’application qui consomme les styles.

Prise en charge des préprocesseurs CSS

Les préprocesseurs CSS sont utiles pour améliorer le développement CSS en utilisant des fonctionnalités comme les variables, l’imbrication, les modules, les mixins et l’héritage. Bien que l’isolation CSS ne prenne pas en charge nativement les préprocesseurs CSS comme Sass ou Less, l’intégration de préprocesseurs CSS se fait sans problème dès lors que la compilation du préprocesseur se produit avant que le framework réécrive les sélecteurs CSS lors du processus de build. Par exemple, avec Visual Studio, configurez la compilation du préprocesseur existant en tant que tâche Avant la build dans l’Explorateur d’exécuteur de tâches Visual Studio.

De nombreux packages NuGet tiers, comme AspNetCore.SassCompiler, peuvent compiler des fichiers SASS/SCSS au début du processus de build avant que l’isolation CSS ne se produise, et aucune configuration supplémentaire n’est requise.

Configuration de l’isolation CSS

L’isolation CSS permet la configuration de certains scénarios avancés, comme quand il existe des dépendances sur des outils ou des workflows existants.

Personnaliser le format de l’identificateur d’étendue

Dans cette section, l’espace réservé {Pages|Views} est Pages pour les applications Razor Pages ou Views pour les applications MVC.

Par défaut, les identificateurs d’étendue utilisent le format b-{STRING}, où l’espace réservé {STRING} est une chaîne de dix caractères générée par le framework. Pour personnaliser le format de l’identificateur d’étendue, mettez à jour le fichier projet avec un modèle souhaité :

<ItemGroup>
  <None Update="{Pages|Views}/Index.cshtml.css" CssScope="custom-scope-identifier" />
</ItemGroup>

Dans l’exemple précédent, le CSS généré pour Index.cshtml.css change son identificateur d’étendue de b-{STRING} en custom-scope-identifier.

Utilisez des identificateurs d’étendue pour mettre en œuvre l’héritage avec des fichiers CSS délimités. Dans l’exemple de fichier projet suivant, un fichier BaseView.cshtml.css contient des styles communs entre les vues. Un fichier DerivedView.cshtml.css hérite de ces styles.

<ItemGroup>
  <None Update="{Pages|Views}/BaseView.cshtml.css" CssScope="custom-scope-identifier" />
  <None Update="{Pages|Views}/DerivedView.cshtml.css" CssScope="custom-scope-identifier" />
</ItemGroup>

Utilisez l’opérateur de caractère générique (*) pour partager des identificateurs d’étendue entre plusieurs fichiers :

<ItemGroup>
  <None Update="{Pages|Views}/*.cshtml.css" CssScope="custom-scope-identifier" />
</ItemGroup>

Changer le chemin de base pour les ressources web statiques

Le fichier CSS délimité est généré à la racine de l’application. Dans le fichier projet, utilisez la propriété StaticWebAssetBasePath pour changer le chemin par défaut. L’exemple suivant place le fichier CSS délimité et le rest des ressources de l’application dans le chemin _content :

<PropertyGroup>
  <StaticWebAssetBasePath>_content/$(PackageId)</StaticWebAssetBasePath>
</PropertyGroup>

Désactiver le regroupement automatique

Pour ne pas accepter la façon dont l’infrastructure publie et charge des fichiers délimités au moment de l’exécution, utilisez la propriété DisableScopedCssBundling. Lors de l’utilisation de cette propriété, d’autres outils ou processus sont chargés de prendre les fichiers CSS isolés du répertoire obj, et de les publier et de les charger au moment de l’exécution :

<PropertyGroup>
  <DisableScopedCssBundling>true</DisableScopedCssBundling>
</PropertyGroup>

Prise en charge de la bibliothèque de classes Razor (RCL)

Quand une bibliothèque de classes Razor(RCL) fournit des styles isolés, l’attribut href de la balise <link> pointe vers {STATIC WEB ASSET BASE PATH}/{PACKAGE ID}.bundle.scp.css, où les espaces réservés sont :

  • {STATIC WEB ASSET BASE PATH} : le chemin de base de la ressource web statique.
  • {PACKAGE ID} : l’identificateur de package de la bibliothèque. L’identificateur de package est défini par défaut sur le nom de l’assembly du projet si l’identificateur de package n’est pas spécifié dans le fichier projet.

Dans l’exemple suivant :

  • Le chemin de base de la ressource web statique est _content/ClassLib.
  • Le nom de l’assembly de la bibliothèque de classes est ClassLib.

Pages/Shared/_Layout.cshtml (Razor Pages) ou Views/Shared/_Layout.cshtml (MVC) :

<link href="_content/ClassLib/ClassLib.bundle.scp.css" rel="stylesheet">

Pour plus d’informations sur les bibliothèques de classes Razor, consultez les articles suivants :

Pour plus d’informations sur l’isolation CSS de Blazor, consultez Isolation CSS Blazor d’ASP.NET Core.