modalità di rendering ASP.NET Core Blazor

Questo articolo illustra il controllo del rendering dei Razor componenti in Blazor App Web, in fase di compilazione o in fase di esecuzione.

Queste indicazioni non si applicano alle app autonome Blazor WebAssembly . Blazor WebAssembly le app eseguono il rendering solo sul client tramite un runtime basato su WebAssembly sul lato client e non hanno alcun concetto di modalità di rendering. Se una modalità di rendering viene applicata a un componente in un'app Blazor WebAssembly , la designazione della modalità di rendering non influisce sul rendering del componente.

Modalità di rendering

Ogni componente in un'app Blazor Web adotta una modalità di rendering per determinare il modello di hosting usato, dove viene eseguito il rendering e se è interattivo o meno.

La tabella seguente illustra le modalità di rendering disponibili per i componenti di rendering Razor in un'app Blazor Web. Per applicare una modalità di rendering a un componente, usare la direttiva nell'istanza @rendermode del componente o nella definizione del componente. Più avanti in questo articolo vengono illustrati esempi per ogni scenario in modalità di rendering.

Nome Descrizione Posizione di rendering Interattivo
Server statico Rendering statico lato server (SSR statico) Server No
Server interattivo Rendering lato server interattivo (SSR interattivo) tramite Blazor Server. Server
WebAssembly interattivo Rendering lato client (CSR) con Blazor WebAssembly†. Client
Auto interattivo SSR interattivo che usa Blazor Server inizialmente e quindi csr nelle visite successive dopo il download del Blazor bundle. Server, quindi client

si presuppone che il rendering lato client (CSR) † sia interattivo. "Rendering lato client interattivo " e "CSR interattivo " non vengono usati dal settore o nella Blazor documentazione.

Il prerendering è abilitato per impostazione predefinita per i componenti interattivi. Le indicazioni sul controllo della prerendering sono disponibili più avanti in questo articolo. Per la terminologia generale del settore sui concetti relativi al rendering client e server, vedere ASP.NET Nozioni fondamentali di baseBlazor.

Gli esempi seguenti illustrano l'impostazione della modalità di rendering del componente con alcune funzionalità di base Razor del componente.

Per testare i comportamenti della modalità di rendering in locale, è possibile inserire i componenti seguenti in un'app creata dal Blazor modello di progetto app Web. Quando si crea l'app, selezionare le opzioni dai menu a discesa (Visual Studio) o applicare le opzioni dell'interfaccia della riga di comando (interfaccia della riga di comando .NET) per abilitare sia l'interattività lato server che quella lato client. Per indicazioni su come creare un'app Blazor Web, vedere Strumenti per ASP.NET Core Blazor.

Abilitare il supporto per le modalità di rendering interattive

È necessario configurare un'app Blazor Web per supportare le modalità di rendering interattive. Le estensioni seguenti vengono applicate automaticamente alle app create dal modello di progetto app Web durante la Blazor creazione dell'app. I singoli componenti sono comunque necessari per dichiarare la modalità di rendering in base alla sezione Modalità di rendering dopo che i servizi e gli endpoint dei componenti sono configurati nel file dell'app Program .

I servizi per Razor i componenti vengono aggiunti chiamando AddRazorComponents.

Estensioni del generatore di componenti:

MapRazorComponents individua i componenti disponibili e specifica il componente radice per l'app (il primo componente caricato), che per impostazione predefinita è il App componente (App.razor).

Estensioni del generatore di convenzioni degli endpoint:

Nota

Per l'orientamento sulla posizione dell'API negli esempi seguenti, esaminare il Program file di un'app generata dal Blazor modello di progetto app Web. Per indicazioni su come creare un'app Blazor Web, vedere Strumenti per ASP.NET Core Blazor.

Esempio 1: l'API file seguente Program aggiunge servizi e configurazione per l'abilitazione di SSR interattivo:

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

Esempio 2: l'API file seguente Program aggiunge servizi e configurazione per abilitare la modalità di rendering Interactive WebAssembly:

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

Esempio 3: l'API file seguente Program aggiunge servizi e configurazione per abilitare le modalità di rendering interattivo Server, Interactive WebAssembly e Interactive Auto:

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

Blazor usa il Blazor WebAssembly modello di hosting per scaricare ed eseguire componenti che usano la modalità di rendering Interactive WebAssembly. Per configurare Blazor WebAssembly l'hosting per questi componenti, è necessario un progetto client separato. Il progetto client contiene il codice di avvio per l'host e configura il runtime .NET per l'esecuzione Blazor WebAssembly in un browser. Il Blazor modello App Web aggiunge automaticamente questo progetto client quando si seleziona l'opzione per abilitare l'interattività WebAssembly. Tutti i componenti che usano la modalità di rendering Interactive WebAssembly devono essere compilati dal progetto client, in modo che vengano inclusi nel bundle dell'app scaricato.

