Udostępnij za pośrednictwem


tryby renderowania ASP.NET Core Blazor

Uwaga

Nie jest to najnowsza wersja tego artykułu. Aby zapoznać się z bieżącym wydaniem, zobacz wersję tego artykułu dla .NET 9.

Ważne

Te informacje odnoszą się do produktu w wersji wstępnej, który może zostać znacząco zmodyfikowany, zanim zostanie wydany komercyjnie. Firma Microsoft nie udziela żadnych gwarancji, jawnych lub domniemanych, w odniesieniu do informacji podanych w tym miejscu.

Aby zapoznać się z bieżącym wydaniem, zobacz wersję tego artykułu dla .NET 9.

W tym artykule wyjaśniono kontrolowanie renderowania komponentów Razor w Blazor Web App zarówno podczas kompilacji, jak i uruchamiania.

Te wskazówki nie dotyczą aplikacji autonomicznych Blazor WebAssembly . Blazor WebAssemblyaplikacje są renderowane tylko na kliencie za pośrednictwem środowiska uruchomieniowego webAssembly po stronie klienta i nie mają pojęcia trybu renderowania. Jeśli tryb renderowania jest stosowany do składnika w Blazor WebAssembly aplikacji, oznaczenie trybu renderowania nie ma wpływu na renderowanie składnika.

Tryby renderowania

Każdy składnik w programie Blazor Web App przyjmuje tryb renderowania w celu określenia modelu hostingu, którego używa, gdzie jest renderowany i czy jest interaktywny. interaktywność umożliwia użytkownikom interakcję z renderowanych komponentów. Obejmuje to odpowiedzi aplikacji na zdarzenia Document Object Model (DOM) oraz zmiany stanu powiązane z członkami C# poprzez programy obsługi zdarzeń i powiązania Blazor.

W poniższej tabeli przedstawiono dostępne tryby renderowania składników Razor w ramach Blazor Web App. Aby zastosować tryb renderowania do składnika, należy użyć dyrektywy @rendermode dla wystąpienia lub definicji składnika. W dalszej części tego artykułu przedstawiono przykłady dla każdego scenariusza trybu renderowania.

Nazwa/nazwisko opis Lokalizacja renderowania Interakcyjny
Serwer statyczny Statyczne renderowanie po stronie serwera (statyczne SSR) Serwer Nie
Serwer interaktywny Interaktywne renderowanie po stronie serwera (interaktywne SSR) przy użyciu Blazor Server. Serwer Tak
Interakcyjny zestaw WebAssembly Renderowanie po stronie klienta (CSR) przy użyciu Blazor WebAssembly†. Klient Tak
Interaktywny Samochód Interaktywna usługa SSR jest uruchamiana początkowo, Blazor Server, a następnie podczas kolejnych wizyt działa jako CSR po pobraniu pakietu Blazor. Serwer, a następnie klient Tak

† przyjmuje się, że renderowanie po stronie klienta (CSR) jest interaktywne. "Interaktywne renderowanie po stronie klienta" i "interaktywne CSR" nie są używane ani przez branżę, ani w Blazor dokumentacji."

Prerendering jest domyślnie włączony dla składników interaktywnych. Wskazówki dotyczące kontrolowania prerenderingu podano w dalszej części tego artykułu. Aby uzyskać ogólną terminologię branżową dotyczącą pojęć związanych z renderowaniem na kliencie i serwerze, zobacz Podstawy ASP.NET CoreBlazor.

W poniższych przykładach pokazano ustawienie trybu renderowania składnika z kilkoma podstawowymi Razor funkcjami składników.

Aby przetestować zachowania trybu renderowania lokalnie, możesz umieścić następujące składniki w aplikacji utworzonej na podstawie szablonu Blazor Web App projektu. Podczas tworzenia aplikacji wybierz opcje z menu rozwijanych (Visual Studio) lub zastosuj opcje interfejsu wiersza polecenia (interfejs wiersza polecenia platformy.NET), aby włączyć interakcyjność po stronie serwera i po stronie klienta. Aby uzyskać wskazówki dotyczące tworzenia elementu Blazor Web App, zobacz Tooling for ASP.NET Core (Narzędzia dla platformy ASP.NET Core Blazor).

Włączanie obsługi interakcyjnych trybów renderowania

Konieczne jest skonfigurowanie Blazor Web App, aby obsługiwał tryby renderowania interakcyjnego. Następujące rozszerzenia są automatycznie stosowane do aplikacji utworzonych na podstawie Blazor Web App szablonu projektu podczas tworzenia aplikacji. Poszczególne składniki muszą nadal deklarować tryb renderowania zgodnie z sekcją Tryby renderowania po skonfigurowaniu usług i punktów końcowych komponentów w pliku aplikacji Program.

Usługi dla składników Razor są dodawane przez wywołanie AddRazorComponents.

Rozszerzenia konstruktora składników:

MapRazorComponents odnajduje dostępne składniki i określa składnik główny aplikacji (pierwszy załadowany składnik), który domyślnie jest składnikiem App (App.razor).

Rozszerzenia konstruktora konwencji punktu końcowego:

Uwaga

Aby uzyskać orientację dotyczącą umieszczenia interfejsu API w poniższych przykładach, sprawdź plik Program aplikacji wygenerowanej z szablonu projektu Blazor Web App. Aby uzyskać wskazówki dotyczące tworzenia elementu Blazor Web App, zobacz Tooling for ASP.NET Core (Narzędzia dla platformy ASP.NET Core Blazor).

Przykład 1: Następujące Program API plików dodaje usługi i konfigurację do włączania interaktywnego SSR (Server-Side Rendering):

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

Przykład 2: Następujące Program API plików dodaje usługi i konfigurację do uruchomienia interaktywnego trybu renderowania WebAssembly.

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

Przykład 3: Następujący Program interfejs API plików dodaje usługi i konfigurację, aby umożliwić włączenie trybów renderowania: Interaktywnego Serwera, Interaktywnego WebAssembly i Interaktywnego Automatycznego Renderowania.

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

