Modes de rendu ASP.NET Core Blazor

Cet article explique le contrôle du rendu des composants Razor dans les applications web Blazor, au moment de la compilation ou au moment de l’exécution.

Cette aide ne s’applique pas aux applications Blazor WebAssembly autonomes. Les applications Blazor WebAssembly s’affichent sur le client seulement via un runtime WebAssembly côté client et n’ont pas de concept de mode d’affichage. Si un mode d’affichage est appliqué à un composant dans une application Blazor WebAssembly, la désignation du mode d’affichage n’a pas d’influence sur l’affichage du composant.

Modes de rendu

Chaque composant d’une application web Blazor adopte un mode de rendu pour déterminer le modèle d’hébergement qu’il utilise, l’endroit où il est affiché et s’il est interactif ou non.

Le tableau suivant présente les modes de rendu disponibles pour le rendu des composants Razor dans l’application web Blazor. Pour appliquer un mode de rendu à un composant, utilisez la directive @rendermode sur l'instance du composant ou sur la définition du composant. Plus loin dans cet article, des exemples sont présentés pour chaque scénario de mode de rendu.

Nom Description Emplacement du rendu Interactive
Serveur statique Rendu statique côté serveur (SSR statique) Serveur Non
Serveur interactif Rendu côté serveur interactif (SSR interactif) à l’aide de Blazor Server. Serveur Oui
WebAssembly interactif Rendu côté client (CSR) à l’aide de Blazor WebAssembly†. Client Oui
Voiture interactive SSR interactif à l’aide de Blazor Server dans un premier temps, puis CSR lors des visites ultérieures après le téléchargement de l’offre groupée Blazor. Serveur, puis client Oui

† Le rendu côté client (CSR) est supposé être interactif. Le « rendu interactif côté client » et « CSR interactif » ne sont pas utilisés par le secteur ou dans la documentation Blazor.

Le pré-rendu est activé par défaut pour les composants interactifs. Des conseils sur le contrôle du pré-rendu sont fournis plus loin dans cet article. Pour connaître la terminologie générale du secteur sur les concepts de rendu du client et du serveur, consultez Notions de base d’ASP.NET Blazor.

Les exemples suivants illustrent la définition du mode de rendu du composant avec quelques fonctionnalités de composant Razor de base.

Pour tester les comportements du mode de rendu localement, vous pouvez placer les composants suivants dans une application créée à partir du modèle de projet de l’application web Blazor. Lorsque vous créez l’application, sélectionnez les options dans les menus déroulants (Visual Studio) ou appliquez les options CLI (interface CLI .NET) pour activer l’interactivité côté serveur et côté client. Pour obtenir des conseils sur la création d’une application web Blazor, consultez Outils pour ASP.NET Core Blazor.

Activez la prise en charge des modes de rendu interactifs

Une application web Blazor doit être configurée pour prendre en charge les modes de rendu interactifs. Les extensions suivantes sont automatiquement appliquées aux applications créées à partir du modèle de projet d’application web Blazor lors de la création de l’application. Les composants individuels doivent toujours déclarer leur mode de rendu conformément à la section Modes de rendu après la configuration des services et points de terminaison des composants dans le fichier Program de l’application.

Les services pour les composants Razor sont ajoutés en appelant AddRazorComponents.

Extensions du générateur de composants :

MapRazorComponents découvre les composants disponibles et spécifie le composant racine de l’application (le premier composant chargé), qui est par défaut le composant App (App.razor).

Extensions du générateur de conventions de point de terminaison :

Remarque

Pour obtenir des indications sur le placement de l’API dans les exemples suivants, examinez le fichier Program d’une application générée à partir du modèle de projet de l’application web Blazor. Pour obtenir des conseils sur la création d’une application web Blazor, consultez Outils pour ASP.NET Core Blazor.

Exemple 1 : l’API de fichier Program suivante ajoute des services et une configuration pour activer SSR interactif :

builder.Services.AddRazorComponents()
    .AddInteractiveServerComponents();
app.MapRazorComponents<App>()
    .AddInteractiveServerRenderMode();

Exemple 2 : l’API de fichier Program suivante ajoute des services et une configuration pour activer le mode de rendu WebAssembly interactif :

builder.Services.AddRazorComponents()
    .AddInteractiveWebAssemblyComponents();
app.MapRazorComponents<App>()
    .AddInteractiveWebAssemblyRenderMode();

Exemple 3 : l’API de fichier Program suivante ajoute des services et une configuration pour activer les modes de rendu Serveur interactif, WebAssembly interactif et Auto interactif :

builder.Services.AddRazorComponents()
    .AddInteractiveServerComponents()
    .AddInteractiveWebAssemblyComponents();
app.MapRazorComponents<App>()
    .AddInteractiveServerRenderMode()
    .AddInteractiveWebAssemblyRenderMode();

Blazor utilise le modèle d’hébergement Blazor WebAssembly pour télécharger et exécuter des composants qui utilisent le mode de rendu WebAssembly interactif. Un projet client distinct est requis pour configurer l’hébergement Blazor WebAssembly de ces composants. Le projet client contient le code de démarrage de l’hôte Blazor WebAssembly et configure le runtime .NET pour qu’il s’exécute dans un navigateur. Le modèle d’application web Blazor ajoute ce projet client pour vous lorsque vous sélectionnez l’option permettant d’activer l’interactivité WebAssembly. Tous les composants utilisant le mode de rendu WebAssembly doivent être générés à partir du projet client. Ils sont donc inclus dans l’ensemble d’applications téléchargé.