Applicare una modalità di rendering a un'istanza del componente

Per applicare una modalità di rendering a un'istanza del componente, usare l'attributo @rendermodeRazor di direttiva in cui viene usato il componente.

Nell'esempio seguente il rendering interattivo lato server (SSR interattivo) viene applicato all'istanza del Dialog componente:

<Dialog @rendermode="InteractiveServer" />

Nota

Blazor I modelli includono una direttiva statica using per RenderMode nel file dell'app _Imports (Components/_Imports.razor) per una sintassi più @rendermode breve:

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

Senza la direttiva precedente, i componenti devono specificare la classe statica RenderMode nella @rendermode sintassi:

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

È anche possibile fare riferimento a istanze personalizzate della modalità di rendering create direttamente con la configurazione personalizzata. Per altre informazioni, vedere la sezione Modalità di rendering abbreviate personalizzate più avanti in questo articolo.

Applicare una modalità di rendering a una definizione di componente

Per specificare la modalità di rendering per un componente come parte della relativa definizione, usare la @rendermodeRazor direttiva e l'attributo della modalità di rendering corrispondente.

@page "..."
@rendermode InteractiveServer

L'applicazione di una modalità di rendering a una definizione di componente viene comunemente usata quando si applica una modalità di rendering a una pagina specifica. Per impostazione predefinita, le pagine instradabili usano la stessa modalità di rendering del Router componente che ha eseguito il rendering della pagina.

Tecnicamente, @rendermode è sia unaRazor direttiva che un attributo di Razordirettiva. La semantica è simile, ma esistono differenze. La @rendermode direttiva si trova nella definizione del componente, pertanto l'istanza della modalità di rendering a cui si fa riferimento deve essere statica. L'attributo @rendermode direttiva può accettare qualsiasi istanza della modalità di rendering.

Nota

Gli autori di componenti devono evitare di accoppiare l'implementazione di un componente a una modalità di rendering specifica. Gli autori di componenti devono in genere progettare componenti per supportare qualsiasi modalità di rendering o modello di hosting. L'implementazione di un componente deve evitare presupposti sulla posizione in cui è in esecuzione (server o client) e deve degradarsi normalmente durante il rendering statico. Specificare la modalità di rendering nella definizione del componente può essere necessaria se il componente non viene creata direttamente un'istanza (ad esempio con un componente pagina instradabile) o per specificare una modalità di rendering per tutte le istanze del componente.

Applicare una modalità di rendering all'intera app

Per impostare la modalità di rendering per l'intera app, indicare la modalità di rendering al componente interattivo di livello più alto nella gerarchia dei componenti dell'app che non è un componente radice.

Nota

Rendere interattivo un componente radice, ad esempio il App componente, non è supportato. Pertanto, la modalità di rendering per l'intera app non può essere impostata direttamente dal App componente.

Per le app basate sul modello di Blazor progetto app Web, viene in genere specificata una modalità di rendering assegnata all'intera app in cui il Routes componente viene usato nel App componente (Components/App.razor):

<Routes @rendermode="InteractiveServer" />

Il Router componente propaga la modalità di rendering alle pagine in cui viene instradato.

In genere è anche necessario impostare la stessa modalità di rendering interattiva nel HeadOutlet componente, disponibile anche nel App componente di un'app Blazor Web generata dal modello di progetto:

<HeadOutlet @rendermode="InteractiveServer" />

Per le app che adottano una modalità di rendering lato client interattiva (WebAssembly o Auto) e abilitare la modalità di rendering per l'intera app tramite il Routes componente:

  • Posizionare o spostare il layout e i file di spostamento della cartella dell'app Components/Layout server nella .Client cartella del Layout progetto. Creare una Layout cartella nel .Client progetto, se non esiste.
  • Posizionare o spostare i componenti della cartella dell'app Components/Pages server nella .Client cartella del Pages progetto. Creare una Pages cartella nel .Client progetto, se non esiste.
  • Posizionare o spostare il Routes componente della cartella dell'app Components server nella .Client cartella radice del progetto.

Per abilitare l'interattività globale durante la creazione di un'app Blazor Web:

  • Visual Studio: impostare l'elenco a discesa Percorso interattività su Globale.
  • Interfaccia della riga di comando di .NET: usare l'opzione -ai|--all-interactive .

Per altre informazioni, vedere Strumenti per ASP.NET Core Blazor.