Blazor używa modelu hostingu do pobierania i wykonywania składników, które korzystają z trybu renderowania interaktywny WebAssembly. Do skonfigurowania Blazor WebAssembly hostingu dla tych składników jest wymagany oddzielny projekt klienta. Projekt klienta zawiera kod uruchamiania hosta Blazor WebAssembly i konfiguruje środowisko uruchomieniowe platformy .NET do uruchamiania w przeglądarce. Szablon Blazor Web App dodaje ten projekt klienta po wybraniu opcji włączenia interaktywności WebAssembly. Wszystkie składniki korzystające z trybu renderowania Interactive WebAssembly powinny być kompilowane z projektu klienta, aby zostały uwzględnione w pobranym pakiecie aplikacji.

Stosuj tryb renderowania do instancji składnika

Aby zastosować tryb renderowania do wystąpienia składnika, użyj atrybutu dyrektywy @rendermodeRazor w miejscu, gdzie jest używany składnik.

W poniższym przykładzie interakcyjne renderowanie po stronie serwera (interakcyjne SSR) jest stosowane do wystąpienia składnika Dialog.

<Dialog @rendermode="InteractiveServer" />

Uwaga

Blazor szablony zawierają statyczną dyrektywę using dla RenderMode w pliku _Imports aplikacji (Components/_Imports.razor) w celu uzyskania krótszej składni @rendermode:

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

W przypadku braku powyższej dyrektywy składniki muszą określać klasę statyczną RenderMode w składni @rendermode.

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

Możesz również odwoływać się do instancji niestandardowego trybu renderowania utworzonych bezpośrednio za pomocą konfiguracji niestandardowej. Aby uzyskać więcej informacji, zobacz sekcję Niestandardowe tryby renderowania skróconego w dalszej części tego artykułu.

Stosowanie trybu renderowania do definicji składnika

Aby określić tryb renderowania składnika w ramach jego definicji, użyj @rendermodeRazor dyrektywy i odpowiedniego atrybutu trybu renderowania.

@page "..."
@rendermode InteractiveServer

Stosowanie trybu renderowania do definicji składnika jest często używane podczas stosowania trybu renderowania do określonej strony. Routowalne strony używają tego samego trybu renderowania co składnik Router, który wyrenderował stronę.

Technicznie rzecz biorąc, @rendermode jest zarówno Razordyrektywą, jak i Razoratrybutem dyrektywy. Semantyka jest podobna, ale istnieją różnice. @rendermode Dyrektywa dotyczy definicji składnika, więc wystąpienie trybu renderowania, do którego się odwołuje, musi być statyczne. Atrybut dyrektywy @rendermode może przyjmować dowolne wystąpienie trybu renderowania.

Uwaga

Autorzy składników powinni unikać sprzęgania implementacji składnika z określonym trybem renderowania. Zamiast tego autorzy składników powinni zazwyczaj projektować składniki do obsługi dowolnego trybu renderowania lub modelu hostingu. Implementacja składnika powinna unikać założeń dotyczących tego, gdzie jest uruchamiana (serwer czy klient) i powinna stopniowo się degradować podczas renderowania statycznego. pl-PL: Określenie trybu renderowania w definicji składnika może być konieczne, jeśli składnik nie jest tworzony bezpośrednio (na przykład w przypadku komponentu strony trasowanej) lub aby określić tryb renderowania dla wszystkich wystąpień składnika.

Stosowanie trybu renderowania do całej aplikacji

Aby ustawić tryb renderowania dla całej aplikacji, wskaż tryb renderowania na najwyższym poziomie składnika interaktywnego w hierarchii składników aplikacji, który nie jest składnikiem głównym.

Uwaga

Tworzenie interakcyjnego składnika głównego, takiego jak składnik App, nie jest wspierane. W związku z tym tryb renderowania dla całej aplikacji nie może być ustawiany bezpośrednio przez App składnik.

W przypadku aplikacji opartych na szablonie Blazor Web App projektu tryb renderowania przypisany do całej aplikacji jest zwykle określany, gdzie Routes składnik jest używany w składniku App (Components/App.razor):

<Routes @rendermode="InteractiveServer" />

Składnik Router propaguje tryb renderowania na stronach, na które prowadzi.

Zazwyczaj należy również ustawić ten sam tryb renderowania interaktywnego w składniku HeadOutlet, który znajduje się również w składniku App składnika Blazor Web App wygenerowanego z szablonu projektu:

<HeadOutlet @rendermode="InteractiveServer" />

W przypadku aplikacji, które przyjmują interaktywny tryb renderowania po stronie klienta (WebAssembly lub Auto) i włączają tryb renderowania dla całej aplikacji za pośrednictwem Routes składnika:

  • Umieść lub przenieś pliki układu i nawigacji folderu aplikacji Components/Layout serwera do .Client folderu projektu Layout . Utwórz folder Layout w projekcie .Client, jeśli nie istnieje.
  • Umieść lub przenieś składniki folderu aplikacji Components/Pages serwera do .Client folderu projektu Pages . Utwórz folder Pages w projekcie .Client, jeśli nie istnieje.
  • Umieść lub przenieś Routes składnik folderu aplikacji Components serwera do .Client folderu głównego projektu.

Aby włączyć globalną interakcyjność podczas tworzenia elementu Blazor Web App:

  • Visual Studio: ustaw listę rozwijaną Lokalizacja interaktywna na Global.
  • Interfejs wiersza polecenia .NET: użyj opcji -ai|--all-interactive.

Aby uzyskać więcej informacji, zobacz Tooling for ASP.NET Core Blazor.

Automatyczne zastosowanie trybu renderowania

Właściwości i pola mogą przypisywać tryb renderowania.

Drugie podejście opisane w tej sekcji, ustawienie trybu renderowania dla instancji składnika, jest szczególnie przydatne, gdy specyfikacja aplikacji wymaga, aby jeden lub więcej składników przyjęło statyczne SSR w przeważająco interaktywnej aplikacji. Ten scenariusz jest omówiony na stronach Static SSR w sekcji interaktywnej aplikacji w późniejszej części tego artykułu.

Ustawianie trybu renderowania według definicji składnika

Definicja składnika może definiować tryb renderowania za pomocą pola prywatnego:

@rendermode pageRenderMode

...

@code {
    private static IComponentRenderMode pageRenderMode = InteractiveServer;
}

