Freigeben über


ASP.NET Core Blazor-Rendermodi

Hinweis

Dies ist nicht die neueste Version dieses Artikels. Die aktuelle Version finden Sie in der .NET 9-Version dieses Artikels.

Wichtig

Diese Informationen beziehen sich auf ein Vorabversionsprodukt, das vor der kommerziellen Freigabe möglicherweise noch wesentlichen Änderungen unterliegt. Microsoft gibt keine Garantie, weder ausdrücklich noch impliziert, hinsichtlich der hier bereitgestellten Informationen.

Die aktuelle Version finden Sie in der .NET 9-Version dieses Artikels.

In diesem Artikel wird das Steuerelement der Razor-Komponentenwiedergabe in Blazor Web Apps entweder zur Kompilierungszeit oder zur Laufzeit erläutert.

Dieser Leitfaden gilt nicht für eigenständige Blazor WebAssembly-Apps. Blazor WebAssembly- Apps werden nur über eine clientseitige WebAssembly-basierte Laufzeit auf dem Client gerendert und haben kein Konzept eines Rendermodus. Wenn ein Rendermodus auf eine Komponente in einer Blazor WebAssembly-App angewendet wird, hat die Rendermodusbezeichnung keinen Einfluss auf das Rendern der Komponente.

Rendermodi

Jede Komponente in einer Blazor Web App verwendet einen Rendering-Modus, um das verwendete Hosting-Modell, den Ort der Darstellung und die Interaktivität zu bestimmen.

Die folgende Tabelle zeigt die verfügbaren Rendermodi zum Rendern von Razor-Komponenten in einer Blazor Web App. Verwenden Sie die @rendermode-Anweisung für die Komponenteninstanz oder die Komponentendefinition, um einen Rendermodus auf eine Komponente anzuwenden. Weiter unten in diesem Artikel werden Beispiele für jedes Rendermodusszenario gezeigt.

Name Beschreibung Renderort Interactive
Statischer Server Statisches serverseitiges Rendering (Statisches SSR) Server Nein
Server (interaktiv) Interaktives serverseitiges Rendering (interaktives SSR) mittels Blazor Server. Server Ja
WebAssembly (interaktiv) Clientseitiges Rendering (CSR) mittels Blazor WebAssembly†. Client Ja
Automatisch (interaktiv) Interaktives SSR bei der Blazor Server ersten Verwendung und CSR bei späteren Besuchen nach dem Herunterladen des Blazor-Pakets. Server, dann Client Ja

†Clientseitiges Rendering (CSR) wird als interaktiv angenommen. „Interaktives clientseitiges Rendering“ und „interaktives CSR“ werden nicht von der Branche oder in der Blazor-Dokumentation verwendet.

Die Vorabrendering ist standardmäßig für interaktive Komponenten aktiviert. Anleitungen zur Steuerung des Vorabrenderings finden Sie weiter unten in diesem Artikel. Allgemeine Branchenterminologie zu Client- und Serverrenderingkonzepten finden Sie unter ASP.NET Core Blazor Grundlagen.

Die folgenden Beispiele veranschaulichen das Festlegen des Rendermodus der Komponente mit einigen grundlegenden Features der Razor-Komponente.

Um das Rendermodusverhalten lokal zu testen, können Sie die folgenden Komponenten in eine App einfügen, die mithilfe der Blazor Web App-Projektvorlage erstellt wurde. Wenn Sie die App erstellen, wählen Sie die Optionen aus Dropdownmenüs (Visual Studio), oder wenden Sie die CLI-Optionen (.NET CLI) an, um sowohl serverseitige als auch clientseitige Interaktivität zu aktivieren. Anleitungen zum Erstellen einer Blazor Web App finden Sie unter Tools für ASP.NET Core Blazor.

Aktivieren der Unterstützung für interaktive Rendermodi

Eine Blazor Web App muss so konfiguriert werden, dass interaktive Rendermodi unterstützt werden. Die folgenden Erweiterungen werden automatisch auf Apps angewendet, die während der App-Erstellung mithilfe der Blazor Web App-Projektvorlage erstellt wurden. Einzelne Komponenten müssen weiterhin ihren Rendermodus gemäß den Angaben unter Rendermodi deklarieren, nachdem die Komponentendienste und Endpunkte in der Program-Datei der App konfiguriert wurden.

Dienste für Razor-Komponenten werden durch Aufrufen von AddRazorComponents hinzugefügt.

Erweiterungen für den Komponenten-Generator:

MapRazorComponents ermittelt die verfügbaren Komponenten und gibt die Stammkomponente für die App (die erste geladene Komponente) an. Dabei handelt es sich standardmäßig um die App-Komponente (App.razor).

Erweiterungen für den Endpunktkonventions-Generator:

Hinweis

Die richtige Position der API in den folgenden Beispielen können Sie in der Program-Datei einer App nachsehen, die mithilfe der Blazor Web App-Projektvorlage generiert wurde. Anleitungen zum Erstellen einer Blazor Web App finden Sie unter Tools für ASP.NET Core Blazor.

Beispiel 1: Die folgende Program-Datei-API fügt Dienste und Konfigurationen zum Aktivieren von interaktivem SSR hinzu:

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

Beispiel 2: Die folgende Program-Datei-API fügt Dienste und Konfiguration zum Aktivieren des Rendermodus „WebAssembly (interaktiv)“ hinzu:

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

Beispiel 3: Die folgende Program-Datei-API fügt Dienste und eine Konfiguration zum Aktivieren der Rendermodi „Server (interaktiv)“, „WebAssembly (interaktiv)“ und „Automatisch (interaktiv)“ hinzu:

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

Blazor verwendet das Blazor WebAssembly-Hostingmodell zum Herunterladen und Ausführen von Komponenten, die den Rendermodus „WebAssembly (interaktiv)“ verwenden. Ein separates Clientprojekt ist erforderlich, um das Blazor WebAssembly-Hosting für diese Komponenten einzurichten. Das Clientprojekt enthält den Startcode für den Blazor WebAssembly-Host und richtet die .NET-Runtime für die Ausführung in einem Browser ein. Die Blazor Web App-Vorlage fügt dieses Clientprojekt für Sie hinzu, wenn Sie die Option zum Aktivieren der WebAssembly-Interaktivität auswählen. Alle Komponenten, die den Rendermodus „WebAssembly (interaktiv)“ verwenden, sollten aus dem Clientprojekt erstellt werden, sodass sie im heruntergeladenen App Bundle enthalten sind.

Anwenden eines Rendermodus auf eine Komponenteninstanz

Wenn Sie einen Rendermodus auf eine Komponenteninstanz anwenden möchten, verwenden Sie das Attribut der @rendermodeRazor-Anweisung, in der die Komponente verwendet wird.