Applicare una modalità di rendering a livello di codice

Le proprietà e i campi possono assegnare una modalità di rendering.

Il secondo approccio descritto in questa sezione, impostando la modalità di rendering per istanza del componente, è particolarmente utile quando la specifica dell'app chiama uno degli scenari seguenti:

  • Si dispone di un'area (cartella) dell'app con componenti che devono adottare il rendering statico lato server (SSR statico) e vengono eseguiti solo nel server. L'app controlla la modalità di rendering a livello globale impostando la modalità di rendering sul Routes componente nel App componente in base al percorso della cartella.
  • Sono presenti componenti intorno all'app in varie posizioni (non in una singola cartella) che devono adottare SSR statici ed essere eseguiti solo nel server. L'app controlla la modalità di rendering in base al componente impostando la modalità di rendering con la direttiva nelle istanze del @rendermode componente. La reflection viene utilizzata nel App componente per impostare la modalità di rendering nel Routes componente.

In entrambi i casi, anche il componente che deve adottare SSR statico deve forzare un ricaricamento a pagina intera.

I due scenari precedenti sono trattati con esempi nella sezione Controllo fine delle modalità di rendering più avanti in questo articolo. Le due sottosezioni seguenti sono incentrate sugli approcci di base per impostare la modalità di rendering.

Impostare la modalità di rendering per definizione del componente

Una definizione di componente può definire una modalità di rendering tramite un campo privato:

@rendermode renderModeForPage

...

@code {
    private static IComponentRenderMode renderModeForPage = InteractiveServer;
}

Impostare la modalità di rendering in base all'istanza del componente

Nell'esempio seguente viene applicato il rendering lato server interattivo (SSR interattivo) a qualsiasi richiesta.

<Routes @rendermode="RenderModeForPage" />

...

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

Altre informazioni sulla propagazione della modalità di rendering sono disponibili nella sezione Propagazione della modalità di rendering più avanti in questo articolo. La sezione Controllo fine delle modalità di rendering mostra come usare l'approccio precedente per adottare SSR statico in aree specifiche dell'app (cartelle) o per componenti specifici distribuiti nell'app con assegnazioni di modalità di rendering per componente.

Prerendering

Il prerendering è il processo di rendering iniziale del contenuto della pagina nel server senza abilitare i gestori eventi per i controlli di cui è stato eseguito il rendering. Il server restituisce l'interfaccia utente HTML della pagina appena possibile in risposta alla richiesta iniziale, che rende l'app più reattiva agli utenti. Il prerendering può anche migliorare l'ottimizzazione del motore di ricerca (edizione Standard O) eseguendo il rendering del contenuto per la risposta HTTP iniziale usata dai motori di ricerca per calcolare la classificazione delle pagine.

Il prerendering è abilitato per impostazione predefinita per i componenti interattivi.

Per disabilitare la prerendering per un'istanza del componente, passare il prerender flag con un valore di false alla modalità di rendering:

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

Per disabilitare la prerendering in una definizione di componente:

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

Per disabilitare la prerendering per l'intera app, indicare la modalità di rendering al componente interattivo di livello più alto nella gerarchia dei componenti dell'app che non è un componente radice.

Per le app basate sul modello di Blazor progetto app Web, viene specificata una modalità di rendering assegnata all'intera app in cui il Routes componente viene usato nel App componente (Components/App.razor). L'esempio seguente imposta la modalità di rendering dell'app su Interactive Server con prerendering disabilitato:

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

Disabilitare anche la prerendering per il HeadOutlet componente nel App componente:

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

La creazione di un componente radice, ad esempio il App componente, interattiva con la @rendermode direttiva all'inizio del file di definizione del componente radice (.razor) non è supportata. Di conseguenza, il prerendering non può essere disabilitato direttamente dal App componente.

Rendering statico lato server (SSR statico)

Per impostazione predefinita, i componenti usano il rendering statico lato server (SSR statico). Il rendering del componente nel flusso di risposta e nell'interattività non è abilitato.

Nell'esempio seguente non esiste alcuna designazione per la modalità di rendering del componente, quindi il componente eredita la modalità di rendering dal relativo elemento padre. Poiché nessun componente predecessore specifica una modalità di rendering, il rendering del componente seguente viene eseguito in modo statico nel server. Il pulsante non è interattivo e non chiama il UpdateMessage metodo quando selezionato. Il valore di message non cambia e il componente non viene rivalutato in risposta agli eventi dell'interfaccia utente.

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

Se si usa il componente precedente in locale in un'app Blazor Web, posizionare il componente nella cartella del progetto server Components/Pages . Il progetto server è il progetto della soluzione con un nome che non termina in .Client. Quando l'app è in esecuzione, passare a /render-mode-1 nella barra degli indirizzi del browser.