Appliquez un mode de rendu à une instance de composant

Pour appliquer un mode de rendu à une instance de composant, utilisez l’attribut de directive @rendermodeRazor où le composant est utilisé.

Dans l’exemple suivant, le rendu côté serveur interactif (SSR interactif) est appliqué à l’instance de composant Dialog :

<Dialog @rendermode="InteractiveServer" />

Remarque

Les modèles Blazor incluent une directive statique using pour RenderMode dans le fichier _Imports de l’application (Components/_Imports.razor) pour une syntaxe de @rendermode plus courte :

@using static Microsoft.AspNetCore.Components.Web.RenderMode

Sans la directive précédente, les composants doivent spécifier la classe statique RenderMode dans la syntaxe @rendermode :

<Dialog @rendermode="RenderMode.InteractiveServer" />

Vous pouvez référencer des instances en mode de rendu personnalisé instanciées directement avec une configuration personnalisée. Pour plus d’informations, consultez la section Modes de rendu abrégé personnalisés plus loin dans cet article.

Appliquez un mode de rendu à une définition de composant

Pour spécifier le mode de rendu d’un composant dans le cadre de sa définition, utilisez la directive @rendermodeRazor et l’attribut de mode de rendu correspondant.

@page "..."
@rendermode InteractiveServer

L’application d’un mode de rendu à une définition de composant est couramment utilisée lors de l’application d’un mode de rendu à une page spécifique. Les pages routables utilisent par défaut le même mode de rendu que le composant Router qui a rendu la page.

Techniquement, @rendermode est à la fois une Razordirective et un Razorattribut de directive. La sémantique est similaire, mais il existe des différences. La directive @rendermode se trouve sur la définition du composant, donc l'instance du mode de rendu référencée doit être statique. L'attribut directive @rendermode peut prendre n'importe quelle instance de mode de rendu.

Remarque

Les auteurs de composants doivent éviter le couplage de l’implémentation d’un composant à un mode de rendu spécifique. Au lieu de cela, les auteurs de composants doivent généralement concevoir des composants permettant de prendre en charge tout mode de rendu ou modèle d’hébergement. L’implémentation d’un composant doit éviter les hypothèses sur l’emplacement où il est en cours d’exécution (serveur ou client) et doit se dégrader correctement lorsqu’il est affiché de manière statique. La spécification du mode de rendu dans la définition du composant peut être nécessaire si le composant n’est pas instancié directement (par exemple, avec un composant de page routable) ou pour spécifier un mode de rendu pour toutes les instances de composant.

Appliquer un mode de rendu à l’ensemble de l’application

Pour définir le mode de rendu pour l’ensemble de l’application, indiquez le mode de rendu au composant interactif de niveau le plus élevé dans la hiérarchie des composants de l’application qui n’est pas un composant racine.

Remarque

Rendre un composant racine interactif, comme le composant App, n’est pas pris en charge. Par conséquent, le mode de rendu de l’application entière ne peut pas être défini directement par le composant App.

Pour les applications basées sur le modèle de projet Web App Blazor, un mode de rendu affecté à l’ensemble de l’application est généralement spécifié, où le composant Routes est utilisé dans le composant App (Components/App.razor) :

<Routes @rendermode="InteractiveServer" />

Le composant Router propage son mode de rendu aux pages qu’il achemine.

Vous devez également définir le même mode de rendu interactif sur le composant HeadOutlet, qui se trouve également dans le composant App d’une application web Blazor générée à partir du modèle de projet :

<HeadOutlet @rendermode="InteractiveServer" />

Pour les applications qui adoptent un mode de rendu côté client interactif (WebAssembly ou Auto) et qui activent le mode de rendu pour l’ensemble de l’application via le composant Routes :

  • Placez ou déplacez les fichiers de mise en page et de navigation du dossier Components/Layout de l’application serveur dans le dossier .Client du projet Layout. S’il n’existe pas déjà, créez un dossier Layout dans le projet .Client.
  • Placez ou déplacez les composants du dossier Components/Pages de l’application serveur dans le dossier .Client du projet Pages. S’il n’existe pas déjà, créez un dossier Pages dans le projet .Client.
  • Placez ou déplacez les composants Routes du dossier Components de l’application serveur dans le dossier racine du projet .Client.

Pour activer l’interactivité globale lors de la création d’une Web App Blazor :

  • Visual Studio : définissez la liste déroulante Emplacement d'interactivité sur Global.
  • CLI .NET : utilisez l’option -ai|--all-interactive.

Pour plus d’informations, consultez Outils pour ASP.NET Core Blazor.

Appliquer un mode de rendu programmatiquement

Les propriétés et les champs peuvent affecter un mode de rendu.

La deuxième approche décrite dans cette section, qui consiste à définir le mode de rendu par instance de composant, est particulièrement utile lorsque les spécifications de votre application prévoient l’un ou l’autre des scénarios suivants :

  • Vous avez une zone (un dossier) de l’application avec des composants qui doivent adopter un rendu statique côté serveur (SSR statique) et ne s’exécuter que sur le serveur. L’application contrôle le mode de rendu globalement en définissant le mode de rendu sur le Routes composant dans le App composant en fonction du chemin d’accès au dossier.
  • Vous disposez de composants autour de l’application à différents emplacements (pas dans un seul dossier) qui doivent adopter la SSR statique et s’exécuter uniquement sur le serveur. L’application contrôle le mode de rendu par composant en définissant le mode de rendu avec la directive dans les @rendermode instances de composant. La réflexion est utilisée dans le Appcomposant pour définir le mode de rendu du Routes composant.