Ustaw tryb renderowania przez instancję składnika

Poniższy przykład stosuje interaktywne renderowanie po stronie serwera (SSR) do każdego żądania.

<Routes @rendermode="PageRenderMode" />

...

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

Dodatkowe informacje na temat propagacji trybu renderowania znajdują się w sekcji Propagacja trybu renderowania w dalszej części tego artykułu. Sekcja statycznych stron SSR w interaktywnej aplikacji pokazuje, jak za pomocą przedstawionego podejścia wdrożyć statyczne SSR w aplikacji, która jest z założenia interaktywna.

Wykrywanie lokalizacji renderowania, interakcyjności i przypisanego trybu renderowania w czasie wykonywania

Właściwości ComponentBase.RendererInfo i ComponentBase.AssignedRenderMode umożliwiają aplikacji wykrywanie szczegółów dotyczących lokalizacji, interakcyjności i przypisanego trybu renderowania składnika:

  • RendererInfo.Name zwraca lokalizację, w której jest wykonywany składnik:
    • Static: Na serwerze (SSR) i niezdolny do interakcji.
    • Server: Na serwerze (SSR) i zdolny do interakcji po wstępnym przetwarzaniu.
    • WebAssembly: Na kliencie (CSR) i zdolnym do interaktywności po wstępnym renderowaniu.
    • WebView: na urządzeniu natywnym i umożliwia interaktywność po wstępnym renderowaniu.
  • RendererInfo.IsInteractive wskazuje, czy składnik obsługuje interakcyjność w czasie renderowania. Wartość wynosi true przy renderowaniu interaktywnym lub false przy prerenderowaniu lub statycznym SSR (RendererInfo.Name z Static).
  • AssignedRenderMode Uwidacznia przypisany przez składnik tryb renderowania:
    • InteractiveServerRenderMode dla serwera interakcyjnego.
    • InteractiveAutoRenderMode dla Interaktywnego Auto.
    • InteractiveWebAssemblyRenderMode w przypadku interaktywnego zestawu WebAssembly.
    • null, jeśli tryb renderowania nie jest przypisany.

Składniki używają tych właściwości do renderowania zawartości w zależności od ich lokalizacji lub stanu interakcyjności. W poniższych przykładach przedstawiono typowe przypadki użycia.

Wyświetlaj zawartość, aż składnik stanie się interaktywny.

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

Wyłącz przycisk, dopóki składnik nie będzie interakcyjny:

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

Wyłącz formularz podczas prerenderingu i włącz formularz, gdy składnik jest interaktywny:

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

Wyrenderuj znaczniki, aby obsłużyć regularną akcję HTML, jeśli komponent jest statycznie renderowany.

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

W powyższym przykładzie:

  • Gdy wartość parametru AssignedRenderMode to null, składnik przyjmuje statyczny SSR. Blazor Obsługa zdarzeń nie działa w przeglądarce ze statycznym żądaniem SSR, dlatego składnik przesyła formularz (żądanie GET) z ciągiem zapytania ustawionym titleFilter na wartość użytkownika <input> . Składnik Movie (/movie) może odczytać ciąg zapytania i przetworzyć wartość titleFilter, aby wyrenderować składnik z filtrowanymi wynikami.
  • W przeciwnym razie tryb renderowania to dowolny z InteractiveServer, InteractiveWebAssemblylub InteractiveAuto. Składnik może używać delegata programu obsługi zdarzeń (FilterMovies) oraz wartości powiązanej z elementem <input> do interaktywnego filtrowania filmów przez połączenie w tle titleFilter.

Blazor przykłady dokumentacji dla Blazor Web Apps

W przypadku korzystania z elementu Blazor Web Appwiększość przykładowych Blazor składników dokumentacji wymaga interakcyjności do działania i zademonstrowania pojęć omówionych w artykułach. Podczas testowania przykładowego składnika dostarczonego przez artykuł upewnij się, że aplikacja przyjmuje globalną interakcyjność lub składnik przyjmuje tryb renderowania interaktywnego.

Prerenderowanie

Prerendering to proces początkowego renderowania zawartości strony na serwerze bez włączania procedur obsługi zdarzeń dla renderowanych kontrolek. Serwer zwraca interfejs użytkownika HTML strony tak szybko, jak to możliwe w odpowiedzi na początkowe żądanie, co sprawia, że aplikacja wydaje się bardziej responsywna dla użytkowników. Prerendering może również poprawić optymalizację dla wyszukiwarek (SEO) poprzez renderowanie zawartości w początkowej odpowiedzi HTTP, która jest używana przez wyszukiwarki do obliczania rangi strony.

Prerendering jest domyślnie włączony dla składników interaktywnych.

Nawigacja wewnętrzna na potrzeby routingu interakcyjnego nie obejmuje żądania nowej zawartości strony z serwera. W związku z tym wstępne renderowanie nie występuje w przypadku żądań stron wewnętrznych, w tym dla rozszerzonej nawigacji. Aby uzyskać więcej informacji, zobacz Routing statyczny kontra interakcyjny, Routing interakcyjny i wstępne renderowanie oraz Ulepszona nawigacja i obsługa formularzy.

Wyłączenie prerenderingu przy użyciu poniższych technik ma zastosowanie tylko w przypadku trybów renderowania najwyższego poziomu. Jeśli składnik nadrzędny określa tryb renderowania, ustawienia wstępne jego elementów podrzędnych są ignorowane. To zachowanie jest badane pod kątem możliwych zmian w wydaniu platformy .NET 10 w listopadzie 2025 r.

Aby wyłączyć prerendering dla wystąpienia składnika, przekaż flagę prerender z wartością false do trybu renderowania.

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

Aby wyłączyć prerendering w definicji komponentu:

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

Aby wyłączyć wstępne przetwarzanie dla całej aplikacji, wskaż tryb renderowania na najwyższym poziomie składnika interaktywnego w hierarchii składników aplikacji, który nie jest składnikiem głównym.

W przypadku aplikacji opartych na szablonie Blazor Web App projektu tryb renderowania przypisany do całej aplikacji jest określony, gdzie Routes składnik jest używany w składniku App (Components/App.razor). W poniższym przykładzie ustawiono tryb renderowania aplikacji na Serwer interaktywny z wyłączonym prerenderingem.

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