Durante il ssr statico, Razor le richieste di pagina dei componenti vengono elaborate dal lato server ASP.NET l'elaborazione delle richieste della pipeline middleware core per il routing e l'autorizzazione. Le funzionalità dedicate Blazor per il routing e l'autorizzazione non sono operative perché Razor il rendering dei componenti non viene eseguito durante l'elaborazione delle richieste sul lato server. Blazor le funzionalità del router nel Routes componente che non sono disponibili durante la visualizzazione statica di SSR includono la visualizzazione:

Se l'app presenta interattività a livello radice, l'elaborazione delle richieste core ASP.NET sul lato server non è coinvolta dopo il SSR statico iniziale, il che significa che le funzionalità precedenti Blazor funzionano come previsto.

La navigazione avanzata con SSR statico richiede particolare attenzione durante il caricamento di JavaScript. Per altre informazioni, vedere ASP.NET Core Blazor JavaScript con rendering statico lato server (SSR statico).

Rendering lato server interattivo (SSR interattivo)

Il rendering lato server interattivo (SSR interattivo) esegue il rendering interattivo del componente dal server usando Blazor Server. Le interazioni utente vengono gestite tramite una connessione in tempo reale con il browser. La connessione al circuito viene stabilita quando viene eseguito il rendering del componente server.

Nell'esempio seguente la modalità di rendering viene impostata su SSR interattivo aggiungendo @rendermode InteractiveServer alla definizione del componente. Il pulsante chiama il UpdateMessage metodo quando selezionato. Il valore delle message modifiche e il componente viene riabilita per aggiornare il messaggio nell'interfaccia utente.

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

Se si usa il componente precedente in locale in un'app Blazor Web, posizionare il componente nella cartella del progetto server Components/Pages . Il progetto server è il progetto della soluzione con un nome che non termina in .Client. Quando l'app è in esecuzione, passare a /render-mode-2 nella barra degli indirizzi del browser.

Rendering lato client

Il rendering lato client esegue il rendering interattivo del componente nel client usando Blazor WebAssembly. Il runtime .NET e il bundle dell'app vengono scaricati e memorizzati nella cache quando viene inizialmente eseguito il rendering del componente WebAssembly. I componenti che usano CSR devono essere compilati da un progetto client separato che configura l'host Blazor WebAssembly .

Nell'esempio seguente la modalità di rendering è impostata su CSR con @rendermode InteractiveWebAssembly. Il pulsante chiama il UpdateMessage metodo quando selezionato. Il valore delle message modifiche e il componente viene riabilita per aggiornare il messaggio nell'interfaccia utente.

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

Se si usa il componente precedente in locale in un'app Blazor Web, posizionare il componente nella cartella del Pages progetto client. Il progetto client è il progetto della soluzione con un nome che termina con .Client. Quando l'app è in esecuzione, passare a /render-mode-3 nella barra degli indirizzi del browser.

Rendering automatico (automatico)

Il rendering automatico (automatico) determina come eseguire il rendering del componente in fase di esecuzione. Il rendering del componente viene inizialmente eseguito con il rendering interattivo lato server (SSR interattivo) usando il Blazor Server modello di hosting. Il runtime .NET e il bundle dell'app vengono scaricati nel client in background e memorizzati nella cache in modo che possano essere usati nelle visite future.

La modalità di rendering automatico non modifica mai dinamicamente la modalità di rendering di un componente già presente nella pagina. La modalità di rendering automatico prende una decisione iniziale sul tipo di interattività da usare per un componente, quindi il componente mantiene tale tipo di interattività purché si tratti della pagina. Un fattore di questa decisione iniziale consiste nel valutare se i componenti esistono già nella pagina con interattività WebAssembly/Server. La modalità automatica preferisce selezionare una modalità di rendering corrispondente alla modalità di rendering dei componenti interattivi esistenti. Il motivo per cui la modalità Automatica preferisce usare una modalità di interattività esistente consiste nell'evitare di introdurre un nuovo runtime interattivo che non condivide lo stato con il runtime esistente.

I componenti che usano la modalità di rendering automatico devono essere compilati da un progetto client separato che configura l'host Blazor WebAssembly .

Nell'esempio seguente il componente è interattivo in tutto il processo. Il pulsante chiama il UpdateMessage metodo quando selezionato. Il valore delle message modifiche e il componente viene riabilita per aggiornare il messaggio nell'interfaccia utente. Inizialmente, il rendering del componente viene eseguito in modo interattivo dal server, ma nelle visite successive viene eseguito il rendering dal client dopo che il runtime .NET e il bundle dell'app vengono scaricati e memorizzati nella 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!";
    }
}