Dans les deux cas, le composant qui doit adopter le SSR statique doit également forcer un rechargement de page complète.

Les deux scénarios précédents sont abordés avec des exemples dans la section Contrôle précis des modes de rendu plus loin dans cet article. Les deux sous-sections suivantes se concentrent sur les approches de base pour définir le mode de rendu.

Définir le mode de rendu par définition de composant

Une définition de composant peut définir un mode de rendu via un champ privé :

@rendermode renderModeForPage

...

@code {
    private static IComponentRenderMode renderModeForPage = InteractiveServer;
}

Définir le mode de rendu par instance de composant

L’exemple suivant applique le rendu interactif côté serveur (SSR interactif) à tout requête.

<Routes @rendermode="RenderModeForPage" />

...

@code {
    private IComponentRenderMode? RenderModeForPage => InteractiveServer;
}

Des informations supplémentaires sur la propagation du mode de rendu sont fournies dans la section Propagation du mode de rendu plus loin dans cet article. La section Contrôle précis des modes de rendu montre comment utiliser l’approche précédente pour adopter la SSR statique dans des zones spécifiques de l’application (dossiers) ou pour des composants spécifiques répartis autour de l’application avec des affectations de mode de rendu par composant.

Prérendu

Le prérendu est le processus de rendu initial du contenu d’une page sur le serveur sans activation des gestionnaires d’événements pour les contrôles rendus. Le serveur génère l’interface utilisateur HTML de la page dès que possible en réponse à la demande initiale, ce qui rend l’application plus réactive pour les utilisateurs. Le prérendu peut aussi améliorer l’optimisation du référencement d’un site auprès d’un moteur de recherche (SEO) en rendant le contenu de la réponse HTTP initiale qui est utilisée par les moteurs de recherche pour calculer le rang de la page.

Le pré-rendu est activé par défaut pour les composants interactifs.

Pour désactiver le prérendu pour une instance de composant, transmettez l'indicateur prerender avec une valeur de false au mode de rendu :

  • <... @rendermode="new InteractiveServerRenderMode(prerender: false)" />
  • <... @rendermode="new InteractiveWebAssemblyRenderMode(prerender: false)" />
  • <... @rendermode="new InteractiveAutoRenderMode(prerender: false)" />

Pour désactiver le prérendu dans une définition de composant :

  • @rendermode @(new InteractiveServerRenderMode(prerender: false))
  • @rendermode @(new InteractiveWebAssemblyRenderMode(prerender: false))
  • @rendermode @(new InteractiveAutoRenderMode(prerender: false))

Pour désactiver le prérendu pour l’ensemble de l’application, indiquez le mode de rendu au composant interactif de niveau le plus élevé dans la hiérarchie des composants de l’application qui n’est pas un composant racine.

Pour les applications basées sur le modèle de projet Web App Blazor, un mode de rendu affecté à l’ensemble de l’application est spécifié, où le composant Routes est utilisé dans le composant App (Components/App.razor). L’exemple suivant montre comment définir le mode de rendu de l’application sur Interactive Server avec désactivation du prérendu :

<Routes @rendermode="new InteractiveServerRenderMode(prerender: false)" />

Désactivez également le prérendu pour le composant HeadOutlet du composant App :

<HeadOutlet @rendermode="new InteractiveServerRenderMode(prerender: false)" />

Le fait de rendre un composant racine, tel que le composant App, interactif avec la directive @rendermode en haut du fichier de définition du composant racine (.razor) n’est pas pris en charge. Par conséquent, le prérendu ne peut pas être désactivé directement par le composant App.

Rendu statique côté serveur (SSR statique)

Par défaut, les composants utilisent le rendu côté serveur statique (SSR statique). Le composant s’affiche dans le flux de réponses et l’interactivité n’est pas activé.

Dans l’exemple suivant, il n’existe aucune désignation pour le mode de rendu du composant, donc le composant hérite du mode de rendu de son parent. Étant donné qu’aucun composant ancêtre ne spécifie un mode de rendu, le composant suivant est rendu de façon statique sur le serveur. Le bouton n’est pas interactif et n’appelle pas la méthode UpdateMessage lorsqu’il est sélectionné. La valeur de message ne change pas et le composant n’est pas affiché à nouveau en réponse aux événements d’interface utilisateur.

RenderMode1.razor:

@page "/render-mode-1"

<button @onclick="UpdateMessage">Click me</button> @message

@code {
    private string message = "Not updated yet.";

    private void UpdateMessage()
    {
        message = "Somebody updated me!";
    }
}

Si vous utilisez le composant précédent localement dans une application web Blazor, placez le composant dans le dossier Components/Pages du projet serveur. Le projet serveur est le projet de la solution avec un nom qui ne se termine pas par .Client. Lorsque l’application est en cours d’exécution, accédez à /render-mode-1 dans la barre d’adresse du navigateur.

Au cours du rendu côté serveur statique, les demandes de page de composants Razor sont prises en charge par le traitement des demandes de pipeline de middleware ASP.NET Core côté serveur pour le routage et l’autorisation. Les fonctionnalités Blazor dédiées pour le routage et l’autorisation ne sont pas opérationnelles, car les composants Razor ne sont pas rendus pendant le traitement des demandes côté serveur. Les fonctionnalités de routeur Blazor du composant Routes qui ne sont pas disponibles pendant le rendu côté client statique incluent l’affichage :