Im folgenden Beispiel wird das interaktive serverseitige Rendering (interaktives SSR) auf die Dialog-Komponenteninstanz angewendet:

<Dialog @rendermode="InteractiveServer" />

Hinweis

BlazorVorlagen enthalten eine statische using Direktive für RenderMode die Datei (_Imports) der App Components/_Imports.razor für kürzere @rendermode Syntax:

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

Ohne die vorstehende Direktive müssen Komponenten die statische RenderMode-Klasse in der @rendermode-Syntax explizit angeben:

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

Sie können mit der benutzerdefinierten Konfiguration auch auf benutzerdefinierte Rendermodusinstanzen verweisen, die direkt instanziiert werden. Weitere Informationen finden Sie im Abschnitt Benutzerdefinierte Rendering-Modi in Kurzform weiter unten in diesem Artikel.

Anwenden eines Rendermodus auf eine Komponentendefinition

Um den Rendermodus für eine Komponente als Teil der Definition anzugeben, verwenden Sie die @rendermodeRazor-Anweisung und das entsprechende Rendermodusattribut.

@page "..."
@rendermode InteractiveServer

Das Anwenden eines Rendermodus auf eine Komponentendefinition wird häufig verwendet, wenn ein Rendermodus auf eine bestimmte Seite angewendet wird. Routingfähige Seiten verwenden standardmäßig denselben Rendermodus wie die Router-Komponente, die die Seite gerendert hat.

Theoretisch ist die @rendermode-Klasse eine Razor-Anweisung und ein Razoranweisendes -Attribut. Die Semantik ist ähnlich, doch es gibt Unterschiede. Die @rendermode-Anweisung bezieht sich auf die Komponentendefinition, sodass die Rendermodusinstanz, auf die sie verweist, statisch sein muss. Das anweisende @rendermode-Attribut kann eine beliebige Rendermodusinstanz verwenden.

Hinweis

Komponentenersteller*innen sollten vermeiden, die Implementierung einer Komponente an einen bestimmten Rendermodus zu koppeln. Komponentenersteller*innen sollten stattdessen Komponenten entwerfen, die jeden Rendermodus oder jedes Hostingmodell unterstützen. Die Implementierung einer Komponente sollte Annahmen darüber vermeiden, wo sie ausgeführt wird (Server oder Client) und sollte beim statischen Rendern sinnvoll herabgestuft werden. Die Angabe des Rendermodus in der Komponentendefinition kann erforderlich sein, wenn die Komponente nicht direkt instanziiert wird (z. B. mit einer routingfähigen Seitenkomponente), oder um einen Rendermodus für alle Komponenteninstanzen anzugeben.

Anwenden eines Rendermodus auf die gesamte App

Um den Rendermodus für die gesamte App festzulegen, geben Sie den Rendermodus für die interaktive Komponente der höchsten Ebene in der App-Hierarchie an, die keine Stammkomponente ist.

Hinweis

Die Interaktivität einer Stammkomponente, wie z. B. der App-Komponente, wird nicht unterstützt. Daher kann der Rendermodus für die gesamte App nicht direkt von der Komponente App festgelegt werden.

Bei Anwendungen, die auf der Blazor Web App-Projektvorlage basieren, wird typischerweise ein Rendermodus, der der gesamten Anwendung zugewiesen wird, dort angegeben, wo die Routes-Komponente in der App-Komponente (Components/App.razor) verwendet wird:

<Routes @rendermode="InteractiveServer" />

Die Router-Komponente gibt seinen Rendermodus an die ihm zugehörigen Seiten weiter.

Außerdem müssen Sie in der Regel den gleichen interaktiven Rendermodus für die HeadOutlet-Komponente festlegen, der auch in der App-Komponente einer Blazor Web App verwendet wird, die aus der Projektvorlage generiert wird:

<HeadOutlet @rendermode="InteractiveServer" />

Bei Apps, die den interaktiven clientseitigen Rendermodus (WebAssembly oder Auto) übernehmen und den Rendermodus für die gesamte App über die Routes-Komponente aktivieren:

  • Platzieren oder verschieben Sie die Layout- und Navigationsdateien des Ordners Components/Layout der Server-App in den Ordner .Client des Layout-Projekts. Erstellen Sie einen Layout-Ordner im .Client-Projekt, falls dieser noch nicht vorhanden ist.
  • Platzieren oder verschieben Sie die Komponenten des Ordners Components/Pages der Server-App in den Ordner .Client des Pages-Projekts. Erstellen Sie einen Pages-Ordner im .Client-Projekt, falls dieser noch nicht vorhanden ist.
  • Platzieren oder verschieben Sie die Routes-Komponente des Ordners Components der Server-App in den Stammordner des .Client-Projekts.

So aktivieren Sie die Interaktivität beim Erstellen einer Blazor Web App:

  • Visual Studio: Legen Sie die Dropdownliste für Interaktivitätsspeicherort auf Global fest.
  • .NET-CLI: Verwenden Sie die Option -ai|--all-interactive.

Weitere Informationen finden Sie unter Tools für ASP.NET Core Blazor.

Programmgesteuertes Anwenden eines Rendermodus

Eigenschaften und Felder können einen Rendermodus zuweisen.

Der zweite in diesem Abschnitt beschriebene Ansatz, bei dem der Rendermodus nach Komponenteninstanz festgelegt wird, ist besonders hilfreich, wenn gemäß Ihrer App-Spezifikation mindestens eine Komponente statisches SSR in einer global interaktiven App umsetzen muss. Dieses Szenario wird weiter unten in diesem Artikel im Abschnitt Seiten mit statischem SSR in einer global interaktiven App behandelt.

Festlegen des Rendermodus nach Komponentendefinition

Eine Komponentendefinition kann einen Rendermodus über ein privates Feld definieren:

@rendermode pageRenderMode

...

@code {
    private static IComponentRenderMode pageRenderMode = InteractiveServer;
}

Festlegen des Rendermodus nach Komponenteninstanz

Im folgenden Beispiel wird interaktives serverseitiges Rendering (interaktives SSR) auf jede Anforderung angewendet.

<Routes @rendermode="PageRenderMode" />

...

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

Weitere Informationen zur Verteilung des Rendermodus finden Sie weiter unten in diesem Artikel im Abschnitt zur Verteilung im Rendermodus. Im Abschnitt Seiten mit statischem SSR in einer global interaktiven App wird gezeigt, wie Sie mit dem vorherigen Ansatz statisches SSR in einer global interaktiven App übernehmen.

Erkennen des Renderorts, der Interaktivität und des zugewiesenen Rendermodus zur Laufzeit