Se si usa il componente precedente in locale in un'app Blazor Web, posizionare il componente nella cartella del Pages progetto client. Il progetto client è il progetto della soluzione con un nome che termina con .Client. Quando l'app è in esecuzione, passare a /render-mode-4 nella barra degli indirizzi del browser.

Propagazione della modalità di rendering

Le modalità di rendering si propagano verso il basso nella gerarchia dei componenti.

Regole per l'applicazione delle modalità di rendering:

  • La modalità di rendering predefinita è Statica.
  • Le modalità di rendering Interactive Server (InteractiveServer), Interactive WebAssembly (InteractiveWebAssembly) e Interactive Auto (InteractiveAuto) possono essere usate da un componente, inclusa l'uso di modalità di rendering diverse per i componenti di pari livello.
  • Non è possibile passare a una modalità di rendering interattiva diversa in un componente figlio. Ad esempio, un componente server non può essere figlio di un componente WebAssembly.
  • I parametri passati a un componente figlio interattivo da un elemento padre statico devono essere JSserializzabili. Ciò significa che non è possibile passare frammenti di rendering o contenuto figlio da un componente padre statico a un componente figlio interattivo.

Gli esempi seguenti usano un componente non instradabile e non di pagina SharedMessage . Il componente indipendente dalla modalità SharedMessage di rendering non applica una modalità di rendering con una @attribute direttiva . Se si testano questi scenari con un'app Blazor Web, posizionare il componente seguente nella cartella dell'app Components .

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

Ereditarietà della modalità di rendering

Se il SharedMessage componente viene inserito in un componente padre sottoposto a rendering statico, viene eseguito anche il rendering statico del SharedMessage componente e non è interattivo. Il pulsante non chiama UpdateMessagee il messaggio non viene aggiornato.

RenderMode5.razor:

@page "/render-mode-5"

<SharedMessage />

Se il SharedMessage componente viene inserito in un componente che definisce la modalità di rendering, eredita la modalità di rendering applicata.

Nell'esempio seguente il SharedMessage componente è interattivo tramite una SignalR connessione al client. Il pulsante chiama UpdateMessagee il messaggio viene aggiornato.

RenderMode6.razor:

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

<SharedMessage />

Componenti figlio con diverse modalità di rendering

Nell'esempio seguente, entrambi i SharedMessage componenti vengono prerenderati (per impostazione predefinita) e vengono visualizzati quando la pagina viene visualizzata nel browser.

  • Il primo SharedMessage componente con rendering interattivo lato server (SSR interattivo) è interattivo dopo la creazione del SignalR circuito.
  • Il secondo SharedMessage componente con rendering lato client (CSR) è interattivo dopo il download del Blazor bundle dell'app e il runtime .NET è attivo nel client.

RenderMode7.razor:

@page "/render-mode-7"

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

Componente figlio con un parametro serializzabile

Nell'esempio seguente viene illustrato un componente figlio interattivo che accetta un parametro . I parametri devono essere serializzabili.

RenderMode8.razor:

@page "/render-mode-8"

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

I parametri del componente non serializzabili, ad esempio il contenuto figlio o un frammento di rendering, non sono supportati. Nell'esempio seguente, il passaggio del contenuto figlio al SharedMessage componente genera un errore di runtime.

RenderMode9.razor:

@page "/render-mode-9"

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

Errore:

System.InvalidOperationException: impossibile passare il parametro 'ChildContent' al componente 'SharedMessage' con renderingmode 'InteractiveServerRenderMode'. Questo perché il parametro è del tipo delegato 'Microsoft.AspNetCore.Components.RenderFragment', che è codice arbitrario e non può essere serializzato.

Per aggirare la limitazione precedente, eseguire il wrapping del componente figlio in un altro componente che non ha il parametro . Questo è l'approccio adottato nel Blazor modello di progetto app Web con il componente (Components/Routes.razor) per eseguire il Routes wrapping del Router componente.

WrapperComponent.razor:

<SharedMessage>
    Child content
</SharedMessage>

RenderMode10.razor:

@page "/render-mode-10"

<WrapperComponent @rendermode="InteractiveServer" />

Nell'esempio precedente:

  • Il contenuto figlio viene passato al SharedMessage componente senza generare un errore di runtime.
  • Il SharedMessage componente esegue il rendering interattivo nel server.

Componente figlio con una modalità di rendering diversa da quella padre

Non provare ad applicare una modalità di rendering interattiva diversa a un componente figlio rispetto alla modalità di rendering del padre.