Si l’application présente une interactivité au niveau racine, le traitement des demandes ASP.NET Core côté serveur n’est pas impliqué après le rendu côté serveur statique initial, ce qui signifie que les fonctionnalités Blazor précédentes fonctionnent normalement.

La navigation améliorée avec SSR statique nécessite une attention particulière lors du chargement de JavaScript. Pour plus d’informations, consultez JavaScript Blazor ASP.NET Core avec rendu côté serveur statique (SSR statique).

Rendu côté serveur interactif (SSR interactif)

Le rendu côté serveur interactif (SSR interactif) affiche le composant de manière interactive à partir du serveur en utilisant Blazor Server. Les interactions avec l’utilisateur sont gérées via une connexion en temps réel avec le navigateur. La connexion de circuit est établie lorsque le composant Serveur est affiché.

Dans l’exemple suivant, le mode de rendu est défini sur SSR interactif en ajoutant @rendermode InteractiveServer à la définition du composant. Le bouton appelle la méthode UpdateMessage lorsqu’il est sélectionné. La valeur message est modifiée et le composant est affiché à nouveau pour mettre à jour le message dans l’interface utilisateur.

RenderMode2.razor :

@page "/render-mode-2"
@rendermode InteractiveServer

<button @onclick="UpdateMessage">Click me</button> @message

@code {
    private string message = "Not updated yet.";

    private void UpdateMessage()
    {
        message = "Somebody updated me!";
    }
}

Si vous utilisez le composant précédent localement dans une application web Blazor, placez le composant dans le dossier Components/Pages du projet serveur. Le projet serveur est le projet de la solution avec un nom qui ne se termine pas par .Client. Lorsque l’application est en cours d’exécution, accédez à /render-mode-2 dans la barre d’adresse du navigateur.

Rendu côté client (CSR)

Le rendu côté client (CSR) affiche le composant de manière interactive sur le client en utilisant Blazor WebAssembly. Le runtime .NET et l’ensemble d'applications sont téléchargés et mis en cache lorsque le composant WebAssembly est initialement affiché. Les composants utilisant CSR doivent être générés à partir d’un projet client distinct qui configure l’hôte Blazor WebAssembly.

Dans l’exemple suivant, le mode de rendu est défini sur CSR avec @rendermode InteractiveWebAssembly. Le bouton appelle la méthode UpdateMessage lorsqu’il est sélectionné. La valeur message est modifiée et le composant est affiché à nouveau pour mettre à jour le message dans l’interface utilisateur.

RenderMode3.razor :

@page "/render-mode-3"
@rendermode InteractiveWebAssembly

<button @onclick="UpdateMessage">Click me</button> @message

@code {
    private string message = "Not updated yet.";

    private void UpdateMessage()
    {
        message = "Somebody updated me!";
    }
}

Si vous utilisez le composant précédent localement dans une application web Blazor, placez le composant dans le dossier Pages du projet client. Le projet client est le projet de la solution dont le nom se termine par .Client. Lorsque l’application est en cours d’exécution, accédez à /render-mode-3 dans la barre d’adresse du navigateur.

Rendu automatique (Auto)

Le rendu automatique (Auto) détermine comment afficher le composant au moment de l’exécution. Le composant est initialement affiché avec le rendu côté serveur interactif (SSR interactif) en utilisant le modèle d’hébergement Blazor Server. Le runtime .NET et l’ensemble d'applications sont téléchargés sur le client en arrière-plan et mis en cache afin de pouvoir être utilisés lors de visites ultérieures.

Le mode de rendu automatique ne modifie jamais dynamiquement le mode de rendu d’un composant déjà sur la page. Le mode de rendu automatique prend une décision initiale sur le type d’interactivité à utiliser pour un composant, puis le composant conserve ce type d’interactivité tant qu’il se trouve sur la page. L’un des facteurs de cette décision initiale consiste à déterminer si les composants existent déjà sur la page avec l’interactivité WebAssembly/Server. Le mode automatique préfère sélectionner un mode de rendu qui correspond au mode de rendu des composants interactifs existants. La raison pour laquelle le mode automatique préfère utiliser un mode d’interactivité existant consiste à éviter d’introduire un nouveau runtime interactif qui ne partage pas l’état avec le runtime existant.

Les composants utilisant le mode de rendu Auto doivent être générés à partir d’un projet client distinct qui configure l’hôte Blazor WebAssembly.

Dans l’exemple suivant, le composant est interactif tout au long du processus. Le bouton appelle la méthode UpdateMessage lorsqu’il est sélectionné. La valeur message est modifiée et le composant est affiché à nouveau pour mettre à jour le message dans l’interface utilisateur. Initialement, le composant est affiché de manière interactive à partir du serveur, mais lors des visites suivantes, il est affiché à partir du client après que le runtime .NET et l’ensemble d’applications ont été téléchargés et mis en cache.

RenderMode4.razor :

@page "/render-mode-4"
@rendermode InteractiveAuto

<button @onclick="UpdateMessage">Click me</button> @message

@code {
    private string message = "Not updated yet.";

    private void UpdateMessage()
    {
        message = "Somebody updated me!";
    }
}

Si vous utilisez le composant précédent localement dans une application web Blazor, placez le composant dans le dossier Pages du projet client. Le projet client est le projet de la solution dont le nom se termine par .Client. Lorsque l’application est en cours d’exécution, accédez à /render-mode-4 dans la barre d’adresse du navigateur.