Die Eigenschaften ComponentBase.RendererInfo und ComponentBase.AssignedRenderMode ermöglichen es der App, Details zum Standort, zur Interaktivität und zum zugewiesenen Rendermodus einer Komponente zu erkennen:

  • RendererInfo.Name gibt den Speicherort zurück, an dem die Komponente ausgeführt wird:
    • Static: Auf dem Server (SSR) und unfähig zu Interagieren.
    • Server: Auf dem Server (SSR) und in der Lage nach dem Vorabendering zu Interagieren.
    • WebAssembly: Auf dem Client (CSR) und in der Lage nach der Vorabendering zu Interagieren.
    • WebView: Auf dem systemeigenen Gerät und in der Lage nach der Vorabendering zu Interagieren.
  • RendererInfo.IsInteractive gibt an, ob die Komponente interaktivität zum Zeitpunkt des Renderings unterstützt. Der Wert ist true beim interaktiven Rendern oder false beim Vorabendering oder für statische SSR (RendererInfo.Name von Static).
  • ComponentBase.AssignedRenderMode macht den zugewiesenen Rendermodus der Komponente verfügbar:
    • InteractiveServer für interaktive Server.
    • InteractiveAuto für interaktives Auto.
    • InteractiveWebAssembly für Interactive WebAssembly.

Komponenten verwenden diese Eigenschaften, um Inhalte abhängig vom Standort- oder Interaktivitätsstatus zu rendern. Die folgenden Beispiele veranschaulichen typische Anwendungsfälle.

Anzeigen von Inhalten, bis eine Komponente interaktiv ist:

@if (!RendererInfo.IsInteractive)
{
    <p>Connecting to the assistant...</p>
}
else
{
    ...
}

Deaktivieren Sie eine Schaltfläche, bis eine Komponente interaktiv ist:

<button @onclick="Send" disabled="@(!RendererInfo.IsInteractive)">
    Send
</button>

Deaktivieren Sie ein Formular während der Voreinstellung, und aktivieren Sie das Formular, wenn die Komponente interaktiv ist:

<EditForm Model="Movie" ...>
    <fieldset disabled="@disabled">

        ...

        <button type="submit" >Save</button>
    </fieldset>
</EditForm>

@code {
    private bool disabled = true;

    [SupplyParameterFromForm]
    private Movie? Movie { get; set; }

    protected override async Task OnInitializedAsync()
    {
        Movie ??= await ...;

        if (RendererInfo.IsInteractive)
        {
            disabled = false;
        }
    }
}

Rendern Sie Markup, um das Ausführen einer regulären HTML-Aktion zu unterstützen, wenn die Komponente statisch gerendert wird:

@if (AssignedRenderMode is null)
{
    // The render mode is Static Server
    <form action="/movies">
        <input type="text" name="titleFilter" />
        <input type="submit" value="Search" />
    </form>
}
else
{
    // The render mode is Interactive Server, WebAssembly, or Auto
    <input @bind="titleFilter" />
    <button @onclick="FilterMovies">Search</button>
}

Im vorherigen Beispiel:

  • Wenn der Wert von AssignedRenderMode null ist, übernimmt die Komponente statische SSR. Die Blazor-Ereignisbehandlung ist in einem Browser mit statischem SSR nicht funktionsfähig, sodass die Komponente ein Formular (GET-Anforderung) mit einer titleFilter-Abfragezeichenfolge sendet, die auf den Wert des <input>-Benutzers festgelegt ist. Die Movie-Komponente (/movie) kann die Abfragezeichenfolge lesen und den Wert titleFilter verarbeiten, um die Komponente mit den gefilterten Ergebnissen zu rendern.
  • Andernfalls ist der Rendermodus ein InteractiveServer, InteractiveWebAssembly oder InteractiveAuto. Die Komponente kann einen Ereignishandlerdelegat (FilterMovies) und den Wert verwenden, der an das <input>-Element (titleFilter) gebunden ist, um Filme interaktiv über die Hintergrundverbindung SignalR zu filtern.

Blazor Dokumentationsbeispiele für Blazor Web Apps

Bei Verwendung einer Blazor Web Apperfordern die meisten Dokumentationsbeispielkomponenten von Blazor Interaktivität, um zu funktionieren und die Konzepte zu veranschaulichen, die in den Artikeln behandelt werden. Wenn Sie eine Beispielkomponente testen, die von einem Artikel bereitgestellt wird, stellen Sie sicher, dass die App globale Interaktivität verwendet oder die Komponente einen interaktiven Rendermodus verwendet.

Voarabrendering

Prerendering ist der Prozess des anfänglichen Renderns von Seiteninhalten auf dem Server, ohne Ereignishandler für gerenderte Steuerelemente zu aktivieren. Der Server gibt die HTML-Benutzeroberfläche der Seite so schnell wie möglich als Reaktion auf die anfängliche Anforderung aus, wodurch die Anwendung für Benutzer besser reagiert. Prerendering kann auch die Suchmaschinenoptimierung (SEO) verbessern, indem Inhalte für die erste HTTP-Antwort gerendert werden, die Suchmaschinen zur Berechnung des Seitenrangs verwenden.

Die Vorabrendering ist standardmäßig für interaktive Komponenten aktiviert.

Die interne Navigation für interaktives Routing umfasst nicht das Anfordern neuer Seiteninhalte vom Server. Daher wird für interne Seitenanforderungen, einschließlich der erweiterten Navigation, kein Vorabrendering durchgeführt. Weitere Informationen finden Sie unter Statisches und interaktives Routing, Interaktives Routing und Vorabrendering und Erweiterte Navigation und Formularverarbeitung.

Wenn das Vorabrendering mit den folgenden Techniken deaktiviert wird, ist die Deaktivierung nur für übergeordneten Rendermodi wirksam. Wenn eine übergeordnete Komponente einen Rendermodus angibt, werden die Vorabrendering-Einstellungen der untergeordneten Elemente ignoriert. Mögliche Änderungen an diesem Verhalten werden für das Release von .NET 10 im November 2025 untersucht.

Um das Prerendering für eine Komponenteninstanz zu deaktivieren, übergeben Sie das Flag prerender mit dem Wert false an den Rendermodus:

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

So deaktivieren Sie das Prerendering in einer Komponentendefinition:

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

Um das Prerendering für die gesamte App zu deaktivieren, geben Sie den Rendermodus für die interaktive Komponente der höchsten Ebene in der App-Hierarchie an, die keine Stammkomponente ist.