Il componente seguente genera un errore di runtime quando viene eseguito il rendering del componente:

RenderMode11.razor:

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

<SharedMessage @rendermode="InteractiveWebAssembly" />

Errore:

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.

Controllo corretto delle modalità di rendering

In alcuni casi la specifica dell'app richiede ai componenti di adottare il rendering statico lato server (SSR statico) e viene eseguito solo nel server, mentre il resto dell'app usa una modalità di rendering interattiva.

Esistono due approcci che è possibile adottare per controllare correttamente le modalità di rendering, ognuna delle quali è descritta nelle sottosezioni seguenti:

  • Area (cartella) dei componenti statici di SSR: è presente un'area (cartella) dell'app con componenti che devono adottare SSR statici e condividere lo stesso prefisso del percorso di route. L'app controlla la modalità di rendering a livello globale impostando la modalità di rendering sul Routes componente nel App componente in base al percorso della cartella.

  • Componenti SSR statici distribuiti nell'app: sono presenti componenti distribuiti nell'app in diverse posizioni che devono adottare SSR statici ed essere eseguiti solo nel server. I componenti statici solo SSR non si trovano in una singola cartella e non condividono un prefisso di percorso di route comune. L'app controlla la modalità di rendering in base al componente impostando la modalità di rendering con la direttiva nelle istanze del @rendermode componente. La reflection viene utilizzata nel App componente per impostare la modalità di rendering nel Routes componente.

In entrambi i casi, anche il componente che deve adottare SSR statico deve forzare un ricaricamento a pagina intera.

Negli esempi seguenti viene usato il HttpContext parametro a catena per determinare se la pagina viene sottoposta a rendering statico. Un nullHttpContext valore indica che il rendering del componente viene eseguito in modo interattivo, utile come segnale nel codice dell'app per attivare un ricaricamento a pagina intera.

Area (cartella) dei componenti statici di SSR

L'approccio descritto in questa sottosezione viene usato dal Blazor modello di progetto app Web con autenticazione singola e interattività globale.

Un'area (cartella) dell'app contiene i componenti che devono adottare SSR statici ed essere eseguiti solo nel server. I componenti nella cartella condividono lo stesso prefisso del percorso di route. Ad esempio, i IdentityRazor componenti del Blazor modello di progetto app Web si trovano nella Components/Account/Pages cartella e condividono il prefisso /Accountdel percorso radice .

La cartella contiene anche un _Imports.razor file, che applica un layout di account personalizzato ai componenti nella cartella:

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

La Shared cartella gestisce il componente di AccountLayout layout. Il componente usa HttpContext per determinare se il componente esegue il rendering nel server. Identity I componenti devono eseguire il rendering nel server con SSR statico perché sono impostati Identitycookie. Se il valore di HttpContext è null, il rendering del componente viene eseguito in modo interattivo e viene eseguito un ricaricamento a pagina intera chiamando NavigationManager.Refresh con forceLoad impostato su true. In questo modo viene usata una ripetizione completa della pagina tramite SSR statico.

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

Nota

Blazor Nel modello di progetto app Web è presente un secondo file di layout (ManageLayout.razor nella cartella ) per Identity i Components/Account/Shared componenti nella Components/Account/Pages/Manage cartella . La Manage cartella ha il proprio _Imports.razor file da applicare ai ManageLayout componenti nella cartella . Nelle tue app, l'uso di file annidati _Imports.razor è un approccio utile per applicare layout personalizzati a gruppi di pagine.

App Nel componente, qualsiasi richiesta di un componente nella Account cartella applica una null modalità di rendering, che applica SSR statico. Altre richieste di componenti ricevono un'applicazione globale della modalità di rendering interattiva di SSR (InteractiveServer).

Importante

L'applicazione di una null modalità di rendering non applica sempre SSR statico. Si comporta in questo modo usando l'approccio illustrato in questa sezione.

Una null modalità di rendering equivale effettivamente a non specificare una modalità di rendering, che comporta l'ereditarietà della modalità di rendering del componente padre. In questo caso, il rendering del App componente viene eseguito tramite SSR statico, pertanto una null modalità di rendering determina l'ereditarietà Routes di SSR statico dal App componente. Se viene specificata una modalità di rendering Null per un componente figlio il cui padre usa una modalità di rendering interattiva, l'elemento figlio eredita la stessa modalità di rendering interattiva.

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

Nel codice precedente modificare il {INTERACTIVE RENDER MODE} segnaposto con il valore appropriato, a seconda che il resto dell'applicazione debba adottare il rendering globale InteractiveServer, InteractiveWebAssemblyo InteractiveAuto .