Propagation du mode de rendu

Les modes de rendu se propagent dans la hiérarchie des composants.

Règles d’application des modes de rendu :

  • Le mode de rendu par défaut est Statique.
  • Les modes de rendu Serveur interactif (InteractiveServer), WebAssembly interactif (InteractiveWebAssembly) et Auto interactif (InteractiveAuto) peuvent être utilisés à partir d’un composant, notamment en utilisant des modes de rendu différents pour les composants frères.
  • Vous ne pouvez pas basculer vers un autre mode de rendu interactif dans un composant enfant. Par exemple, un composant Serveur ne peut pas être un enfant d’un composant WebAssembly.
  • Les paramètres transmis à un composant enfant interactif à partir d'un parent statique doivent être sérialisables JSON. Cela signifie que vous ne pouvez pas transmettre de fragments de rendu ou de contenu enfant d’un composant parent statique à un composant enfant interactif.

Les exemples suivants utilisent un composant SharedMessage non routable et non page. Le composant SharedMessage indépendant du mode de rendu n’applique pas de mode de rendu avec une directive @attribute. Si vous testez ces scénarios avec une application web Blazor, placez le composant suivant dans le dossier Components de l’application.

SharedMessage.razor :

<p>@Greeting</p>

<button @onclick="UpdateMessage">Click me</button> @message

<p>@ChildContent</p>

@code {
    private string message = "Not updated yet.";

    [Parameter]
    public RenderFragment? ChildContent { get; set; }

    [Parameter]
    public string Greeting { get; set; } = "Hello!";

    private void UpdateMessage()
    {
        message = "Somebody updated me!";
    }
}

Héritage du mode de rendu

Si le composant SharedMessage est placé dans un composant parent rendu statiquement, le composant SharedMessage est également affiché de manière statique et n’est pas interactif. Le bouton n’appelle pas UpdateMessage et le message n’est pas mis à jour.

RenderMode5.razor :

@page "/render-mode-5"

<SharedMessage />

Si le composant SharedMessage est placé dans un composant qui définit le mode de rendu, il hérite du mode de rendu appliqué.

Dans l’exemple suivant, le composant SharedMessage est interactif via une connexion SignalR au client. Le bouton appelle UpdateMessageet le message est mis à jour.

RenderMode6.razor :

@page "/render-mode-6"
@rendermode InteractiveServer

<SharedMessage />

Composants enfants avec différents modes de rendu

Dans l’exemple suivant, les deux composants SharedMessage sont pré-rendus (par défaut) et apparaissent lorsque la page est affichée dans le navigateur.

  • Le premier composant SharedMessage avec rendu côté serveur interactif (SSR interactif) est interactif une fois le circuit SignalR établi.
  • Le deuxième composant SharedMessage avec rendu côté client (CSR) est interactif une fois l’ensemble d’applications Blazor téléchargé et le runtime .NET actif sur le client.

RenderMode7.razor :

@page "/render-mode-7"

<SharedMessage @rendermode="InteractiveServer" />
<SharedMessage @rendermode="InteractiveWebAssembly" />

Composant enfant avec un paramètre sérialisable

L’exemple suivant illustre un composant enfant interactif qui prend un paramètre. Les paramètres doivent être sérialisables.

RenderMode8.razor :

@page "/render-mode-8"

<SharedMessage @rendermode="InteractiveServer" Greeting="Welcome!" />

Les paramètres de composants non sérialisables, tels que le contenu enfant ou un fragment de rendu, ne sont pas pris en charge. Dans l’exemple suivant, le passage du contenu enfant au composant SharedMessage entraîne une erreur de runtime.

RenderMode9.razor :

@page "/render-mode-9"

<SharedMessage @rendermode="InteractiveServer">
    Child content
</SharedMessage>

Erreur :

System.InvalidOperationException : impossible de transmettre le paramètre « ChildContent » au composant « SharedMessage » avec le mode de rendu « InteractiveServerRenderMode ». Cela est dû au fait que le paramètre est de type délégué « Microsoft.AspNetCore.Components.RenderFragment », qui est un code arbitraire et ne peut pas être sérialisé.

Pour contourner la limitation précédente, enveloppez le composant enfant dans un autre composant qui n’a pas le paramètre. Il s’agit de l’approche adoptée dans le modèle de projet de l’application web Blazor avec le composant Routes (Components/Routes.razor) pour envelopper le composant Router.

WrapperComponent.razor :

<SharedMessage>
    Child content
</SharedMessage>

RenderMode10.razor :

@page "/render-mode-10"

<WrapperComponent @rendermode="InteractiveServer" />

Dans l'exemple précédent :

  • Le contenu enfant est transmis au composant SharedMessage sans générer d’erreur de runtime.
  • Le composant SharedMessage s’affiche de manière interactive sur le serveur.

Composant enfant avec un mode de rendu différent de son parent

N’essayez pas d’appliquer à un composant enfant un mode de rendu interactif différent de celui de son parent.

Le composant suivant génère une erreur de runtime lorsque le composant est rendu :

RenderMode11.razor :

@page "/render-mode-11"
@rendermode InteractiveServer

<SharedMessage @rendermode="InteractiveWebAssembly" />

Erreur :

Cannot create a component of type 'BlazorSample.Components.SharedMessage' because its render mode 'Microsoft.AspNetCore.Components.Web.InteractiveWebAssemblyRenderMode' is not supported by Interactive Server rendering.