Bei Anwendungen, die auf der Blazor Web App-Projektvorlage basieren, wird ein Rendermodus, der der gesamten Anwendung zugewiesen wird, dort angegeben, wo die Routes-Komponente in der App-Komponente (Components/App.razor) verwendet wird. Im folgenden Beispiel wird der Rendermodus der App auf „Interaktiver Server“ festgelegt, wobei das Prerendering deaktiviert wird:

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

Deaktivieren Sie außerdem die Voreinstellung für die HeadOutlet-Komponente in der App-Komponente:

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

Die Interaktivität einer Stammkomponente wie der App-Komponente mit der @rendermode-Anweisung oben in der Definitionsdatei der Stammkomponente (.razor) wird nicht unterstützt. Daher kann die Voreinstellung nicht direkt von der App-Komponente deaktiviert werden.

Statisches serverseitiges Rendering (Statisches SSR)

Die Komponenten verwenden statisches serverseitiges Rendering (statisches SSR). Die Komponente wird im Antwortdatenstrom gerendert, und die Interaktivität ist nicht aktiviert.

Im folgenden Beispiel gibt es keine Bezeichnung für den Rendermodus der Komponente, und die Komponente erbt den Standardrendermodus von ihrem übergeordneten Elementen. Da keine Vorgängerkomponente einen Rendermodus angibt, wird die folgende Komponente auf dem Server statisch gerendert. Die Schaltfläche ist nicht interaktiv und ruft die UpdateMessage-Methode nicht auf, wenn sie ausgewählt ist. Der Wert von message ändert sich nicht, und die Komponente wird als Reaktion auf Benutzeroberflächenereignisse nicht erneut gerendert.

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!";
    }
}

Wenn Sie die vorherige Komponente lokal in einer Blazor Web App verwenden, speichern Sie die Komponente im Components/Pages-Ordner des Serverprojekts. Das Serverprojekt ist das Projekt in der Projektmappe mit einem Namen, der nicht auf .Client endet. Wenn die App ausgeführt wird, navigieren Sie in der Adressleiste des Browsers zu /render-mode-1.

Während statischer SSR Razor werden Komponentenseitenanforderungen von serverseitigen ASP.NET Core Middleware-Pipelineanforderungsverarbeitung für Routing und Autorisierung verarbeitet. Dedizierte Blazor Features für Routing und Autorisierung sind nicht funktionsfähig, da Razor Komponenten während der serverseitigen Anforderungsverarbeitung nicht gerendert werden. Blazor Routerfeatures in der Komponente Routes, die während der statischen SSR nicht verfügbar sind, umfassen die Anzeige:

Wenn die App Interaktivität auf Stammebene aufweist, wird die serverseitige ASP.NET Core-Anforderungsverarbeitung nach dem anfänglichen statischen SSR nicht einbezogen, was bedeutet, dass die vorherigen Blazor Features wie erwartet funktionieren.

Die erweiterte Navigation mit statischem SSR erfordert besondere Aufmerksamkeit beim Laden von JavaScript. Weitere Informationen finden Sie unter ASP.NET Core Blazor: JavaScript mit statischem serverseitigem Rendering (statisches SSR).

Interaktives serverseitiges Rendering (interaktives SSR)

Interaktives serverseitiges Rendering (interaktives SSR) rendert die Komponente mithilfe von Blazor Server interaktiv vom Server. Benutzerinteraktionen werden über eine Echtzeitverbindung mit dem Browser verarbeitet. Die Verbindung wird beim Rendern der Serverkomponente hergestellt.

Im folgenden Beispiel wird der Rendermodus auf interaktives SSR festgelegt, indem der Komponentendefinition @rendermode InteractiveServer hinzugefügt wird. Wenn die Schaltfläche ausgewählt wird, wird die Methode UpdateMessage aufgerufen. Der Wert von message ändert sich, und die Komponente wird erneut gerendert, damit die Meldung auf der Benutzeroberfläche aktualisiert wird.

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!";
    }
}

Wenn Sie die vorhergehende Komponente in einer Blazor Web AppKomponente verwenden, platzieren Sie die Komponente im Ordner des Serverprojekts Components/Pages . Das Serverprojekt ist das Projekt in der Projektmappe mit einem Namen, der nicht auf .Client endet. Wenn die App ausgeführt wird, navigieren Sie in der Adressleiste des Browsers zu /render-mode-2.

Clientseitiges Rendering (CSR)

Clientseitiges Rendering (CSR) rendert die Komponente mithilfe von Blazor WebAssembly interaktiv auf dem Client. Die .NET-Runtime und das App Bundle werden heruntergeladen und zwischengespeichert, wenn die WebAssembly-Komponente anfänglich gerendert wird. Komponenten, die CSR verwenden, müssen aus einem separaten Clientprojekt erstellt werden, das den Blazor WebAssembly-Host einrichtet.

Im folgenden Beispiel wird der Rendermodus mit @rendermode InteractiveWebAssembly auf „CSR“ festgelegt. Wenn die Schaltfläche ausgewählt wird, wird die Methode UpdateMessage aufgerufen. Der Wert von message ändert sich, und die Komponente wird erneut gerendert, damit die Meldung auf der Benutzeroberfläche aktualisiert wird.

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!";
    }
}

Wenn Sie die vorherige Komponente lokal in einer Blazor Web App verwenden, speichern Sie die Komponente im Pages-Ordner des Clientprojekts. Das Clientprojekt ist das Projekt in der Projektmappe mit einem Namen, der auf .Client endet. Wenn die App ausgeführt wird, navigieren Sie in der Adressleiste des Browsers zu /render-mode-3.

Automatisches Rendering

Der Rendermodus „Automatisch“ bestimmt, wie die Komponente zur Laufzeit gerendert wird. Die Komponente wird zunächst mithilfe des Blazor Server-Hostingmodells mit interaktivem serverseitigem Rendering (interaktives SSR) gerendert. Die .NET-Runtime und das App Bundle werden im Hintergrund auf den Client heruntergeladen und zwischengespeichert, sodass sie zukünftig verwendet werden können.

Der Automatische Rendermodus ändert nie dynamisch den Rendermodus einer Komponente, die sich bereits auf der Seite befindet. Der Automatische Rendermodus trifft eine anfängliche Entscheidung darüber, welche Art von Interaktivität für eine Komponente verwendet werden soll, und die Komponente behält diese Art von Interaktivität so lange bei, wie sie sich auf der Seite befindet. Ein Faktor in dieser anfänglichen Entscheidung besteht darin zu prüfen, ob Komponenten bereits auf der Seite mit WebAssembly/Server-Interaktivität vorhanden sind. Der automatische Modus bevorzugt die Auswahl eines Rendermodus, der dem Rendermodus vorhandener interaktiver Komponenten entspricht. Der Grund dafür, dass der Automodus einen vorhandenen Interaktivitätsmodus bevorzugt, besteht darin, keine neue interaktive Laufzeit einzuführen, die den Status nicht mit der vorhandenen Laufzeit teilt.