Dodatkowo, wyłącz prerendering dla składnika HeadOutlet w składniku App.

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

Tworzenie interaktywnego składnika głównego, takiego jak składnik App, za pomocą dyrektywy @rendermode znajdującej się na górze pliku definicji składnika głównego (.razor) nie jest obsługiwane. W związku z tym prerendering nie może być bezpośrednio wyłączony przez komponent App.

Statyczne renderowanie po stronie serwera (statyczne SSR)

Komponenty używają statycznego renderowania po stronie serwera (SSR). Składnik renderuje się do strumienia odpowiedzi, a interakcyjność jest wyłączona.

W poniższym przykładzie nie ma oznaczenia dla trybu renderowania składnika, więc składnik dziedziczy jego tryb renderowania z elementu nadrzędnego. Ponieważ żaden składnik programu ancestor nie określa trybu renderowania, następujący składnik jest statycznie renderowany na serwerze. Przycisk nie jest interaktywny i nie wywołuje metody UpdateMessage po jego wybraniu. Wartość message nie zmienia się, a komponent nie jest przeładowany w odpowiedzi na zdarzenia interfejsu użytkownika.

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

Jeśli używasz wymienionego składnika lokalnie w Blazor Web App, umieść składnik w folderze Components/Pages projektu serwera. Projekt serwera to projekt rozwiązania o nazwie, która nie kończy się na .Client. Gdy aplikacja jest uruchomiona, przejdź do /render-mode-1 na pasku adresu przeglądarki.

Podczas statycznego SSR Razor żądania stron składników są obsługiwane przez potok oprogramowania pośredniczącego ASP.NET Core na serwerze, w celu routingu i autoryzacji. Dedykowane Blazor funkcje routingu i autoryzacji nie są operacyjne, ponieważ Razor komponenty nie są renderowane podczas przetwarzania żądań po stronie serwera. Blazor funkcje routera w komponencie Routes, które nie są dostępne podczas statycznego renderowania po stronie serwera (SSR), obejmują wyświetlanie:

Jeśli aplikacja wykazuje interakcyjność na poziomie głównym, przetwarzanie żądań po stronie serwera ASP.NET Core nie jest zaangażowane po początkowym statycznym renderowaniu po stronie serwera (SSR), co oznacza, że poprzednie Blazor funkcje działają zgodnie z oczekiwaniami.

Ulepszona nawigacja przy użyciu statycznego przewodnika SSR wymaga szczególnej uwagi podczas ładowania kodu JavaScript. Aby uzyskać więcej informacji, zobacz ASP.NET Core Blazor JavaScript z renderowaniem statycznym po stronie serwera (static SSR) .

Interaktywne renderowanie po stronie serwera (interaktywne SSR)

Interaktywne renderowanie po stronie serwera (interakcyjne SSR) renderuje składnik interaktywnie z serwera przy użyciu polecenia Blazor Server. Interakcje użytkownika są obsługiwane za pośrednictwem połączenia w czasie rzeczywistym z przeglądarką. Połączenie obwodu ustanawia się, gdy renderowany jest komponent serwera.

W poniższym przykładzie tryb renderowania jest ustawiany na interaktywny tryb SSR przez dodanie @rendermode InteractiveServer do definicji składnika. Przycisk wywołuje metodę UpdateMessage po wybraniu. Wartość message zmienia się, a komponent jest ponownie renderowany, aby zaktualizować komunikat w interfejsie użytkownika.

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

Jeśli używasz poprzedniego składnika w elemencie Blazor Web App, umieść składnik w folderze projektu Components/Pages serwera. Projekt serwera to projekt rozwiązania o nazwie, która nie kończy się na .Client. Gdy aplikacja jest uruchomiona, przejdź do /render-mode-2 na pasku adresu przeglądarki.

Renderowanie po stronie klienta (CSR)

Renderowanie po stronie klienta (CSR) renderuje składnik interaktywnie na kliencie przy użyciu polecenia Blazor WebAssembly. Środowisko uruchomieniowe platformy .NET i pakiet aplikacji są pobierane i buforowane, gdy składnik WebAssembly jest początkowo renderowany. Składniki używające CSR muszą być tworzone z osobnego projektu po stronie klienta, który konfiguruje Blazor WebAssembly hosta.

W poniższym przykładzie tryb renderowania jest ustawiony na CSR za pomocą @rendermode InteractiveWebAssembly polecenia. Przycisk wywołuje metodę UpdateMessage po wybraniu. Wartość message zmienia się, a komponent jest ponownie renderowany, aby zaktualizować komunikat w interfejsie użytkownika.

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

Jeśli używasz powyższego składnika lokalnie w Blazor Web App, umieść składnik w folderze projektu klienta Pages. Projekt klienta to projekt rozwiązania o nazwie kończącej się na .Client. Gdy aplikacja jest uruchomiona, przejdź do /render-mode-3 na pasku adresu przeglądarki.

Automatyczne renderowanie

Renderowanie automatyczne określa, jak renderować składnik podczas wykonywania. Składnik jest początkowo renderowany przy użyciu interaktywnego renderowania po stronie serwera (interakcyjnego SSR) przy użyciu modelu hostingu Blazor Server . Środowisko uruchomieniowe platformy .NET i pakiet aplikacji są pobierane do klienta w tle i buforowane, aby można było ich używać podczas przyszłych wizyt.

Tryb automatycznego renderowania nigdy nie zmienia dynamicznie trybu renderowania składnika już na stronie. Tryb automatycznego renderowania podejmuje początkową decyzję o tym, jakiego typu interakcyjność ma być używana dla składnika, a następnie składnik zachowuje ten typ interakcyjności tak długo, jak to jest na stronie. Jednym z czynników w tej początkowej decyzji jest rozważenie, czy składniki już istnieją na stronie z interaktywnymi funkcjami WebAssembly/serwera. Tryb automatyczny preferuje wybranie trybu renderowania zgodnego z trybem renderowania istniejących składników interaktywnych. Powodem, dla którego tryb automatyczny preferuje korzystanie z istniejącego trybu interakcyjnego, jest uniknięcie wprowadzenia nowego interakcyjnego środowiska uruchomieniowego, które nie współużytkuje stanu z istniejącym środowiskiem uruchomieniowym.