Contrôle précis des modes de rendu

Dans certains cas, les spécifications de l’application prévoient que les composants adoptent un rendu statique côté serveur (static SSR) et ne s’exécutent que sur le serveur, tandis que le reste de l’application utilise un mode de rendu interactif.

Deux approches peuvent être adoptées pour le contrôle fin des modes de rendu, chacune d’entre elles étant décrite dans les sous-sections suivantes :

  • Zone (dossier) des composants SSR statiques : vous disposez d’une zone (dossier) de l’application avec des composants qui doivent adopter le SSR statique et partager le même préfixe de chemin d’accès d’itinéraire. L’application contrôle le mode de rendu globalement en définissant le mode de rendu sur le Routes composant dans le App composant en fonction du chemin d’accès au dossier.

  • Composants SSR statiques répartis sur l’application : vous avez des composants répartis dans l’application à différents emplacements qui doivent adopter le SSR statique et s’exécuter uniquement sur le serveur. Les composants statiques du SSR ne se trouvent pas dans un dossier unique et ne partagent pas le même préfixe de chemin d’accès. L’application contrôle le mode de rendu par composant en définissant le mode de rendu avec la directive dans les @rendermode instances de composant. La réflexion est utilisée dans le Appcomposant pour définir le mode de rendu du Routes composant.

Dans les deux cas, le composant qui doit adopter le SSR statique doit également forcer un rechargement de page complète.

Les exemples suivants utilisent le HttpContext paramètre en cascade pour déterminer si la page est rendue statiquement. Un nullHttpContext indique que le composant a un rendu interactif, ce qui est utile comme signal dans le code de l’application pour déclencher un rechargement complet de la page.

Zone (dossier) des composants SSR statiques

L’approche décrite dans cette sous-section est utilisée par le modèle de Blazor projet Web App avec authentification individuelle et interactivité globale.

Une zone (dossier) de l’application contient les composants qui doivent adopter un SSR statique et ne s’exécuter que sur le serveur. Les composants du dossier partagent le même préfixe de chemin d’accès. Par exemple, les IdentityRazor composants du Blazor modèle de projet Web App se trouvent dans le Components/Account/Pages dossier et partagent le préfixe du chemin d’accès racine /Account.

Le dossier contient également un fichier _Imports.razor, qui applique un layout de compte personnalisé aux composants du dossier :

@using BlazorSample.Components.Account.Shared
@layout AccountLayout

Le dossier Shared gère le composant de layout AccountLayout. Le composant utilise HttpContext pour déterminer si le composant est rendu sur le serveur. Identity composants doivent s’afficher sur le serveur avec un SSR statique, car ils définissent Identitycookies. Si la valeur est HttpContextnull, le composant est rendu de manière interactive et un rechargement de page complète est effectué en appelant NavigationManager.Refresh avec forceLoad la valeur définie sur true. Cela force une nouvelle version complète de la page à l’aide de la fonction SSR statique.

Components/Account/Shared/AccountLayout.razor :

@inherits LayoutComponentBase
@layout BlazorSample.Components.Layout.MainLayout
@inject NavigationManager NavigationManager

@if (HttpContext is null)
{
    <p>Loading...</p>
}
else
{
    @Body
}

@code {
    [CascadingParameter]
    private HttpContext? HttpContext { get; set; }

    protected override void OnParametersSet()
    {
        if (HttpContext is null)
        {
            NavigationManager.Refresh(forceReload: true);
        }
    }
}

Remarque

Dans le Blazor modèle de projet Web App, il existe un deuxième fichier de layout (ManageLayout.razor dans le Components/Account/Shared dossier) pour Identity les composants du Components/Account/Pages/Manage dossier. Le Manage dossier possède son propre _Imports.razor fichier à appliquer aux ManageLayout composants du dossier. Dans vos propres applications, l’utilisation de fichiers imbriqués _Imports.razor est une approche utile pour appliquer des layouts personnalisés à des groupes de pages.

Dans le App composant, toute requête d’un composant dans le Account dossier applique un null mode de rendu, qui applique la SSR statique. D’autres demandes de composant reçoivent une application globale du mode de rendu SSR interactif (InteractiveServer).

Important

L’application d’un null mode de rendu n’applique pas toujours la SSR statique. Il arrive simplement de se comporter de cette façon à l’aide de l’approche présentée dans cette section.

Un null mode de rendu est effectivement identique à ne pas spécifier de mode de rendu, ce qui entraîne l’héritage du mode de rendu de son parent. Dans ce cas, le App composant est rendu à l’aide du SSR statique. Par conséquent, un null mode de rendu entraîne l’héritage Routes du SSR statique du App composant. Si un mode de rendu nul est spécifié pour un composant enfant dont le parent utilise un mode de rendu interactif, l’enfant hérite du même mode de rendu interactif.

Components/App.razor :

<Routes @rendermode="RenderModeForPage" />

...

@code {
    [CascadingParameter]
    private HttpContext HttpContext { get; set; } = default!;

    private IComponentRenderMode? RenderModeForPage => 
        HttpContext.Request.Path.StartsWithSegments("/Account")
            ? null
            : {INTERACTIVE RENDER MODE};
}

Dans le code précédent, remplacez l’espace {INTERACTIVE RENDER MODE} réservé par la valeur appropriée, selon que le reste de l’application doit adopter le rendu global InteractiveServer, InteractiveWebAssemblyou le rendu InteractiveAuto.