I componenti che devono adottare ssr statici nella Account cartella non sono necessari per impostare il layout perché vengono applicati tramite il _Imports.razor file e i componenti non impostano una modalità di rendering perché devono eseguire il rendering con SSR statico. Non è necessario eseguire altre operazioni per i componenti nella Account cartella per applicare ssr statici.

Componenti SSR statici distribuiti nell'app

Nella sottosezione precedente, l'app controlla la modalità di rendering dei componenti impostando la modalità di rendering a livello globale nel App componente. In alternativa, il App componente può anche adottare modalità di rendering per componente per impostare la modalità di rendering, che consente ai componenti distribuiti nell'app di applicare l'adozione di SSR statici. Questa sottosezione descrive l'approccio.

L'app ha un layout personalizzato che può essere applicato ai componenti dell'app. In genere, un componente condiviso per l'app viene inserito nella Components/Layout cartella . Il componente usa HttpContext per determinare se il componente esegue il rendering nel server. Se il valore di HttpContext è null, il rendering del componente viene eseguito in modo interattivo e viene eseguito un ricaricamento a pagina intera chiamando NavigationManager.Refresh con forceLoad impostato su true. In questo modo viene attivata una richiesta al server per il componente.

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

App Nel componente viene usata la reflection per impostare la modalità di rendering. Qualsiasi modalità di rendering assegnata al singolo file di definizione del componente viene applicata al Routes componente.

Components/App.razor:

<Routes @rendermode="RenderModeForPage" />

...

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

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

Ogni componente che deve adottare SSR statico imposta il layout personalizzato e non specifica una modalità di rendering. Se non si specifica una modalità di rendering, viene restituito un null valore di RenderModeAttribute.Mode nel componente, che non comporta alcuna modalità di rendering assegnata all'istanza del Routes componente e l'applicazione di SSR statico.App

Importante

L'applicazione di una null modalità di rendering non applica sempre SSR statico. Si comporta in questo modo usando l'approccio illustrato in questa sezione.

Una null modalità di rendering equivale effettivamente a non specificare una modalità di rendering, che comporta l'ereditarietà della modalità di rendering del componente padre. In questo caso, il rendering del App componente viene eseguito tramite SSR statico, pertanto una null modalità di rendering determina l'ereditarietà Routes di SSR statico dal App componente. Se viene specificata una modalità di rendering Null per un componente figlio il cui padre usa una modalità di rendering interattiva, l'elemento figlio eredita la stessa modalità di rendering interattiva.

Non è necessario eseguire altre operazioni per i componenti per applicare ssr statici rispetto all'applicazione del layout personalizzato senza impostare una modalità di rendering interattiva:

@layout BlazorSample.Components.Layout.StaticSsrLayout

I componenti interattivi intorno all'app evitano di applicare il layout statico di SSR personalizzato e impostano solo una modalità di rendering interattiva appropriata, che alla reflection nel App componente viene applicata:Routes

@rendermode {INTERACTIVE RENDER MODE}

Nel codice precedente modificare il {INTERACTIVE RENDER MODE} segnaposto con il valore appropriato, a seconda che il componente debba adottare InteractiveServer, InteractiveWebAssemblyo InteractiveAuto il rendering.

I servizi sul lato client non riescono a risolvere durante il pre-riavvio

Supponendo che il prerendering non sia disabilitato per un componente o per l'app, un componente nel .Client progetto viene pre-predefinito nel server. Poiché il server non ha accesso ai servizi lato Blazor client registrati, non è possibile inserire questi servizi in un componente senza ricevere un errore che indica che non è possibile trovare il servizio durante la pre-gestione.

Si consideri ad esempio il componente seguente Home nel .Client progetto in un'app Blazor Web con rendering Interattivo WebAssembly o Interattivo automatico. Il componente tenta di inserire IWebAssemblyHostEnvironment per ottenere il nome dell'ambiente.

@page "/"
@inject IWebAssemblyHostEnvironment Environment

<PageTitle>Home</PageTitle>

<h1>Home</h1>

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

Non si verifica alcun errore in fase di compilazione, ma si verifica un errore di runtime durante la pre-esecuzione:

Impossibile specificare un valore per la proprietà 'Environment' nel tipo 'BlazorSample.Client.Pages'Home. Non esiste alcun servizio registrato di tipo 'Microsoft.AspNetCore.Components.WebAssembly.Hosting.IWebAssemblyHostEnvironment'.

Questo errore si verifica perché il componente deve essere compilato ed eseguito nel server durante la pre-esecuzione, ma IWebAssemblyHostEnvironment non è un servizio registrato nel server.