Składniki korzystające z trybu automatycznego renderowania muszą być tworzone z oddzielnego projektu klienta, który konfiguruje Blazor WebAssembly host.

W poniższym przykładzie składnik jest interaktywny w całym procesie. Przycisk wywołuje metodę UpdateMessage po wybraniu. Wartość message zmienia się, a komponent jest ponownie renderowany, aby zaktualizować komunikat w interfejsie użytkownika. Początkowo składnik jest renderowany interaktywnie z serwera, ale podczas kolejnych wizyt jest renderowany po stronie klienta, po pobraniu i zbuforowaniu środowiska uruchomieniowego .NET oraz pakietu aplikacji.

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

Jeśli używasz powyższego składnika lokalnie w Blazor Web App, umieść składnik w folderze projektu klienta Pages. Projekt klienta to projekt rozwiązania o nazwie kończącej się na .Client. Gdy aplikacja jest uruchomiona, przejdź do /render-mode-4 na pasku adresu przeglądarki.

Propagacja trybu renderowania

Tryby renderowania propagują się w dół hierarchii składników.

Reguły stosowania trybów renderowania:

  • Domyślny tryb renderowania to Statyczny.
  • Tryby renderowania Interactive Server (InteractiveServer), Interactive WebAssembly (InteractiveWebAssembly) i Interactive Auto (InteractiveAuto) mogą być używane z poziomu składnika, w tym przy użyciu różnych trybów renderowania dla składników równorzędnych.
  • Nie można przełączyć się na inny interaktywny tryb renderowania w składniku podrzędnym. Na przykład składnik serwera nie może być elementem podrzędnym składnika WebAssembly.
  • Parametry przekazywane do interaktywnego składnika podrzędnego z elementu nadrzędnego statycznego muszą być serializowalne w formacie JSON. Oznacza to, że nie można przekazać fragmentów renderowania ani zawartości podrzędnej ze składnika nadrzędnego Static do interaktywnego składnika podrzędnego.

W poniższych przykładach użyto komponentu niedającego się trasować, nie będącego częścią strony SharedMessage. Składnik SharedMessage niezależny od trybu renderowania nie stosuje trybu renderowania z dyrektywą @attribute. Jeśli testujesz te scenariusze za pomocą Blazor Web App, umieść następujący składnik w folderze Components aplikacji.

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

Dziedziczenie trybu renderowania

SharedMessage Jeśli składnik zostanie umieszczony w statycznie renderowanych składnikach nadrzędnych, SharedMessage składnik jest również renderowany statycznie i nie jest interaktywny. Przycisk nie wywołuje funkcji UpdateMessage, a komunikat nie jest aktualizowany.

RenderMode5.razor:

@page "/render-mode-5"

<SharedMessage />

SharedMessage Jeśli składnik zostanie umieszczony w składniku definiującym tryb renderowania, dziedziczy zastosowany tryb renderowania.

W poniższym przykładzie składnik SharedMessage jest interaktywny poprzez połączenie z klientem SignalR. Przycisk wywołuje UpdateMessage, a następnie komunikat zostaje zaktualizowany.

RenderMode6.razor:

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

<SharedMessage />

Komponenty podrzędne z różnymi trybami renderowania

W poniższym przykładzie oba SharedMessage składniki są wstępnie renderowane i pojawiają się, gdy strona jest wyświetlana w przeglądarce.

  • Pierwszy SharedMessage komponent z interaktywnym renderowaniem po stronie serwera (interactive SSR) staje się interaktywny po ustanowieniu obwodu BlazorSignalR.
  • Drugi SharedMessage składnik z renderowaniem po stronie klienta (CSR) jest interaktywny poBlazor pobraniu pakietu aplikacji, a środowisko uruchomieniowe platformy .NET jest aktywne na kliencie.

RenderMode7.razor:

@page "/render-mode-7"

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

Składnik podrzędny z serializowalnym parametrem

W poniższym przykładzie pokazano interaktywny komponent dziecka, który przyjmuje parametr. Parametry muszą być serializowalne.

RenderMode8.razor:

@page "/render-mode-8"

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

Parametry składnika, których nie można serializować, takie jak treść podrzędna lub fragment renderujący, nie są obsługiwane. W poniższym przykładzie przekazanie zawartości podrzędnej SharedMessage do składnika powoduje wystąpienie błędu w czasie wykonywania.

RenderMode9.razor:

@page "/render-mode-9"

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

Błąd:

System.InvalidOperationException: Nie można przekazać parametru "ChildContent" do składnika "SharedMessage" z trybem renderowania "InteractiveServerRenderMode". Jest to spowodowane tym, że parametr jest typu delegata "Microsoft.AspNetCore.Components.RenderFragment", który jest dowolnym kodem i nie można go serializować.

Aby obejść powyższe ograniczenie, opakuj składnik podrzędny w inny komponent, który nie posiada tego parametru. Jest to podejście zastosowane w szablonie projektu Blazor Web App ze składnikiem Routes (Components/Routes.razor) w celu otoczenia składnika Router.

WrapperComponent.razor:

<SharedMessage>
    Child content
</SharedMessage>

RenderMode10.razor:

@page "/render-mode-10"

<WrapperComponent @rendermode="InteractiveServer" />

W powyższym przykładzie:

  • Zawartość dziecięca jest przekazywana do składnika SharedMessage bez generowania błędu w czasie wykonywania.
  • Składnik SharedMessage jest renderowany interaktywnie na serwerze.

Komponent podrzędny z innym trybem renderowania niż jego komponent nadrzędny

Nie próbuj stosować innego interaktywnego trybu renderowania do składnika podrzędnego niż tryb renderowania elementu nadrzędnego.

Następujący składnik powoduje błąd środowiska uruchomieniowego po renderowaniu składnika:

RenderMode11.razor:

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

<SharedMessage @rendermode="InteractiveWebAssembly" />

Błąd:

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.

Statyczne strony SSR w aplikacji interaktywnej