Komponenten, die den Rendermodus „Automatisch“ verwenden, müssen aus einem separaten Clientprojekt erstellt werden, das den Blazor WebAssembly-Host einrichtet.

Im folgenden Beispiel ist die Komponente während des gesamten Prozesses interaktiv. Wenn die Schaltfläche ausgewählt wird, wird die Methode UpdateMessage aufgerufen. Der Wert von message ändert sich, und die Komponente wird erneut gerendert, damit die Meldung auf der Benutzeroberfläche aktualisiert wird. Zunächst wird die Komponente interaktiv vom Server gerendert, aber bei nachfolgenden Besuchen wird sie vom Client gerendert, nachdem die .NET-Runtime und das App Bundle heruntergeladen und zwischengespeichert wurden.

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!";
    }
}

Wenn Sie die vorherige Komponente lokal in einer Blazor Web App verwenden, speichern Sie die Komponente im Pages-Ordner des Clientprojekts. Das Clientprojekt ist das Projekt in der Projektmappe mit einem Namen, der auf .Client endet. Wenn die App ausgeführt wird, navigieren Sie in der Adressleiste des Browsers zu /render-mode-4.

Weitergabe von Rendermodi

Rendermodi werden in der Komponentenhierarchie nach unten weitergegeben.

Regeln für das Anwenden von Rendermodi:

  • Der Standardrendermodus ist „Statisch“.
  • Die Rendermodi „Server (interaktiv)“ (InteractiveServer), „WebAssembly (interaktiv)“ (InteractiveWebAssembly) und „Automatisch (interaktiv)“ (InteractiveAuto) können über eine statische Komponente verwendet werden, einschließlich der Verwendung verschiedener Rendermodi für gleichgeordnete Komponenten.
  • Sie können in einer untergeordneten Komponente nicht zu einem anderen interaktiven Rendermodus wechseln. Beispielsweise kann eine Serverkomponente keiner WebAssembly-Komponente untergeordnet sein.
  • Parameter, die an eine interaktive untergeordnete Komponente einer statischen übergeordneten Komponente übergeben werden, müssen mit JSON serialisierbar sein. Das bedeutet, dass Sie Renderfragmente oder untergeordnete Inhalte nicht von einer statischen übergeordneten Komponente an eine interaktive untergeordnete Komponente übergeben können.

In den folgenden Beispielen wird eine nicht routing- und seitenfähige SharedMessage-Komponente verwendet. Die rendermodusagnostische SharedMessage-Komponente wendet keinen Rendermodus mit einer @attribute-Anweisung an. Wenn Sie diese Szenarios mit einer Blazor Web App testen, speichern Sie die folgende Komponente im Ordner Components der App.

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!";
    }
}

Vererbung des Rendermodus

Wenn die SharedMessage-Komponente sich in einer statisch gerenderten übergeordneten Komponente befindet, wird die SharedMessage-Komponente ebenfalls statisch gerendert und ist nicht interaktiv. Die Schaltfläche ruft UpdateMessage nicht auf, und die Meldung wird nicht aktualisiert.

RenderMode5.razor:

@page "/render-mode-5"

<SharedMessage />

Wenn die SharedMessage-Komponente sich in einer Komponente befindet, die den Rendermodus definiert, erbt sie den angewendeten Rendermodus.

Im folgenden Beispiel ist die SharedMessage-Komponente interaktiv über eine SignalR-Verbindung mit dem Client. Die Schaltfläche ruft UpdateMessage auf, und die Meldung wird aktualisiert.

RenderMode6.razor:

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

<SharedMessage />

Untergeordnete Komponenten mit unterschiedlichen Rendermodi

Im folgenden Beispiel werden beide SharedMessage-Komponenten vorgerendert und erscheinen, wenn die Seite im Browser angezeigt wird.

  • Die erste SharedMessage Komponente mit interaktivem serverseitigem Rendering (interaktiver SSR) ist interaktiv, nachdem Blazorder SignalR Schaltkreis eingerichtet wurde.
  • Die zweite SharedMessage-Komponente mit clientseitigem Rendering ist interaktiv, nachdem das App Bundle Blazor heruntergeladen wurde und die .NET-Runtime auf dem Client aktiv ist.

RenderMode7.razor:

@page "/render-mode-7"

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

Untergeordnete Komponente mit einem serialisierbaren Parameter

Im folgenden Beispiel wird eine interaktive untergeordnete Komponente veranschaulicht, die einen Parameter verwendet. Parameter müssen serialisierbar sein.

RenderMode8.razor:

@page "/render-mode-8"

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

Nicht-serialisierbare Komponentenparameter, wie z. B. untergeordneter Inhalt oder ein Renderfragment, werden nicht unterstützt. Im folgenden Beispiel führt das Übergeben untergeordneter Inhalte an die SharedMessage-Komponente zu einem Laufzeitfehler.

RenderMode9.razor:

@page "/render-mode-9"

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

Fehler:

System.InvalidOperationException: Der Parameter „ChildContent“ kann nicht an die Komponente „SharedMessage“ mit dem Rendermodus „InteractiveServerRenderMode“ übergeben werden. Das ist darauf zurückzuführen, dass der Parameter den Delegattyp „Microsoft.AspNetCore.Components.RenderFragment“ aufweist, bei dem es sich um arbiträren, nicht serialisierbaren Code handelt.

Um diese Einschränkung zu umgehen, schließen Sie die untergeordnete Komponente in eine andere Komponente ein, die den Parameter nicht aufweist. Dieser Ansatz wird auch in der Blazor Web App/Projektvorlage angewendet, indem die Routes-Komponente (Components/Routes.razor) zum Umschließen der Router-Komponente verwendet wird.

WrapperComponent.razor:

<SharedMessage>
    Child content
</SharedMessage>

RenderMode10.razor:

@page "/render-mode-10"

<WrapperComponent @rendermode="InteractiveServer" />

Im vorherigen Beispiel:

  • Der untergeordnete Inhalt wird an die SharedMessage-Komponente übergeben, ohne einen Laufzeitfehler zu generieren.
  • Die SharedMessage-Komponente wird interaktiv auf dem Server gerendert.

Untergeordnete Komponente mit einem anderen Rendermodus als die übergeordnete Komponente

Versuchen Sie nicht, einen anderen interaktiven Rendermodus als den Rendermodus der übergeordneten Komponente auf eine untergeordnete Komponente anzuwenden.

Die folgende Komponente führt beim Rendern zu einem Laufzeitfehler:

RenderMode11.razor:

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

<SharedMessage @rendermode="InteractiveWebAssembly" />

Fehler:

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.

Seiten mit statischem SSR in einer global interaktiven App

Es gibt Fälle, in denen die Spezifikation der App für Komponenten erfordert, dass statisches serverseitiges Rendering (statisches SSR) verwendet wird und dass sie nur auf dem Server ausgeführt werden, während der rest der App einen interaktiven Rendermodus verwendet.

Dieser Ansatz ist nur hilfreich, wenn bestimmte Seiten der App nicht mit interaktivem Server- oder WebAssembly-Rendering funktionieren. Dieser Ansatz eignet sich z. B. für Seiten, die vom Lesen/Schreiben von HTTP-Cookies abhängig sind und nur in einem Anforderungs-/Antwortzyklus funktionieren können, aber nicht mit interaktivem Rendering. Für Seiten, die mit interaktivem Rendering funktionieren, sollten Sie kein statisches SSR-Rendering erzwingen, da es weniger reaktionsfähig und weniger effizient für den Endbenutzer ist.

Markieren Sie eine beliebige Razor Komponentenseite mit dem Attribut, das [ExcludeFromInteractiveRouting] der @attributeRazor Direktive zugewiesen ist:

@attribute [ExcludeFromInteractiveRouting]

Die Anwendung des Attributs bewirkt, dass die Navigation zu der Seite das interaktive Routing beendet. Die eingehende Navigation wird gezwungen, die Seite vollständig neu zu laden, anstatt die Seite über das interaktive Routing aufzulösen. Das vollständige Neuladen zwingt die Stammkomponente der obersten Ebene, in der Regel die App-Komponente (App.razor), vom Server erneut zu rendern, sodass die App zu einem anderen Rendermodus auf oberster Ebene wechseln kann.

Mit RazorComponentsEndpointHttpContextExtensions.AcceptsInteractiveRouting der Erweiterungsmethode kann die Komponente erkennen, ob das [ExcludeFromInteractiveRouting] Attribut auf die aktuelle Seite angewendet wird.

Verwenden Sie in der App-Komponente das Muster im folgenden Beispiel:

  • Seiten, die nicht mit dem Attribut versehen sind, das [ExcludeFromInteractiveRouting] standardmäßig für den InteractiveServer Rendermodus mit globaler Interaktivität verwendet wird. Sie können InteractiveServer durch InteractiveWebAssembly oder InteractiveAuto ersetzen, um einen anderen standardmäßigen globalen Rendermodus anzugeben.
  • Mit dem [ExcludeFromInteractiveRouting] Attribut kommentierte Seiten übernehmen statische SSR (PageRenderMode wird zugewiesen null).
<!DOCTYPE html>
<html>
<head>
    ...
    <HeadOutlet @rendermode="@PageRenderMode" />
</head>
<body>
    <Routes @rendermode="@PageRenderMode" />
    ...
</body>
</html>

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

    private IComponentRenderMode? PageRenderMode
        => HttpContext.AcceptsInteractiveRouting() ? InteractiveServer : null;
}

Eine Alternative zur Verwendung der Erweiterungsmethode RazorComponentsEndpointHttpContextExtensions.AcceptsInteractiveRouting besteht darin, Endpunktmetadaten manuell mithilfe von HttpContext.GetEndpoint()?.Metadata zu lesen.

Es gibt zwei Ansätze, die zur genauen Kontrolle der Rendermodi eingesetzt werden können. Sie werden in den folgenden Unterabschnitten beschrieben:

  • Bereich (Ordner) statischer SSR-Komponenten: Sie verfügen über einen Bereich (Ordner) der App mit Komponenten, die statisches SSR übernehmen müssen und die das gleiche Routenpfadpräfix verwenden. Die App steuert den Rendermodus global, indem der Rendermodus für die Routes-Komponente in der App-Komponente basierend auf dem Pfad zum Ordner festgelegt wird.

  • Statische SSR-Komponenten sind in der gesamten App verteilt: Sie verfügen über Komponenten, die an verschiedenen Stellen in der App verteilt sind, die statisches SSR übernehmen müssen und nur auf dem Server ausgeführt werden. Die statischen SSR-Komponenten befinden sich nicht in einem einzigen Ordner und weisen kein gemeinsames Routenpfadpräfix auf. Die App steuert den Rendermodus pro Komponente, indem der Rendermodus mit der Anweisung @rendermode in Komponenteninstanzen festgelegt wird. Reflexion wird in der App-Komponente verwendet, um den Rendermodus für die Routes-Komponente festzulegen.

In beiden Fällen muss die Komponente, die statisches SSR übernehmen muss, auch das erneute Laden einer vollständigen Seite erzwingen.

In den folgenden Beispielen wird mit dem kaskadierenden Parameter HttpContext ermittelt, ob die Seite statisch gerendert wird. Wenn HttpContext den Wert null aufweist, zeigt dies, dass die Komponente interaktiv gerendert wird, was als Signal im App-Code nützlich ist, um ein erneutes Laden der vollständigen Seite auszulösen.

Bereich (Ordner) statischer SSR-Komponenten

Der in diesem Unterabschnitt beschriebene Ansatz wird von der Blazor Web App-Projektvorlage mit individueller Authentifizierung und globaler Interaktivität verwendet.

Ein Bereich (Ordner) der App enthält die Komponenten, die statisches SSR übernehmen müssen und nur auf dem Server ausgeführt werden. Die Komponenten im Ordner verwenden das gleiche Routenpfadpräfix. Beispielsweise befinden sich die IdentityRazor-Komponenten der Blazor Web App-Projektvorlage im Ordner Components/Account/Pages und verwenden das Stammpfadpräfix /Account.

Der Ordner enthält auch eine _Imports.razor-Datei, die ein benutzerdefiniertes Kontolayout auf die Komponenten im Ordner anwendet:

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

Der Ordner Shared enthält die Layoutkomponente AccountLayout. Die Komponente verwendet HttpContext, um festzustellen, ob die Komponente statisches SSR verwendet. Identity-Komponenten müssen auf dem Server mit statischem SSR gerendert werden, da sie Identity-Cookies festlegen. Wenn der Wert von HttpContext null lautet, wird die Komponente interaktiv gerendert, und ein Neuladen der vollständigen Seite wird durch Aufrufen von NavigationManager.Refresh mit forceLoad als true ausgeführt. Dadurch wird ein vollständiges erneutes Rendern der Seite mithilfe von statischem SSR erzwungen.

Components/Account/Shared/AccountLayout.razor:

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

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

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

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

Hinweis