Les composants qui doivent adopter le SSR statique dans le Account dossier ne sont pas nécessaires pour définir le layout, car elles sont appliquées via le _Imports.razor fichier et les composants ne définissent pas de mode de rendu, car ils doivent s’afficher avec le SSR statique. Rien d’autre ne doit être effectué pour les composants du Account dossier afin d’appliquer la SSR statique.

Composants SSR statiques répartis dans l’application

Dans la sous-section précédente, l’application contrôle le mode de rendu des composants en définissant le mode de rendu globalement dans le composant App. App Le composant peut également adopter des modes de rendu par composant pour définir le mode de rendu, ce qui permet aux composants répartis autour de l’application d’appliquer l’adoption de la SSR statique. Cette sous-section décrit l’approche.

L’application a un layout personnalisé qui peut être appliqué aux composants autour de l’application. En règle générale, un composant partagé pour l’application est placé dans le dossier Components/Layout. Le composant utilise HttpContext pour déterminer si le composant est rendu sur le serveur. Si la valeur est HttpContextnull, le composant est rendu de manière interactive et un rechargement de page complète est effectué en appelant NavigationManager.Refresh avec forceLoad la valeur définie sur true. Cela déclenche une requête au serveur pour le composant.

Components/Layout/StaticSsrLayout.razor :

@inherits LayoutComponentBase
@layout MainLayout
@inject NavigationManager NavigationManager

@if (HttpContext is null)
{
    <p>Loading...</p>
}
else
{
    @Body
}

@code {
    [CascadingParameter]
    private HttpContext? HttpContext { get; set; }

    protected override void OnParametersSet()
    {
        if (HttpContext is null)
        {
            NavigationManager.Refresh(forceReload: true);
        }
    }
}

Dans le composant App, la réflexion est utilisée pour définir le mode de rendu. Quel que soit le mode de rendu affecté au fichier de définition de composant individuel, il est appliqué au composant Routes.

Components/App.razor :

<Routes @rendermode="RenderModeForPage" />

...

@code {
    [CascadingParameter]
    private HttpContext HttpContext { get; set; } = default!;

    private IComponentRenderMode? RenderModeForPage =>
        HttpContext.GetEndpoint()?.Metadata.GetMetadata<RenderModeAttribute>()?
            .Mode;
}

Chaque composant qui doit adopter le SSR statique définit le layout personnalisée et ne spécifie pas de mode de rendu. L’absence de spécification d’un mode de rendu entraîne une null valeur du RenderModeAttribute.Mode dans le composant App, ce qui n’entraîne aucun mode de rendu affecté à l’instance du composant Routes et à l’application de la SSR statique.

Important

L’application d’un null mode de rendu n’applique pas toujours la SSR statique. Il arrive simplement de se comporter de cette façon à l’aide de l’approche présentée dans cette section.

Un null mode de rendu est effectivement identique à ne pas spécifier de mode de rendu, ce qui entraîne l’héritage du mode de rendu de son parent. Dans ce cas, le App composant est rendu à l’aide du SSR statique. Par conséquent, un null mode de rendu entraîne l’héritage Routes du SSR statique du App composant. Si un mode de rendu nul est spécifié pour un composant enfant dont le parent utilise un mode de rendu interactif, l’enfant hérite du même mode de rendu interactif.

Pour que les composants appliquent le rendu côté client statique, il ne reste qu’à appliquer la disposition personnalisée sans définir de mode de rendu interactif :

@layout BlazorSample.Components.Layout.StaticSsrLayout

Les composants interactifs autour de l’application évitent d’appliquer la disposition de rendu côté client statique personnalisée et définissent uniquement un mode de rendu interactif approprié, qui, après réflexion dans le composant App, est appliqué au composant Routes :

@rendermode {INTERACTIVE RENDER MODE}

Dans le code précédent, remplacez l’espace réservé {INTERACTIVE RENDER MODE} par la valeur appropriée, selon que le reste de l’application doit adopter le rendu global InteractiveServer, InteractiveWebAssemblyou le rendu InteractiveAuto.

Les services côté client ne parviennent pas à être résolus lors du prérendu

En supposant que le prérendu n’est pas désactivé pour un composant ou pour l’application, un composant du projet .Client est prérendu sur le serveur. Le serveur n’ayant pas accès aux services Blazor côté client inscrits, il n’est pas possible d’injecter ces services dans un composant sans recevoir d’erreur indiquant que le service n’a pas pu être trouvé lors du prérendu.

Par exemple, considérez le composant Home suivant dans le projet .Client d’une Web App Blazor avec rendu global Interactive WebAssembly ou Interactive Auto. Le composant tente d’injecter IWebAssemblyHostEnvironment pour obtenir le nom de l’environnement.

@page "/"
@inject IWebAssemblyHostEnvironment Environment

<PageTitle>Home</PageTitle>

<h1>Home</h1>

<p>
    Environment: @Environment.Environment
</p>

Aucune erreur de temps de compilation ne se produit, mais une erreur de runtime se produit pendant le prérendu :

Impossible de fournir une valeur pour la propriété « Environment » sur le type « BlazorSample.Client.Pages.Home ». Il n’existe aucun service inscrit de type « Microsoft.AspNetCore.Components.WebAssembly.Hosting.IWebAssemblyHostEnvironment ».