Istnieją przypadki, w których specyfikacja aplikacji wymaga, aby składniki przyjęły statyczne renderowanie po stronie serwera (SSR) i były uruchamiane wyłącznie na serwerze, podczas gdy reszta aplikacji korzysta z interaktywnego trybu renderowania.

Takie podejście jest przydatne tylko wtedy, gdy aplikacja ma określone strony, które nie mogą działać z interaktywnym renderowaniem serwera lub przy renderowaniu za pomocą WebAssembly. Na przykład zastosuj to podejście dla stron, które zależą od odczytywania/zapisywania plików cookie HTTP i mogą działać tylko w cyklu żądania/odpowiedzi zamiast renderowania interakcyjnego. W przypadku stron, które działają z renderowaniem interaktywnym, nie należy wymuszać używania statycznego SSR, ponieważ jest mniej efektywne i mniej responsywne dla użytkownika końcowego.

Oznacz dowolną stronę składnika za pomocą atrybutu przypisanego do dyrektywy .

@attribute [ExcludeFromInteractiveRouting]

Zastosowanie atrybutu powoduje wyjście z routingu interakcyjnego podczas nawigacji do strony. Nawigacja przychodząca jest zmuszona do ponownego załadowania pełnej strony, zamiast ustalać stronę za pomocą interaktywnego routingu. Ponowne ładowanie pełnej strony wymusza element główny najwyższego poziomu, zazwyczaj składnik App (App.razor), aby ponownie renderować z serwera, co pozwala aplikacji przełączyć się do innego trybu renderowania najwyższego poziomu.

RazorComponentsEndpointHttpContextExtensions.AcceptsInteractiveRouting Metoda rozszerzenia umożliwia składnikowi wykrywanie, czy [ExcludeFromInteractiveRouting] atrybut jest stosowany do bieżącej strony.

W składniku App użyj wzorca w poniższym przykładzie:

  • Strony, które nie są oznaczone atrybutem [ExcludeFromInteractiveRouting], domyślnie przechodzą w tryb renderowania InteractiveServer z globalną interaktywnością. Możesz zastąpić InteractiveServer ciągiem InteractiveWebAssembly lub InteractiveAuto, aby określić inny domyślny globalny tryb renderowania.
  • Strony oznaczone atrybutem [ExcludeFromInteractiveRouting] przyjmują statyczny SSR (PageRenderMode jest przypisane 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;
}

Alternatywą dla stosowania metody RazorComponentsEndpointHttpContextExtensions.AcceptsInteractiveRouting rozszerzenia jest ręczne odczytywanie metadanych punktu końcowego za pomocą HttpContext.GetEndpoint()?.Metadata.

Istnieją dwa podejścia, które można podjąć w celu precyzyjnej kontroli trybów renderowania, z których każda jest opisana w następujących podsekcjach:

  • Obszar (folder) statycznych komponentów SSR: masz obszar (folder) aplikacji z komponentami, które muszą przyjąć statyczny SSR i dzielić ten sam prefiks ścieżki trasy. Aplikacja kontroluje tryb renderowania globalnie, ustawiając tryb renderowania na składniku Routes w składniku App na podstawie ścieżki do folderu.

  • Statyczne składniki SSR rozłożone w całej aplikacji: Masz składniki rozmieszczone w różnych miejscach aplikacji, które muszą przyjąć statyczny SSR i być uruchamiane tylko na serwerze. Statyczne komponenty tylko do SSR nie znajdują się w jednym folderze i nie mają wspólnego prefiksu ścieżki trasy. Aplikacja zarządza trybem renderowania na poziomie poszczególnych komponentów, ustawiając tryb renderowania za pomocą dyrektywy @rendermode w instancjach komponentów. Odbicie jest używane w składniku App do ustawiania trybu renderowania na składniku Routes .

W obu przypadkach składnik, który musi przyjąć statyczne SSR, musi również wymusić pełne ponowne załadowanie strony.

W poniższych przykładach użyto parametru HttpContext kaskadowego, aby określić, czy strona jest renderowana statycznie. Element nullHttpContext wskazuje, że składnik renderuje interaktywnie, co jest przydatne jako sygnał w kodzie aplikacji w celu wyzwolenia ponownego ładowania pełnostronicowego.

Obszar (folder) statycznych składników SSR

Aby zapoznać się z przykładem podejścia w tej sekcji, zobacz przykładową aplikację BlazorWebAppAreaOfStaticSsrComponents. Technika opisana w tej sekcji jest najbardziej odpowiednia dla wersji 8.0 Blazor Web Apps, ale przykład jest implementowany w wersji 9.0 przy użyciu funkcji Blazor, które upraszczają pokazanie sposobu działania podejścia.

Podejście opisane w tej podsekcji jest używane przez szablon projektu Blazor Web App z globalną interakcyjnością.

Obszar (folder) aplikacji zawiera składniki, które muszą przyjąć statyczny protokół SSR i uruchamiać je tylko na serwerze. Komponenty w folderze mają ten sam prefiks ścieżki trasy. Na przykład składniki szablonu projektu IdentityRazor znajdują się w folderze Blazor Web App i współużytkują prefiks ścieżki głównej Components/Account/Pages.

Aplikacja zawiera również plik _Imports.razor, który jest automatycznie stosowany do statycznych komponentów SSR w folderze Components, co pozwala na zastosowanie niestandardowego rozmieszczenia.

Components/Account/_Imports.razor:

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

Folder Shared zawiera AccountLayout składnik układu. Składnik używa HttpContext do określenia, czy przyjął statyczny SSR. Na przykład komponenty Identity muszą być renderowane na serwerze ze statycznym SSR, ponieważ ustawiają Identity pliki cookie. Jeśli wartość HttpContext to null, składnik jest renderowany w sposób interaktywny, a pełne przeładowanie strony odbywa się przez wywołanie NavigationManager.Refresh z forceLoad ustawionym na true. Wymusza to pełne ponowne renderowanie strony przy użyciu statycznego SSR.

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

Uwaga

W szablonie projektu Blazor Web App dla scenariuszy uwierzytelniania znajduje się drugi plik układu (ManageLayout.razor w folderze Components/Account/Shared) dla składników Identity w folderze Components/Account/Pages/Manage. Folder Manage posiada własny plik _Imports.razor, który jest stosowany do komponentów ManageLayout w folderze. We własnych aplikacjach, korzystanie z zagnieżdżonych plików _Imports.razor to użyteczna metoda zastosowania niestandardowych układów do grup stron.