In der Blazor Web App-Projektvorlage gibt es eine zweite Layoutdatei (ManageLayout.razor im Ordner Components/Account/Shared) für Identity-Komponenten im Ordner Components/Account/Pages/Manage. Der Ordner Manage verfügt über eine eigene _Imports.razor-Datei, um ManageLayout auf Komponenten im Ordner anzuwenden. In Ihren eigenen Apps ist die Verwendung geschachtelter _Imports.razor-Dateien ein nützlicher Ansatz zum Anwenden von benutzerdefinierten Layouts auf Seitengruppen.

In der App-Komponente wendet jede Anforderung für eine Komponente im Ordner Account einen null-Rendermodus an, der statisches SSR erzwingt. Andere Komponentenanforderungen erhalten eine globale Anwendung des interaktiven SSR-Rendermodus (InteractiveServer).

Wichtig

Das Anwenden eines null-Rendermodus erzwingt nicht immer statisches SSR. Das Verhalten ist nur so, wenn Sie den in diesem Abschnitt gezeigten Ansatz verwenden.

Ein null-Rendermodus ist effektiv identisch mit der Angabe eines Rendermodus, was dazu führt, dass die Komponente den Rendermodus des übergeordneten Elements erbt. In diesem Fall wird die App-Komponente mit statischem SSR gerendert, sodass ein null-Rendermodus dazu führt, dass die Routes-Komponente statisches SSR von der App-Komponente erbt. Wenn ein NULL-Rendermodus für eine untergeordnete Komponente angegeben wird, deren übergeordnetes Element einen interaktiven Rendermodus verwendet, erbt das untergeordnete Element den gleichen interaktiven Rendermodus.

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};
}

Ändern Sie im obigen Code den Platzhalter {INTERACTIVE RENDER MODE} in den entsprechenden Wert, je nachdem, ob die rest-Anwendung das globale InteractiveServer-, InteractiveWebAssembly- oder InteractiveAuto-Rendering übernehmen soll.

Die Komponenten, die statische SSR im Account-Ordner übernehmen müssen, sind nicht erforderlich, um das Layout festzulegen, das über die _Imports.razor-Datei angewendet wird. Die Komponenten legen keinen Rendermodus fest, da sie mit statischem SSR gerendert werden sollen. Mehr ist nicht erforderlich, damit die Komponenten im Ordner Account statisches SSR erzwingen.

Statische SSR-Komponenten sind in der gesamten App verteilt

Im vorherigen Unterabschnitt steuert die App den Rendermodus der Komponenten, indem der Rendermodus global in der App-Komponente festgelegt wird. Alternativ kann die App-Komponente auch Rendermodi pro Komponente übernehmen, um den Rendermodus festzulegen. Dadurch können Komponenten, die in der App verteilt sind, die Übernahme von statischem SSR erzwingen. In diesem Unterabschnitt wird der Ansatz beschrieben.

Die App verfügt über ein benutzerdefiniertes Layout, das auf Komponenten in der App angewendet werden kann. In der Regel wird eine freigegebene Komponente für die App im Ordner Components/Layout platziert. Die Komponente verwendet HttpContext, um festzustellen, ob die Komponente statisches SSR verwendet. Wenn der Wert von HttpContext null lautet, wird die Komponente interaktiv gerendert, und ein Neuladen der vollständigen Seite wird durch Aufrufen von NavigationManager.Refresh mit forceLoad als true ausgeführt. Dadurch wird eine Anforderung an den Server für die Komponente ausgelöst.

Components/Layout/StaticSsrLayout.razor:

@inherits LayoutComponentBase
@layout MainLayout
@inject NavigationManager Navigation

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

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

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

In der App-Komponente wird eine Reflexion verwendet, um den Rendermodus festzulegen. Jeder Rendermodus, der der einzelnen Komponentendefinitionsdatei zugewiesen ist, wird auf die Routes-Komponente angewendet.

Components/App.razor:

<Routes @rendermode="RenderModeForPage" />

...

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

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

Jede Komponente, die statisches SSR übernehmen muss, legt das benutzerdefinierte Layout fest und gibt keinen Rendermodus an. Die fehlende Angabe eines Rendermodus führt zu einem null-Wert von RenderModeAttribute.Mode in der App-Komponente, was dazu führt, dass kein Rendermodus der Routes-Komponenteninstanz zugewiesen und statisches SSR erzwungen wird.

Wichtig

Das Anwenden eines null-Rendermodus erzwingt nicht immer statisches SSR. Das Verhalten ist nur so, wenn Sie den in diesem Abschnitt gezeigten Ansatz verwenden.

Ein null-Rendermodus ist effektiv identisch mit der Angabe eines Rendermodus, was dazu führt, dass die Komponente den Rendermodus des übergeordneten Elements erbt. In diesem Fall wird die App-Komponente mit statischem SSR gerendert, sodass ein null-Rendermodus dazu führt, dass die Routes-Komponente statisches SSR von der App-Komponente erbt. Wenn ein NULL-Rendermodus für eine untergeordnete Komponente angegeben wird, deren übergeordnetes Element einen interaktiven Rendermodus verwendet, erbt das untergeordnete Element den gleichen interaktiven Rendermodus.

Es muss nichts weiter getan werden, damit die Komponenten statische SSR erzwingen, als das benutzerdefinierte Layout anzuwenden, ohne einen interaktiven Rendermodusfestzulegen:

@layout BlazorSample.Components.Layout.StaticSsrLayout

Interaktive Komponenten um die App vermeiden das Anwenden des benutzerdefinierten statischen SSR-Layouts und legen nur einen geeigneten interaktiven Rendermodusfest, der in der Komponente App auf die Komponente Routes angewendet wird:

@rendermode {INTERACTIVE RENDER MODE}

Ändern Sie im vorherigen Code den Platzhalter {INTERACTIVE RENDER MODE} in den entsprechenden Wert, je nachdem, ob die Komponente InteractiveServer-, InteractiveWebAssembly- oder InteractiveAuto-Rendering übernehmen soll.

Clientseitige Dienste können während des Prerendering nicht aufgelöst werden.

Sofern das Prerendering nicht für eine Komponente oder die App deaktiviert ist, wird eine Komponente im .Client-Projekt auf dem Server vorab gerendert. Weil der Server keinen Zugriff auf registrierte clientseitige Blazor-Dienste hat, ist es nicht möglich, diese Dienste in eine Komponente einzufügen, ohne einen Fehler zu erhalten, der besagt, dass der Dienst während des Prerendering nicht gefunden wird.

Betrachten Sie z. B. die folgende Home-Komponente im .Client-Projekt in einer Blazor Web App mit globaler interaktiver WebAssembly oder interaktivem automatischen Rendering. Die Komponente versucht, IWebAssemblyHostEnvironment einzufügen, um den Namen der Umgebung abzurufen.