Se l'app non richiede il valore durante la prerendering, questo problema può essere risolto inserendo IServiceProvider per ottenere il servizio anziché il tipo di servizio stesso:

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

Tuttavia, l'approccio precedente non è utile se la logica richiede un valore durante la prerendering.

È anche possibile evitare il problema se si disabilita il prerendering per il componente, ma si tratta di una misura estrema da adottare in molti casi che potrebbero non soddisfare le specifiche del componente.

Esistono tre approcci che è possibile adottare per risolvere questo scenario. Di seguito sono elencate le opzioni consigliate per la maggior parte consigliate:

  • Consigliato per i servizi framework condivisi: per i servizi framework condivisi che semplicemente non sono registrati sul lato server nel progetto principale, registrare i servizi nel progetto principale, rendendoli disponibili durante la pre-gestione. Per un esempio di questo scenario, vedere le linee guida per HttpClient i servizi in Chiamare un'API Web da un'app ASP.NET CoreBlazor.

  • Consigliato per i servizi all'esterno del framework condiviso: creare un'implementazione del servizio personalizzata per il servizio nel server. Usare il servizio normalmente nei componenti interattivi del .Client progetto. Per una dimostrazione di questo approccio, vedere ASP.NET Ambienti CoreBlazor.

  • Creare un'astrazione del servizio e creare implementazioni per il servizio nei .Client progetti server e . Registrare i servizi in ogni progetto. Inserire il servizio personalizzato nel componente.

  • Potrebbe essere possibile aggiungere un .Client riferimento al pacchetto di progetto a un pacchetto sul lato server ed eseguire il fallback all'uso dell'API lato server durante la pre-esecuzione del rendering nel server.

Individuare i componenti da assembly aggiuntivi

Per individuare i componenti instradabili Razor nei progetti a cui si fa riferimento, è necessario divulgare assembly aggiuntivi al Blazor framework. Per altre informazioni, vedere ASP.NET routing e navigazione coreBlazor.

Chiusura di circuiti quando non sono presenti componenti Interactive Server rimanenti

I componenti di Interactive Server gestiscono gli eventi dell'interfaccia utente Web usando una connessione in tempo reale con il browser denominato circuito. Un circuito e lo stato associato vengono creati quando viene eseguito il rendering di un componente Interactive Server radice. Il circuito viene chiuso quando nella pagina non sono presenti componenti Interactive Server rimanenti, che liberano risorse server.

Modalità di rendering abbreviate personalizzate

La @rendermode direttiva accetta un singolo parametro che è un'istanza statica di tipo IComponentRenderMode. L'attributo @rendermode di direttiva può accettare qualsiasi istanza della modalità di rendering, statica o meno. Il Blazor framework fornisce la RenderMode classe statica con alcune modalità di rendering predefinite per praticità, ma è possibile crearne di personalizzate.

In genere, un componente usa la direttiva seguente @rendermode per disabilitare il prerendering:

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

Si consideri tuttavia l'esempio seguente che crea una modalità di rendering lato server interattivo a mano abbreviata senza eseguire la pre-esecuzione tramite il file dell'app _Imports (Components/_Imports.razor):

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

Usare la modalità di rendering abbreviata nei componenti della Components cartella:

@rendermode InteractiveServerWithoutPrerendering

In alternativa, una singola istanza del componente può definire una modalità di rendering personalizzata tramite un campo privato:

@rendermode interactiveServerWithoutPrerendering

...

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

Al momento, l'approccio alla modalità di rendering abbreviata è probabilmente utile solo per ridurre il livello di dettaglio dell'impostazione del prerender flag. L'approccio abbreviato potrebbe risultare più utile in futuro se sono disponibili flag aggiuntivi per il rendering interattivo e si vogliono creare modalità di rendering abbreviate con diverse combinazioni di flag.

Inserimento del servizio tramite un file di importazione di primo livello (_Imports.razor)

Questa sezione si applica solo a Blazor App Web.

Un file di primo livello importa nella Components cartella (Components/_Imports.razor) inserisce i riferimenti in tutti i componenti nella gerarchia di cartelle, che include il App componente (App.razor). Il rendering del App componente viene sempre eseguito in modo statico anche se la pre-gestione di un componente di pagina è disabilitata. Pertanto, l'inserimento di servizi tramite il file di importazione di primo livello comporta la risoluzione di due istanze del servizio nei componenti della pagina.

Per risolvere questo scenario, inserire il servizio in un nuovo file di importazioni inserito nella Pages cartella (Components/Pages/_Imports.razor). Da tale posizione, il servizio viene risolto una sola volta nei componenti della pagina.

Risorse aggiuntive