W składniku App każdy wniosek dotyczący składnika w folderze Account stosuje tryb renderowania null, który wymusza statyczne SSR. Inne żądania składników otrzymują globalne zastosowanie interakcyjnego trybu renderowania SSR (InteractiveServer).

Ważne

Ustawienie trybu renderowania null nie zawsze wymusza statyczne SSR. Dzieje się tak po prostu przy użyciu podejścia pokazanego w tej sekcji.

null Tryb renderowania jest w rzeczywistości taki sam, jak nieokreślenie trybu renderowania, co powoduje, że składnik dziedziczy tryb renderowania od elementu nadrzędnego. W takim przypadku składnik App jest renderowany przy użyciu statycznego SSR, więc tryb renderowania null powoduje, że składnik Routes dziedziczy statyczny SSR ze składnika App. Jeśli dla składnika podrzędnego, którego element nadrzędny używa trybu interaktywnego renderowania, określono tryb renderowania jako null, składnik podrzędny dziedziczy ten sam interaktywny tryb renderowania.

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

W poprzednim kodzie zmień symbol zastępczy {INTERACTIVE RENDER MODE} na odpowiednią wartość, w zależności od tego, czy reszta aplikacji powinna przyjąć globalne renderowanie InteractiveServer, InteractiveWebAssemblylub InteractiveAuto.

Składniki, które muszą przyjąć statyczne SSR w folderze Account, nie muszą ustawiać układu, który jest stosowany za pośrednictwem pliku _Imports.razor. Składniki nie ustawiają trybu renderowania, ponieważ powinny być renderowane z wykorzystaniem statycznego renderowania po stronie serwera (SSR). Aby wymusić statyczny SSR, nie należy wykonywać żadnych dalszych czynności dla składników w folderze Account.

Statyczne składniki SSR rozmieszczone w aplikacji

Aby zapoznać się z przykładem podejścia w tej sekcji, zobacz przykładową aplikację BlazorWebAppSpreadOutStaticSsrComponents. Technika opisana w tej sekcji jest najbardziej odpowiednia dla wersji 8.0 Blazor Web Apps, ale przykład jest implementowany w wersji 9.0 przy użyciu funkcji Blazor, które upraszczają pokazanie sposobu działania podejścia.

W poprzedniej podsekcji aplikacja kontroluje tryb renderowania składników, ustawiając tryb renderowania globalnie w składniku App . Alternatywnie, składnik App może również przyjąć tryby renderowania dla poszczególnych składników w celu ustawienia trybu renderowania, co pozwala składnikom rozmieszczonym w aplikacji wymusić zastosowanie statycznego SSR. W tej podsekcji opisano podejście.

Aplikacja ma niestandardowy układ, który można zastosować do składników wokół aplikacji. Zazwyczaj składnik udostępniony aplikacji jest umieszczany w folderze Components/Layout . Składnik używa HttpContext do określenia, czy przyjął statyczny SSR. Jeśli wartość HttpContext to null, składnik jest renderowany w sposób interaktywny, a pełne przeładowanie strony odbywa się przez wywołanie NavigationManager.Refresh z forceLoad ustawionym na true. Powoduje to wysłanie żądania do serwera w celu uzyskania składnika.

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

W składniku App odbicie służy do ustawiania trybu renderowania. Tryb renderowania przypisany do pojedynczego pliku definicji składnika jest stosowany do składnika Routes.

Components/App.razor:

<Routes @rendermode="RenderModeForPage" />

...

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

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

Każdy komponent, który musi przyjąć statyczne renderowanie po stronie serwera (SSR), ustawia własny układ i nie określa trybu renderowania. Nieokreślenie trybu renderowania powoduje, że wartość null w składniku RenderModeAttribute.Mode wynosi App, co skutkuje brakiem przypisania trybu renderowania do wystąpienia składnika Routes i wymuszeniem statycznego SSR.

Ważne

Ustawienie trybu renderowania null nie zawsze wymusza statyczne SSR. Dzieje się tak po prostu przy użyciu podejścia pokazanego w tej sekcji.

null Tryb renderowania jest w rzeczywistości taki sam, jak nieokreślenie trybu renderowania, co sprawia, że składnik dziedziczy tryb renderowania od swojego elementu nadrzędnego. W takim przypadku składnik App jest renderowany przy użyciu statycznego SSR, więc tryb renderowania null powoduje, że składnik Routes dziedziczy statyczny SSR ze składnika App. Jeśli dla składnika podrzędnego został określony tryb renderowania o wartości null, a jego element nadrzędny używa trybu renderowania interakcyjnego, to element podrzędny dziedziczy tryb renderowania interakcyjnego.

Nie należy wykonywać żadnych dalszych czynności, aby składniki wymuszały statyczny protokół SSR niż stosowanie układu niestandardowego bez ustawiania interaktywnego trybu renderowania:

@layout BlazorSample.Components.Layout.StaticSsrLayout

Składniki interakcyjne wokół aplikacji unikają stosowania niestandardowego układu statycznego SSR i ustawiają tylko odpowiedni interaktywny tryb renderowania, który po odbiciu w App składniku Routes jest stosowany do składnika:

@rendermode {INTERACTIVE RENDER MODE}

W poprzednim kodzie zmień {INTERACTIVE RENDER MODE} symbol zastępczy na odpowiednią wartość, w zależności od tego, czy fragment powinien przyjąć InteractiveServer, InteractiveWebAssembly lub InteractiveAuto renderowanie.

Nie można rozpoznać usług po stronie klienta podczas wstępnego renderowania

Zakładając, że prerendering nie jest wyłączony dla składnika lub aplikacji, składnik w projekcie .Client jest prerenderowany na serwerze. Ponieważ serwer nie ma dostępu do zarejestrowanych usług po stronie Blazor klienta, nie można wstrzyknąć tych usług do składnika bez otrzymania błędu wskazującego na niemożność odnalezienia usługi podczas prerenderowania.