@page "/"
@inject IWebAssemblyHostEnvironment Environment

<PageTitle>Home</PageTitle>

<h1>Home</h1>

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

Es tritt kein Fehler zur Kompilierungszeit auf, während des Prerendering tritt jedoch ein Laufzeitfehler auf:

Für die Eigenschaft „Environment“ des Typs „BlazorSample.Client.Pages.Home“ kann kein Wert angegeben werden. Es gibt keinen registrierten Dienst vom Typ ‚Microsoft.AspNetCore.Components.WebAssembly.Hosting.IWebAssemblyHostEnvironment‘.

Dieser Fehler tritt auf, weil die Komponente während des Prerendering kompiliert und auf dem Server ausgeführt werden muss, aber IWebAssemblyHostEnvironment kein registrierter Dienst auf dem Server ist.

Wenn für die App der Wert während des Prerendering nicht erforderlich ist, kann dieses Problem gelöst werden, indem IServiceProvider eingefügt wird, um den Dienst anstelle des Diensttyps zu beziehen:

@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;
        }
    }
}

Der vorstehende Ansatz ist jedoch nicht hilfreich, wenn ihre Logik während des Prerendering einen Wert erfordert.

Sie können das Problem auch vermeiden, wenn Sie das Prerendering für die Komponente deaktivieren. Doch das ist eine extreme Maßnahme, die in vielen Fällen möglicherweise nicht den Spezifikationen Ihrer Komponente entspricht.

Es gibt drei Ansätze, wie Sie dieses Szenario angehen können. Im Folgenden sind sie in der Reihenfolge von „am empfehlenswertesten“ bis „am wenigsten empfehlenswert“ aufgeführt:

  • Empfohlen für freigegebene Frameworkdienste: Für freigegebene Frameworkdienste, die lediglich nicht serverseitig im Hauptprojekt registriert sind, registrieren Sie die Dienste im Hauptprojekt, wodurch sie während des Prerenderingvorgangs verfügbar werden. Ein Beispiel für dieses Szenario finden Sie in der Anleitung für HttpClient-Dienste unter Aufrufen einer Web-API über eine ASP.NET Core-Blazor-App.

  • Empfohlen für Dienste außerhalb des freigegebenen Frameworks: Erstellen Sie eine benutzerdefinierte Dienstimplementierung für den Dienst auf dem Server. Verwenden Sie den Dienst normalerweise in interaktiven Komponenten des .Client-Projekts. Eine Demonstration dieses Ansatzes finden Sie unter ASP.NET Core Blazor Umgebungen.

  • Erstellen Sie eine Dienststraktion, und erstellen Sie Implementierungen für den Dienst in den .Client- und Serverprojekten. Registrieren Sie die Dienste in jedem Projekt. Fügen Sie den benutzerdefinierten Dienst in die Komponente ein.

  • Möglicherweise können Sie einen .Client-Projektpaketverweis zu einem serverseitigen Paket hinzufügen und beim Prerendering auf dem Server auf die serverseitige API zurückgreifen.

Ermitteln von Komponenten aus zusätzlichen Assemblys

Zusätzliche Assemblys müssen dem Blazor-Framework offengelegt werden, um routingfähige Razor-Komponenten in Projekten zu ermitteln, auf die verwiesen wird. Weitere Informationen finden Sie unter ASP.NET Core: Routing und Navigation in Blazor.

Schließen von Verbindungen, wenn keine verbleibenden interaktiven Serverkomponenten vorhanden sind

Interaktive Serverkomponenten verarbeiten Ereignisse auf der Webbenutzeroberfläche mithilfe einer Echtzeitverbindung mit dem Browser. Diese wird als Verbindung bezeichnet. Eine Verbindung und der zugehörige Zustand werden erstellt, wenn eine interaktive Stammserverkomponente gerendert wird. Die Verbindung wird geschlossen, wenn keine interaktiven Serverkomponenten auf der Seite vorhanden sind, wodurch Serverressourcen freigegeben werden.

Benutzerdefinierte Kurzrendermodi

Die @rendermode-Anweisung verwendet einen einzelnen Parameter, der eine statische Instanz des Typs IComponentRenderMode ist. Das anweisende @rendermode-Attribut kann eine beliebige statische oder nichtstatische Rendermodusinstanz verwenden. Das Blazor-Framework bietet zur einfachen Verwendung die statische RenderMode-Klasse mit einigen vordefinierten Rendermodi. Sie können jedoch eigene Rendermodi erstellen.

Normalerweise verwendet eine Komponente die folgende @rendermode-Anweisung, um das Prerendering zu deaktivieren:

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

Beachten Sie jedoch das folgende Beispiel, das eine Kurzform des interaktiven serverseitigen Rendermodus ohne Vorabrendering über die _Imports-Datei der App (Components/_Imports.razor) erstellt:

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

Verwenden Sie die Kurzform des Rendermodus für die Komponenten im Components-Ordner:

@rendermode InteractiveServerWithoutPrerendering

Stattdessen kann eine einzelne Komponenteninstanz einen benutzerdefinierten Rendermodus über ein privates Feld definieren:

@rendermode interactiveServerWithoutPrerendering

...

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

Derzeit ist der Ansatz mit dem Kurzrendermodus wahrscheinlich nur hilfreich, um das Angeben des prerender-Flags weniger ausführlich zu gestalten. Der Kurzansatz könnte sich in Zukunft als hilfreicher erweisen, wenn zusätzliche Flags für das interaktive Rendering zur Verfügung stehen und Sie Kurzrendermodi mit unterschiedlichen Kombinationen von Flags erstellen möchten.

Diensteinfügung über eine Importdatei auf oberster Ebene (_Imports.razor)

Dieser Abschnitt gilt nur für Blazor Web Apps.

Eine Importdatei auf oberster Ebene im Ordner Components (Components/_Imports.razor) fügt ihre Verweise in alle Komponenten in der Ordnerhierarchie ein, die die App-Komponente (App.razor) enthält. Die App-Komponente wird immer statisch gerendert, auch wenn das Prerendering einer Seitenkomponente deaktiviert ist. Daher führt das Einfügen von Diensten über die Importdatei der obersten Ebene dazu, zwei Instanzen des Diensts in Seitenkomponenten aufzulösen.

Um dieses Szenario zu beheben, fügen Sie den Dienst in eine neue Importdatei ein, die im Ordner Pages (Components/Pages/_Imports.razor) platziert wird. Von diesem Speicherort aus wird der Dienst nur einmal in Seitenkomponenten aufgelöst.

Zusätzliche Ressourcen