Cette erreur se produit, car le composant doit compiler et s’exécuter sur le serveur pendant le prérendu, mais IWebAssemblyHostEnvironment n’est pas un service inscrit sur le serveur.

Si l’application n’a pas besoin de la valeur pendant le prérendu, ce problème peut être résolu en injectant IServiceProvider pour obtenir le service au lieu du type de service lui-même :

@page "/"
@using Microsoft.AspNetCore.Components.WebAssembly.Hosting
@inject IServiceProvider Services

<PageTitle>Home</PageTitle>

<h1>Home</h1>

<p>
    <b>Environment:</b> @environmentName
</p>

@code {
    private string? environmentName;

    protected override void OnInitialized()
    {
        if (Services.GetService<IWebAssemblyHostEnvironment>() is { } env)
        {
            environmentName = env.Environment;
        }
    }
}

Toutefois, l’approche précédente n’est pas utile si votre logique nécessite une valeur pendant le prérendu.

Vous pouvez également éviter le problème si vous désactivez le prérendu pour le composant, mais c’est une mesure extrême à prendre dans de nombreux cas qui peuvent ne pas répondre aux spécifications de votre composant.

Il existe trois approches que vous pouvez prendre pour aborder ce scénario. Les éléments suivants sont listés du plus recommandé au moins recommandé :

  • Recommandé pour les services de framework partagé : pour les services de framework partagé qui ne sont simplement pas inscrits côté serveur dans le projet principal, inscrivez les services dans le projet principal, ce qui les rend disponibles lors de la préversion. Pour obtenir un exemple de ce scénario, consultez les conseils pour les services HttpClient dans Appeler une API web à partir d’une application Blazor ASP.NET Core.

  • Recommandé pour les services en dehors du cadre partagé : créez une implémentation de service personnalisé pour le service sur le serveur. Utilisez normalement le service dans les composants interactifs du projet .Client. Pour une démonstration de cette approche, consultez ASP.NET Core Blazor environnements.

  • Créez une abstraction de service et créez des implémentations pour le service dans les projets .Client et serveur. Inscrivez les services dans chaque projet. Injectez le service personnalisé dans le composant.

  • Vous pouvez peut-être ajouter une référence de package de projet .Client à un package côté serveur et revenir à l’utilisation de l’API côté serveur pendant le prérendu sur le serveur.

Découvrir des composants d’assemblys supplémentaires

Des assemblys supplémentaires doivent être divulgués à l’infrastructure Blazor pour découvrir les composants Razor routables dans les projets référencés. Pour plus d’informations, consultez Routage et navigation ASP.NET Core Blazor.

Fermeture des circuits quand il ne reste plus de composants de serveur interactif

Les composants de serveur interactif gèrent les événements de l’interface utilisateur web en utilisant une connexion en temps réel avec le navigateur, appelée un circuit. Un circuit et son état associé sont créés quand un composant de serveur interactif racine est rendu. Le circuit est fermé quand il ne reste plus de composants de serveur interactif sur la page, ce qui libère des ressources du serveur.

Modes de rendu abrégés personnalisés

La directive @rendermode prend un seul paramètre qui est une instance statique de type IComponentRenderMode. L'attribut directive @rendermode peut prendre n'importe quelle instance de mode de rendu, statique ou non. Le framework Blazor fournit à la classe statique RenderMode avec certains modes de rendu prédéfinis pour plus de commodité, mais vous pouvez créer les vôtres.

Normalement, un composant utilise la directive @rendermode suivante pour désactiver le prérendu :

@rendermode @(new InteractiveServerRenderMode(prerender: false))

Toutefois, considérez l’exemple suivant qui crée un mode de rendu côté serveur interactif abrégé sans prérendu via le fichier _Imports de l’application (Components/_Imports.razor) :

public static IComponentRenderMode InteractiveServerWithoutPrerendering { get; } = 
    new InteractiveServerRenderMode(prerender: false);

Utilisez le mode de rendu abrégé dans les composants dans tout le dossier Components :

@rendermode InteractiveServerWithoutPrerendering

Une instance à composant unique peut également définir un mode de rendu personnalisé via un champ privé :

@rendermode interactiveServerWithoutPrerendering

...

@code {
    private static IComponentRenderMode interactiveServerWithoutPrerendering = 
        new InteractiveServerRenderMode(prerender: false);
}

Pour le moment, l'approche du mode de rendu abrégé n'est probablement utile que pour réduire la verbosité de la spécification de l'indicateur prerender. L'approche abrégée pourrait être plus utile à l'avenir si des indicateurs supplémentaires deviennent disponibles pour le rendu interactif et si vous souhaitez créer des modes de rendu abrégés avec différentes combinaisons d'indicateurs.

Injection de service via un fichier d’importation de niveau supérieur (_Imports.razor)

Cette section s’applique uniquement aux Blazorapplications web.

Un fichier d’importation de niveau supérieur dans le dossier Components (Components/_Imports.razor) injecte ses références dans tous les composants de la hiérarchie de dossiers, qui inclut le composant App (App.razor). Le composant App est toujours rendu statiquement, même si le prérendu d’un composant de page est désactivé. Par conséquent, l’injection de services via le fichier d’importation de niveau supérieur entraîne la résolution de deux instances du service dans les composants de page.

Pour résoudre ce scénario, injectez le service dans un nouveau fichier d’importation placé dans le dossier Pages (Components/Pages/_Imports.razor). À partir de cet emplacement, le service est résolu une seule fois dans les composants de page.

Ressources supplémentaires