Na przykład, rozważmy następujący Home składnik w projekcie .Client w ramach Blazor Web App z globalnym interaktywnym WebAssembly lub automatycznym interaktywnym renderowaniem. Składnik próbuje wstrzyknąć IWebAssemblyHostEnvironment, aby uzyskać nazwę środowiska.

@page "/"
@inject IWebAssemblyHostEnvironment Environment

<PageTitle>Home</PageTitle>

<h1>Home</h1>

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

Podczas prerenderingu nie występuje błąd czasu kompilacji, ale występuje błąd środowiska uruchomieniowego:

Nie można podać wartości właściwości "Environment" dla typu "BlazorSample.Client.Pages".Home Nie ma zarejestrowanej usługi typu "Microsoft.AspNetCore.Components.WebAssembly.Hosting.IWebAssemblyHostEnvironment".

Ten błąd występuje, ponieważ składnik musi kompilować i wykonywać na serwerze podczas prerenderingu, ale IWebAssemblyHostEnvironment nie jest zarejestrowaną usługą na serwerze.

Jeśli aplikacja nie wymaga wartości podczas prerenderingu, ten problem można rozwiązać przez wstrzyknięcie IServiceProvider w celu uzyskania usługi zamiast samego typu usługi:

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

Jednakże przedstawione wcześniej podejście nie jest użyteczne, jeśli logika wymaga wartości podczas prerenderingu.

Można również uniknąć problemu, jeśli wyłączysz prerendering dla składnika, ale jest to skrajna miara do podjęcia w wielu przypadkach, które mogą nie spełniać specyfikacji składnika.

Istnieją trzy podejścia, które można zastosować, aby rozwiązać ten scenariusz. Poniżej przedstawiono od najbardziej zalecanych do najmniej zalecanych:

  • Zalecane w przypadku usług współużytkowanej platformy: w przypadku usług platformy, które nie są zarejestrowane po stronie serwera w głównym projekcie, zarejestruj usługi w głównym projekcie, aby były dostępne podczas prerenderingu. Aby zapoznać się z przykładem tego scenariusza, zobacz wskazówki dotyczące usług w kontekście aplikacji ASP.NET Core korzystających z interfejsu API sieci Web.

  • Zalecane w przypadku usług spoza platformy udostępnionej: utwórz niestandardową implementację usługi dla usługi na serwerze. Korzystaj z usługi normalnie w interaktywnych składnikach projektu .Client. Aby zapoznać się z demonstracją tego podejścia, zobacz Blazor.

  • Utwórz abstrakcję usługi i utwórz implementacje dla usługi w projekcie .Client i projektach serwera. Zarejestruj usługi w każdym projekcie. Wstrzyknij usługę niestandardową do składnika.

  • Może być możliwe dodanie .Client odwołania do pakietu projektu do pakietu po stronie serwera i powrót do korzystania z interfejsu API po stronie serwera podczas prerenderingu na serwerze.

Odkrywanie elementów z dodatkowych zestawów

Dodatkowe zestawy muszą zostać ujawnione ramom Blazor w celu odnalezienia składników routingu Razor w projektach, do których się odwołujesz. Aby uzyskać więcej informacji, zobacz ASP.NET Core Blazor trasowanie i nawigacja.

Zamykanie obwodów, gdy nie ma pozostałych składników programu Interactive Server

Składniki interaktywnego serwera obsługują zdarzenia internetowego interfejsu użytkownika przy użyciu połączenia w czasie rzeczywistym z przeglądarką, które nazywane jest obwodem. Obwód i skojarzony z nim stan są tworzone, gdy renderowany jest główny komponent Serwera Interaktywnego. Obwód jest zamykany, gdy na stronie nie ma żadnych pozostałych komponentów serwera interakcyjnego, co uwalnia zasoby serwera.

Niestandardowe skrócone tryby renderowania

Dyrektywa @rendermode przyjmuje pojedynczy parametr, który jest statycznym wystąpieniem typu IComponentRenderMode. Atrybut @rendermode dyrektywy może przyjmować dowolne wystąpienie trybu renderowania, statyczne lub nie. Platforma Blazor udostępnia klasę RenderMode statyczną z niektórymi wstępnie zdefiniowanymi trybami renderowania dla wygody, ale możesz utworzyć własne.

Zwykle składnik używa następującej @rendermode dyrektywy w celu wyłączenia prerenderowania

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

Rozważmy jednak poniższy przykład, który tworzy skrócony interaktywny tryb renderowania po stronie serwera bez prerenderowania poprzez plik aplikacji _Imports (Components/_Imports.razor):

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

Użyj trybu renderowania skróconego w składnikach w folderze Components :

@rendermode InteractiveServerWithoutPrerendering

Alternatywnie pojedyncze wystąpienie składnika może zdefiniować niestandardowy tryb renderowania za pomocą pola prywatnego:

@rendermode interactiveServerWithoutPrerendering

...

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

W tej chwili podejście w trybie renderowania skrótowego jest prawdopodobnie przydatne tylko w przypadku zmniejszenia zwięzłości ustawiania flagi prerender. Podejście skrócone może być bardziej przydatne w przyszłości, jeśli dodatkowe flagi staną się dostępne do renderowania interakcyjnego i chcesz utworzyć tryby renderowania skróconego z różnymi kombinacjami flag.

Wstrzykiwanie usługi za pośrednictwem pliku importów najwyższego poziomu (_Imports.razor)

Ta sekcja dotyczy tylko Blazor Web Apps.

Plik importujący najwyższego poziomu w folderze Components (Components/_Imports.razor) wprowadza odwołania do wszystkich elementów w hierarchii folderów, co obejmuje także element App (App.razor). Składnik App jest zawsze renderowany statycznie, nawet jeśli prerendering składnika strony jest wyłączony. W związku z tym wstrzyknięcie usług za pośrednictwem pliku importowego najwyższego poziomu powoduje utworzenie dwóch wystąpień usługi w składnikach strony.

Aby rozwiązać ten scenariusz, należy wstrzyknąć usługę w nowym pliku importu umieszczonym w folderze Pages (Components/Pages/_Imports.razor). Z tej lokalizacji usługa jest rozwiązana tylko raz w elementach strony.

Dodatkowe zasoby