Megosztás a következőn keresztül:


ASP.NET Core-összetevők Razor integrálása MVC-vel vagy Razor Pages lapokkal üzemeltetett Blazor WebAssembly megoldásokban

Megjegyzés

A üzemeltetett Blazor WebAssembly megoldások továbbra is támogatottak maradnak, de a projektsablon el lett távolítva, és a .NET 8-as vagy újabb verziójában már nem támogatott. Ez a cikk hivatkozásként a .NET 7-es verzióig jelenik meg a tartalomjegyzékben, de vegye figyelembe, hogy a .NET 7 egy Standard Támogatási Verzió, amely már nem támogatott.

Figyelmeztetés

A ASP.NET Core ezen verziója már nem támogatott. További információ: .NET és .NET Core támogatási szabályzat.

Ez a cikk az üzemeltetett Razor alkalmazások összetevőintegrációs forgatókönyveit ismertetiBlazor WebAssembly, beleértve a kiszolgálón lévő összetevők előzetes rendszerezését Razor is.

Fontos

A keretrendszer ASP.NET Core-kiadásokra vonatkozó változásai a jelen cikkben szereplő utasítások különböző készleteihez vezettek. A cikk útmutatásának használata előtt győződjön meg arról, hogy a jelen cikk tetején található dokumentumverzió-választó megegyezik ASP.NET Core alkalmazáshoz használni kívánt verziójával.

Az előzetes rendezés javíthatja a keresőmotor-optimalizálást (SEO) azáltal, hogy megjeleníti a kezdeti HTTP-válasz tartalmát, amellyel a keresőmotorok kiszámíthatják az oldal rangját.

Megoldáskonfiguráció

Előrenderelés konfigurációja

Előrerenderelés beállítása hostolt Blazor WebAssembly alkalmazáshoz:

  1. Blazor WebAssembly Az alkalmazást egy ASP.NET Core-alkalmazásban üzemelteti. Egy önálló Blazor WebAssembly alkalmazás hozzáadható egy ASP.NET Core megoldáshoz, vagy használhat egy Blazor WebAssembly létrehozott üzemeltetett Blazor WebAssembly alkalmazást az üzemeltetett opció használatával.

    • Visual Studio: A További információk párbeszédpanelen jelölje be a ASP.NET Központi üzemeltetésű jelölőnégyzetet az Blazor WebAssembly alkalmazás létrehozásakor. A jelen cikk példáiban a megoldás neve BlazorHosted.
    • Visual Studio Code/.NET CLI parancssori felület: dotnet new blazorwasm -ho (használja a -ho|--hosted lehetőséget). Ezzel a -o|--output {LOCATION} beállítással létrehozhat egy mappát a megoldáshoz, és beállíthatja a megoldás projektnévtereit. A cikk példáiban a megoldás neve BlazorHosted (dotnet new blazorwasm -ho -o BlazorHosted).

    A cikkben szereplő példák esetében az üzemeltetett megoldás neve (szerelvény neve) a következő BlazorHosted: . Az ügyfélprojekt névtere a BlazorHosted.Clientkiszolgálóprojekt névtere BlazorHosted.Server.

  2. Törölje a wwwroot/index.html fájlt a Blazor WebAssemblyClient projektből.

  3. A Client projektben a következő sorokat törölje a fájlban:

    - builder.RootComponents.Add<App>("#app");
    - builder.RootComponents.Add<HeadOutlet>("head::after");
    
  4. Adja hozzá a _Host.cshtml fájlt a Server mappába a Pages projektben. A fájlokat egy sablonból létrehozott projektből szerezheti be a Blazor Server Visual Studióval, vagy a .NET CLI-vel a dotnet new blazorserver -o BlazorServer parancshéjban található paranccsal (a -o BlazorServer beállítás létrehoz egy mappát a projekthez). Miután elhelyezte a fájlokat a Server projekt mappájába Pages , végezze el a következő módosításokat a fájlokon.

    Végezze el a következő módosításokat a _Host.cshtml fájlon:

    • Frissítse a Pages fájl tetején lévő névteret, hogy megfeleljen az Server alkalmazás lapjainak névterének. A {APP NAMESPACE} következő példában szereplő helyőrző a donoralkalmazás azon lapjainak névterét jelöli, amelyek a _Host.cshtml fájlt adták:

      Eltávolítás:

      - @namespace {APP NAMESPACE}.Pages
      

      Hozzáad:

      @namespace BlazorHosted.Server.Pages
      
    • Adjon hozzá egy direktívát @using a Client projekthez a fájl tetején:

      @using BlazorHosted.Client
      
    • Frissítse a stíluslap hivatkozásait, hogy a WebAssembly projekt stíluslapjaira mutasson. Az alábbi példában az ügyfélprojekt névtere a következő BlazorHosted.Client: . A {APP NAMESPACE} helyőrző a _Host.cshtml fájlt biztosító donor alkalmazás névterét jelöli. Frissítse az <component> összetevőcímke-segéd (HeadOutlet címke) beállításait az összetevő előrendereléséhez.

      Eltávolítás:

      - <link href="css/site.css" rel="stylesheet" />
      - <link href="{APP NAMESPACE}.styles.css" rel="stylesheet" />
      - <component type="typeof(HeadOutlet)" render-mode="ServerPrerendered" />
      

      Hozzáad:

      <link href="css/app.css" rel="stylesheet" />
      <link href="BlazorHosted.Client.styles.css" rel="stylesheet" />
      <component type="typeof(HeadOutlet)" render-mode="WebAssemblyPrerendered" />
      

      Megjegyzés

      Hagyja helyben a <link> Bootstrap stíluslapot (css/bootstrap/bootstrap.min.css) kérő elemet.

    • Frissítse a Blazor szkript forrását, hogy az ügyféloldali Blazor WebAssembly szkriptet használja:

      Eltávolítás:

      - <script src="_framework/blazor.server.js"></script>
      

      Hozzáad:

      <script src="_framework/blazor.webassembly.js"></script>
      
    • Frissítse a render-modeKomponenscímke segédprogramot , hogy a gyökérösszetevőt App előrerendelje a következővel WebAssemblyPrerendered:

      Eltávolítás:

      - <component type="typeof(App)" render-mode="ServerPrerendered" />
      

      Hozzáad:

      <component type="typeof(App)" render-mode="WebAssemblyPrerendered" />
      

      Fontos

      A hitelesítési végpontok (/authentication/ elérési utak szegmense) esetében az előrendelés nem támogatott. További információ: ASP.NET Core Blazor WebAssembly további biztonsági forgatókönyvek.

  5. A Program.cs projekt Server fájljában módosítsa a tartalék végpontot a index.html fájlról a _Host.cshtml lapra:

    Eltávolítás:

    - app.MapFallbackToFile("index.html");
    

    Hozzáad:

    app.MapFallbackToPage("/_Host");
    
  6. Ha a Client és a Server projektek egy vagy több közös szolgáltatást használnak az előrenderelés során, helyezze el a szolgáltatásregisztrációkat egy olyan eljárásba, amely mindkét projektből meghívható. További információért lásd a ASP.NET Core Blazor függőség-injektálás.

  7. Futtassa a Server projektet. A üzemeltetett Blazor WebAssembly alkalmazást a Server projekt előfeldolgozza az ügyfelek számára.

A Razor összetevők lapokba vagy nézetekbe való beágyazásának konfigurálása

A következő szakaszok és példák a(z) Razor összetevők ClientBlazor WebAssembly alkalmazásból a kiszolgálóalkalmazás lapjaiba vagy nézeteibe történő beágyazására további konfigurációt igényelnek.

A Server projektnek a következő fájlokkal és mappával kell rendelkeznie.

Razor Oldalak:

  • Pages/Shared/_Layout.cshtml
  • Pages/Shared/_Layout.cshtml.css
  • Pages/_ViewImports.cshtml
  • Pages/_ViewStart.cshtml

MVC:

  • Views/Shared/_Layout.cshtml
  • Views/Shared/_Layout.cshtml.css
  • Views/_ViewImports.cshtml
  • Views/_ViewStart.cshtml

Az előző fájlokat úgy szerezheti be, hogy létrehoz egy alkalmazást a ASP.NET Core-projektsablonokból a következő használatával:

  • A Visual Studio új projektlétrehozó eszközei.
  • Parancssor megnyitása és dotnet new webapp -o {PROJECT NAME} (Razor Pages) vagy dotnet new mvc -o {PROJECT NAME} (MVC) végrehajtása. A helyőrző értékével -o|--output rendelkező beállítás {PROJECT NAME} megadja az alkalmazás nevét, és létrehoz egy mappát az alkalmazás számára.

Frissítse az importált _ViewImports.cshtml fájl névtereit úgy, hogy azok megfeleljenek a Server fájlokat fogadó projekt által használt névtereknek.

Pages/_ViewImports.cshtml (Razor Oldalak):

@using BlazorHosted.Server
@namespace BlazorHosted.Server.Pages
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers

Views/_ViewImports.cshtml (MVC):

@using BlazorHosted.Server
@using BlazorHosted.Server.Models
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers

Frissítse az importált elrendezésfájlt, amely a Pages/Shared/_Layout.cshtml Pages vagy az Razor MVC számára Views/Shared/_Layout.cshtml készült.

Először törölje a címet és a stíluslapot a donorprojektből, amely az alábbi példában található RPDonor.styles.css . A {PROJECT NAME} helyőrző a donorprojekt alkalmazásnevét jelöli.

- <title>@ViewData["Title"] - {PROJECT NAME}</title>
- <link rel="stylesheet" href="~/RPDonor.styles.css" asp-append-version="true" />

Adja meg a Client projekt stílusát az elrendezésfájlban. Az alábbi példában a Client projekt névtere a következő BlazorHosted.Client: . Az <title> elem egyszerre frissíthető.

Helyezze a következő sorokat az <head> elrendezésfájl tartalmába:

<title>@ViewData["Title"] - BlazorHosted</title>
<link href="css/app.css" rel="stylesheet" />
<link rel="stylesheet" href="BlazorHosted.Client.styles.css" asp-append-version="true" />
<component type="typeof(HeadOutlet)" render-mode="WebAssemblyPrerendered" />

Az importált elrendezés két Home (Index oldal) és Privacy navigációs hivatkozást tartalmaz. Ahhoz, hogy a Home hivatkozások az üzemeltetett Blazor WebAssembly alkalmazásra mutassanak, változtassa meg a hivatkozásokat:

- <a class="navbar-brand" asp-area="" asp-page="/Index">{PROJECT NAME}</a>
+ <a class="navbar-brand" href="/">BlazorHosted</a>
- <a class="nav-link text-dark" asp-area="" asp-page="/Index">Home</a>
+ <a class="nav-link text-dark" href="/">Home</a>

MVC-elrendezésfájlban:

- <a class="navbar-brand" asp-area="" asp-controller="Home" 
-     asp-action="Index">{PROJECT NAME}</a>
+ <a class="navbar-brand" href="/">BlazorHosted</a>
- <a class="nav-link text-dark" asp-area="" asp-controller="Home" 
-     asp-action="Index">Home</a>
+ <a class="nav-link text-dark" href="/">Home</a>

Frissítse az <footer> elem alkalmazásnevét. Az alábbi példa az alkalmazás nevét BlazorHostedhasználja:

- &copy; {DATE} - {DONOR NAME} - <a asp-area="" asp-page="/Privacy">Privacy</a>
+ &copy; {DATE} - BlazorHosted - <a asp-area="" asp-page="/Privacy">Privacy</a>

Az előző példában a helyőrző a {DATE} Pages vagy az MVC projektsablonból Razor létrehozott alkalmazás szerzői jogi dátumát jelöli.

Ha azt szeretné, hogy a Privacy hivatkozás egy adatvédelmi laphoz (Razor Pages) vezessen, adjon hozzá egy adatvédelmi lapot a Server projekthez.

Pages/Privacy.cshtml a Server projektben:

@page
@model PrivacyModel
@{
    ViewData["Title"] = "Privacy Policy";
}
<h1>@ViewData["Title"]</h1>

<p>Use this page to detail your site's privacy policy.</p>

MVC-alapú adatvédelmi nézet esetén hozzon létre egy adatvédelmi nézetet a Server projektben.

View/Home/Privacy.cshtml a Server projektben:

@{
    ViewData["Title"] = "Privacy Policy";
}
<h1>@ViewData["Title"]</h1>

<p>Use this page to detail your site's privacy policy.</p>

Home Az MVC alkalmazás vezérlőjében adja vissza a nézetet.

Adja hozzá a következő kódot a Controllers/HomeController.cs:

public IActionResult Privacy()
{
    return View();
}

Ha donoralkalmazásból importál fájlokat, mindenképpen frissítse a fájlokban lévő névtereket úgy, Serverhogy azok megfeleljenek a BlazorHosted.Server projektnek (például).

Statikus eszközök importálása a Server projektbe a donor projekt mappájából wwwroot :

  • wwwroot/css mappa és tartalom
  • wwwroot/js mappa és tartalom
  • wwwroot/lib mappa és tartalom

Ha a donorprojekt egy ASP.NET Core-projektsablonból jön létre, és a fájlok nem módosulnak, a teljes wwwroot mappát átmásolhatja a donorprojektből a Server projektbe, és eltávolíthatja az favicon ikonfájlt.

Figyelmeztetés

Kerülje el, hogy a statikus objektumot mind a Client mappába, mind a Serverwwwroot mappákba helyezze. Ha ugyanaz a fájl mindkét mappában megtalálható, kivételt jelent, mert a statikus objektumok ugyanazon a webes gyökérútvonalon osztoznak. Ezért statikus objektumot kell üzemeltetni valamelyik wwwroot mappában, nem mindkettőben.

Az előző konfiguráció bevezetése után ágyazza be Razor az összetevőket a Server projekt lapjaiba vagy nézeteibe. Használja a cikk következő szakaszaiban található útmutatást:

  • Összetevők renderelése egy lapon vagy nézetben az Összetevőcímke súgójával
  • Összetevők renderelése egy lapon vagy nézetben CSS-választóval

Összetevők renderelése egy lapon vagy nézetben az Összetevőcímke súgójával

A megoldás konfigurálása után , beleértve a további konfigurációt is, a Komponenscímke segéd két renderelési módot támogat egy összetevő egy alkalmazásból Blazor WebAssembly való megjelenítéséhez egy lapon vagy nézetben:

A következő Razor Pages-példában az Counter összetevő egy lapon jelenik meg. Az összetevő interaktívvá tétele érdekében a Blazor WebAssembly szkript szerepel a lap renderelési szakaszában. Ha el szeretné kerülni, hogy az Counter összetevő teljes névterét használja a Komponenscímke segéd{ASSEMBLY NAME}.Pages.Counter () segítségével, adjon hozzá egy @using irányelvet az ügyfélprojekt névteréhezPages. Az alábbi példában a Client projekt névtere a következő BlazorHosted.Client: .

A Server projektben, Pages/RazorPagesCounter1.cshtml:

@page
@using BlazorHosted.Client.Pages

<component type="typeof(Counter)" render-mode="WebAssemblyPrerendered" />

@section Scripts {
    <script src="_framework/blazor.webassembly.js"></script>
}

Futtassa a Server projektet. Navigáljon a Razor oldalra a /razorpagescounter1 helyen. Az előre berendezett Counter összetevő beágyazva van a lapba.

RenderMode beállítja, hogy a komponens:

  • Előre le van renderelve az oldalra.
  • Statikus HTML-ként jelenik meg a lapon, vagy ha tartalmazza a szükséges információkat az alkalmazás indításához a felhasználói ügynöktől Blazor.

Az összetevőcímke-segédről , beleértve a paraméterek és RenderMode a konfiguráció átadását is, a ASP.NET Core összetevőcímke-segédjében talál további információt.

További munkára lehet szükség az összetevők által használt statikus erőforrásoktól és az elrendezési lapok alkalmazásbeli rendszerezésétől függően. A szkriptek általában egy lap vagy nézet renderelési szakaszához Scripts lesznek hozzáadva, a stíluslapok pedig hozzáadódnak az elrendezés elemtartalmaihoz <head> .

Gyermek tartalom beállítása renderelő fragmentumon keresztül

Az összetevőcímke-segédeszköz nem támogatja, hogy egy RenderFragment delegáltat fogadjon gyerektartalomhoz ( például param-ChildContent="..."). Javasoljuk, hogy hozzon létre egy Razor összetevőt (.razor), amely hivatkozik arra az összetevőre, amelyet meg szeretne jeleníteni a továbbítani kívánt gyermek tartalommal, majd hívja meg az Razor összetevőt az oldalból vagy nézetből.

Győződjön meg arról, hogy a legfelső szintű előrerendelt összetevők nincsenek kivágva a közzétételkor

Ha egy összetevőcímke-segéd közvetlenül hivatkozik egy olyan erőforrástárból származó összetevőre, amelyre a közzétételkor vágás vonatkozik, előfordulhat, hogy az összetevőt a közzététel során levágják, mert az ügyféloldali alkalmazáskódból nincsenek rá mutató hivatkozások. Ennek eredményeképpen az összetevő nincs előrerendezve, így üres helyet hagy a kimenetben. Ha ez történik, utasítsa a trimmerrel, hogy őrizze meg a könyvtárkomponenst úgy, hogy egy DynamicDependency attribútumot ad hozzá az ügyféloldali alkalmazás bármely osztályához. Egy SomeLibraryComponentToBePreserved nevű összetevő megőrzéséhez adja hozzá a következőket bármelyik összetevőhöz:

@using System.Diagnostics.CodeAnalysis
@attribute [DynamicDependency(DynamicallyAccessedMemberTypes.All, 
    typeof(SomeLibraryComponentToBePreserved))]

Az előző megközelítés általában nem szükséges, mert az alkalmazás általában előrerendeli az összetevőit (amelyek nincsenek levágva), ami viszont a kódtárak összetevőire hivatkozik (ami miatt azokat sem kell levágni). Csak akkor használja a DynamicDependency elemet explicit módon egy könyvtárkomponens előfeldolgozására közvetlenül, ha a könyvtár vágás alá esik.

Összetevők renderelése egy lapon vagy nézetben CSS-választóval

Miután konfigurálta a megoldást, beleértve a további konfigurációt, adjon hozzá gyökérösszetevőket a Client fájlban Blazor WebAssembly található üzemeltetett Program.cs megoldás projektéhez. Az alábbi példában az Counter összetevő gyökérkomponensként van deklarálva, egy CSS-választóval, amely az id elemet választja ki, amely megfelel a counter-component feltételnek. Az alábbi példában a Client projekt névtere a következő BlazorHosted.Client: .

A Program.cs projekt fájljának Client részéhez adja hozzá a projekt Razor összetevőinek névterét a fájl elejére.

using BlazorHosted.Client.Pages;

Miután a builder létrejött a Program.cs-ben, adja hozzá az Counter komponenset gyökérkomponensként.

builder.RootComponents.Add<Counter>("#counter-component");

A következő Razor Pages-példában az Counter összetevő egy lapon jelenik meg. Az összetevő interaktívvá tétele érdekében a Blazor WebAssembly szkript szerepel a lap renderelési szakaszában.

A Server projektben, Pages/RazorPagesCounter2.cshtml:

@page

<div id="counter-component">Loading...</div>

@section Scripts {
    <script src="_framework/blazor.webassembly.js"></script>
}

Futtassa a Server projektet. Navigáljon a Razor oldalra a /razorpagescounter2 helyen. Az előre berendezett Counter összetevő beágyazva van a lapba.

További munkára lehet szükség az összetevők által használt statikus erőforrásoktól és az elrendezési lapok alkalmazásbeli rendszerezésétől függően. A szkriptek általában egy lap vagy nézet renderelési szakaszához Scripts lesznek hozzáadva, a stíluslapok pedig hozzáadódnak az elrendezés elemtartalmaihoz <head> .

Megjegyzés

Az előző példa JSException dob, ha egy Blazor WebAssembly alkalmazás előre van renderelve, és egy Pages vagy MVC alkalmazásba van integrálva Razor, a CSS-választó használatával. Amikor a Client projekt valamelyik összetevőjére navigál Razor, vagy beágyazott összetevővel rendelkező oldalra vagy nézetre navigál Server, az egy vagy több JSException okozhat.

Ez normális viselkedés, mert egy Blazor WebAssembly alkalmazás előrerenderése és útvonalazható Razor összetevőkkel való integrálása nem kompatibilis a CSS-választók használatával.

Ha az előző szakaszokban szereplő példákkal dolgozott, és csak azt szeretné látni, hogy a CSS-választó működik a mintaalkalmazásban, tegye megjegyzésbe a AppClient projekt fájljának fő összetevőjének specifikációját Program.cs :

- builder.RootComponents.Add<App>("#app");
+ //builder.RootComponents.Add<App>("#app");

Navigáljon a CSS-választót használó beágyazott Razor összetevővel (például /razorpagescounter2 az előző példával) rendelkező lapra vagy nézetre. A lap vagy a nézet betöltődik a beágyazott összetevővel, és a beágyazott összetevő a várt módon működik.

Előre beállított állapot megőrzése

Az előre beállított állapot megőrzése nélkül az előrendelés során használt állapot elveszik, és újra létre kell hozni az alkalmazás teljes betöltésekor. Ha bármely állapot aszinkron módon van beállítva, a felhasználói felület villanhat, mivel az előre renderelt felhasználói felületet ideiglenesen helyőrző elemek váltják fel, majd újra teljesen renderelődik.

Az előre összeállított összetevők állapotának megőrzéséhez használja a Komponensállapot-címke megőrzése segédet (referenciaforrás). Adja hozzá a Tag Helper címkéjét <persist-component-state /> a lap záró </body> címkéjébe a _Host oldalon, egy olyan alkalmazásban, amely előrendereli a komponenseket.

Megjegyzés

A .NET referenciaforrásra mutató dokumentációs hivatkozások általában betöltik az adattár alapértelmezett ágát, amely a .NET következő kiadásának aktuális fejlesztését jelöli. Egy adott kiadás címkéjének kiválasztásához használja az Ágak vagy címkék közötti váltás legördülő listát. További információ: A ASP.NET Core-forráskód (dotnet/AspNetCore.Docs #26205) verziócímkéjének kiválasztása.

A Pages/_Host.cshtml alkalmazások közül azokban, amelyek WebAssembly-vel vannak előre renderelve (Blazor), egy üzemeltetett WebAssemblyPrerendered alkalmazásban:

<body>
    ...

    <persist-component-state />
</body>

Döntse el, hogy melyik állapotot kívánja megőrizni a PersistentComponentState szolgáltatással. PersistentComponentState.RegisterOnPersisting regisztrál egy visszahívást az összetevő állapotának megőrzéséhez az alkalmazás szüneteltetése előtt. A rendszer az alkalmazás folytatásakor kéri le az állapotot. Az inicializálási kód végén hajtsa végre a hívást, hogy elkerülje a lehetséges versenyhelyzetet az alkalmazás leállítása során.

Az alábbi példában:

  • A {TYPE} helyőrző a megőrizendő adatok típusát jelöli (például WeatherForecast[]).
  • A {TOKEN} helyőrző egy állapotazonosító sztring (például fetchdata).
@implements IDisposable
@inject PersistentComponentState ApplicationState

...

@code {
    private {TYPE} data;
    private PersistingComponentStateSubscription persistingSubscription;

    protected override async Task OnInitializedAsync()
    {
        if (!ApplicationState.TryTakeFromJson<{TYPE}>(
            "{TOKEN}", out var restored))
        {
            data = await ...;
        }
        else
        {
            data = restored!;
        }

        // Call at the end to avoid a potential race condition at app shutdown
        persistingSubscription = ApplicationState.RegisterOnPersisting(PersistData);
    }

    private Task PersistData()
    {
        ApplicationState.PersistAsJson("{TOKEN}", data);

        return Task.CompletedTask;
    }

    void IDisposable.Dispose()
    {
        persistingSubscription.Dispose();
    }
}

Az alábbi példa egy FetchData üzemeltetett Blazor WebAssembly alkalmazás összetevőjének frissített verziója a Blazor projektsablon alapján. Az WeatherForecastPreserveState összetevő megőrzi az időjárás-előrejelzés állapotát az előrendelés során, majd lekéri az állapotot az összetevő inicializálásához. A Komponensállapotot megőrző tag asszisztens az összes összetevő-meghívás után is megőrzi az összetevő állapotát.

Pages/WeatherForecastPreserveState.razor:

@page "/weather-forecast-preserve-state"
@using BlazorSample.Shared
@implements IDisposable
@inject IWeatherForecastService WeatherForecastService
@inject PersistentComponentState ApplicationState

<PageTitle>Weather Forecast</PageTitle>

<h1>Weather forecast</h1>

<p>This component demonstrates fetching data from the server.</p>

@if (forecasts == null)
{
    <p><em>Loading...</em></p>
}
else
{
    <table class="table">
        <thead>
            <tr>
                <th>Date</th>
                <th>Temp. (C)</th>
                <th>Temp. (F)</th>
                <th>Summary</th>
            </tr>
        </thead>
        <tbody>
            @foreach (var forecast in forecasts)
            {
                <tr>
                    <td>@forecast.Date.ToShortDateString()</td>
                    <td>@forecast.TemperatureC</td>
                    <td>@forecast.TemperatureF</td>
                    <td>@forecast.Summary</td>
                </tr>
            }
        </tbody>
    </table>
}

@code {
    private WeatherForecast[] forecasts = Array.Empty<WeatherForecast>();
    private PersistingComponentStateSubscription persistingSubscription;

    protected override async Task OnInitializedAsync()
    {
        if (!ApplicationState.TryTakeFromJson<WeatherForecast[]>(
            nameof(forecasts), out var restored))
        {
            forecasts = await WeatherForecastService.GetForecastAsync(
                DateOnly.FromDateTime(DateTime.Now));
        }
        else
        {
            forecasts = restored!;
        }

        // Call at the end to avoid a potential race condition at app shutdown
        persistingSubscription = ApplicationState.RegisterOnPersisting(PersistData);
    }

    private Task PersistData()
    {
        ApplicationState.PersistAsJson(nameof(forecasts), forecasts);

        return Task.CompletedTask;
    }

    void IDisposable.Dispose()
    {
        persistingSubscription.Dispose();
    }
}

Az előrendelés során használt azonos állapotú összetevők inicializálásával a költséges inicializálási lépések csak egyszer lesznek végrehajtva. A renderelt felhasználói felület megegyezik az előre beállított felhasználói felülettel, így a böngészőben nem történik villódzás.

A rendszer átviszi a megőrzött előrerendelt állapotot az ügyfélnek, ahol az összetevő állapotának visszaállítására szolgál. Egy üzemeltetett Blazor WebAssembly alkalmazásban történő előzetes rendezéshez az adatok a böngészőben lesznek közzétéve, és nem tartalmazhatnak bizalmas, személyes adatokat.

További Blazor WebAssembly erőforrások

Az előzetes rendezés javíthatja a keresőmotor-optimalizálást (SEO) azáltal, hogy megjeleníti a kezdeti HTTP-válasz tartalmát, amellyel a keresőmotorok kiszámíthatják az oldal rangját.

Megoldáskonfiguráció

Előrenderelés konfigurációja

Előrerenderelés beállítása hostolt Blazor WebAssembly alkalmazáshoz:

  1. Blazor WebAssembly Az alkalmazást egy ASP.NET Core-alkalmazásban üzemelteti. Egy önálló Blazor WebAssembly alkalmazás hozzáadható egy ASP.NET Core megoldáshoz, vagy használhat egy Blazor WebAssembly létrehozott üzemeltetett Blazor WebAssembly alkalmazást az üzemeltetett opció használatával.

    • Visual Studio: A További információk párbeszédpanelen jelölje be a ASP.NET Központi üzemeltetésű jelölőnégyzetet az Blazor WebAssembly alkalmazás létrehozásakor. A jelen cikk példáiban a megoldás neve BlazorHosted.
    • Visual Studio Code/.NET CLI parancssori felület: dotnet new blazorwasm -ho (használja a -ho|--hosted lehetőséget). Ezzel a -o|--output {LOCATION} beállítással létrehozhat egy mappát a megoldáshoz, és beállíthatja a megoldás projektnévtereit. A cikk példáiban a megoldás neve BlazorHosted (dotnet new blazorwasm -ho -o BlazorHosted).

    A cikkben szereplő példák esetében az ügyfélprojekt névtere a BlazorHosted.Client, és a kiszolgálóprojekt névtere a BlazorHosted.Server.

  2. Törölje a wwwroot/index.html fájlt a Blazor WebAssemblyClient projektből.

  3. A Client projektben a következő sorokat törölje a fájlban:

    - builder.RootComponents.Add<App>("#app");
    - builder.RootComponents.Add<HeadOutlet>("head::after");
    
  4. A _Host.cshtml és _Layout.cshtml fájlok hozzáadása a Server projekt Pages mappájába. A fájlokat egy sablonból létrehozott projektből szerezheti be a Blazor Server Visual Studióval, vagy a .NET CLI-vel a dotnet new blazorserver -o BlazorServer parancshéjban található paranccsal (a -o BlazorServer beállítás létrehoz egy mappát a projekthez). Miután elhelyezte a fájlokat a Server projekt mappájába Pages , végezze el a következő módosításokat a fájlokon.

    Fontos

    A _Layout.cshtml komponensnél szükséges egy elrendezési oldal () és egy HeadOutlet használata a <head> tartalom szabályozásához, például a lap címének (PageTitle komponens) és egyéb fejelemeinek (HeadContent komponens) kezeléséhez. További információ: Vezérlőfej tartalma ASP.NET Core-alkalmazásokbanBlazor.

    Végezze el a következő módosításokat a _Layout.cshtml fájlon:

    • Frissítse a Pages fájl tetején lévő névteret, hogy megfeleljen az Server alkalmazás lapjainak névterének. A {APP NAMESPACE} következő példában szereplő helyőrző a donoralkalmazás azon lapjainak névterét jelöli, amelyek a _Layout.cshtml fájlt adták:

      Eltávolítás:

      - @namespace {APP NAMESPACE}.Pages
      

      Hozzáad:

      @namespace BlazorHosted.Server.Pages
      
    • Adjon hozzá egy direktívát @using a Client projekthez a fájl tetején:

      @using BlazorHosted.Client
      
    • Frissítse a stíluslap hivatkozásait, hogy a WebAssembly projekt stíluslapjaira mutasson. Az alábbi példában az ügyfélprojekt névtere a következő BlazorHosted.Client: . A {APP NAMESPACE} helyőrző a _Layout.cshtml fájlt biztosító donor alkalmazás névterét jelöli. Frissítse az <component> összetevőcímke-segéd (HeadOutlet címke) beállításait az összetevő előrendereléséhez.

      Eltávolítás:

      - <link href="css/site.css" rel="stylesheet" />
      - <link href="{APP NAMESPACE}.styles.css" rel="stylesheet" />
      - <component type="typeof(HeadOutlet)" render-mode="ServerPrerendered" />
      

      Hozzáad:

      <link href="css/app.css" rel="stylesheet" />
      <link href="BlazorHosted.Client.styles.css" rel="stylesheet" />
      <component type="typeof(HeadOutlet)" render-mode="WebAssemblyPrerendered" />
      

      Megjegyzés

      Hagyja helyben a <link> Bootstrap stíluslapot (css/bootstrap/bootstrap.min.css) kérő elemet.

    • Frissítse a Blazor szkript forrását, hogy az ügyféloldali Blazor WebAssembly szkriptet használja:

      Eltávolítás:

      - <script src="_framework/blazor.server.js"></script>
      

      Hozzáad:

      <script src="_framework/blazor.webassembly.js"></script>
      

    A _Host.cshtml fájlban:

    • Módosítsa a Pages névteret a Client projekt névterére. A {APP NAMESPACE} helyőrző a donoralkalmazás azon lapjainak névterét jelöli, amelyek a _Host.cshtml fájlt adták:

      Eltávolítás:

      - @namespace {APP NAMESPACE}.Pages
      

      Hozzáad:

      @namespace BlazorHosted.Client
      
    • Frissítse a render-modeKomponenscímke segédprogramot , hogy a gyökérösszetevőt App előrerendelje a következővel WebAssemblyPrerendered:

      Eltávolítás:

      - <component type="typeof(App)" render-mode="ServerPrerendered" />
      

      Hozzáad:

      <component type="typeof(App)" render-mode="WebAssemblyPrerendered" />
      

      Fontos

      A hitelesítési végpontok (/authentication/ elérési utak szegmense) esetében az előrendelés nem támogatott. További információ: ASP.NET Core Blazor WebAssembly további biztonsági forgatókönyvek.

  5. A Server projekt Program.cs végpontleképezésében változtassa meg a tartalékot a index.html fájlról a _Host.cshtml lapra.

    Eltávolítás:

    - app.MapFallbackToFile("index.html");
    

    Hozzáad:

    app.MapFallbackToPage("/_Host");
    
  6. Ha a Client és a Server projektek egy vagy több közös szolgáltatást használnak az előrenderelés során, helyezze el a szolgáltatásregisztrációkat egy olyan eljárásba, amely mindkét projektből meghívható. További információért lásd a ASP.NET Core Blazor függőség-injektálás.

  7. Futtassa a Server projektet. A üzemeltetett Blazor WebAssembly alkalmazást a Server projekt előfeldolgozza az ügyfelek számára.

A Razor összetevők lapokba vagy nézetekbe való beágyazásának konfigurálása

A következő szakaszok és példák a(z) Razor összetevők ClientBlazor WebAssembly alkalmazásból a kiszolgálóalkalmazás lapjaiba vagy nézeteibe történő beágyazására további konfigurációt igényelnek.

A Server projektnek a következő fájlokkal és mappával kell rendelkeznie.

Razor Oldalak:

  • Pages/Shared/_Layout.cshtml
  • Pages/Shared/_Layout.cshtml.css
  • Pages/_ViewImports.cshtml
  • Pages/_ViewStart.cshtml

MVC:

  • Views/Shared/_Layout.cshtml
  • Views/Shared/_Layout.cshtml.css
  • Views/_ViewImports.cshtml
  • Views/_ViewStart.cshtml

Fontos

A _Layout.cshtml komponensnél szükséges egy elrendezési oldal () és egy HeadOutlet használata a <head> tartalom szabályozásához, például a lap címének (PageTitle komponens) és egyéb fejelemeinek (HeadContent komponens) kezeléséhez. További információ: Vezérlőfej tartalma ASP.NET Core-alkalmazásokbanBlazor.

Az előző fájlokat úgy szerezheti be, hogy létrehoz egy alkalmazást a ASP.NET Core-projektsablonokból a következő használatával:

  • A Visual Studio új projektlétrehozó eszközei.
  • Parancssor megnyitása és dotnet new webapp -o {PROJECT NAME} (Razor Pages) vagy dotnet new mvc -o {PROJECT NAME} (MVC) végrehajtása. A helyőrző értékével -o|--output rendelkező beállítás {PROJECT NAME} megadja az alkalmazás nevét, és létrehoz egy mappát az alkalmazás számára.

Frissítse az importált _ViewImports.cshtml fájl névtereit úgy, hogy azok megfeleljenek a Server fájlokat fogadó projekt által használt névtereknek.

Pages/_ViewImports.cshtml (Razor Oldalak):

@using BlazorHosted.Server
@namespace BlazorHosted.Server.Pages
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers

Views/_ViewImports.cshtml (MVC):

@using BlazorHosted.Server
@using BlazorHosted.Server.Models
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers

Frissítse az importált elrendezésfájlt, amely a Pages/Shared/_Layout.cshtml Pages vagy az Razor MVC számára Views/Shared/_Layout.cshtml készült.

Először törölje a címet és a stíluslapot a donorprojektből, amely az alábbi példában található RPDonor.styles.css . A {PROJECT NAME} helyőrző a donorprojekt alkalmazásnevét jelöli.

- <title>@ViewData["Title"] - {PROJECT NAME}</title>
- <link rel="stylesheet" href="~/RPDonor.styles.css" asp-append-version="true" />

Adja meg a Client projekt stílusát az elrendezésfájlban. Az alábbi példában a Client projekt névtere a következő BlazorHosted.Client: . Az <title> elem egyszerre frissíthető.

Helyezze a következő sorokat az <head> elrendezésfájl tartalmába:

<title>@ViewData["Title"] - BlazorHosted</title>
<link href="css/app.css" rel="stylesheet" />
<link rel="stylesheet" href="BlazorHosted.Client.styles.css" asp-append-version="true" />
<component type="typeof(HeadOutlet)" render-mode="WebAssemblyPrerendered" />

Az importált elrendezés két Home (Index oldal) és Privacy navigációs hivatkozást tartalmaz. Ahhoz, hogy a Home hivatkozások az üzemeltetett Blazor WebAssembly alkalmazásra mutassanak, változtassa meg a hivatkozásokat:

- <a class="navbar-brand" asp-area="" asp-page="/Index">{PROJECT NAME}</a>
+ <a class="navbar-brand" href="/">BlazorHosted</a>
- <a class="nav-link text-dark" asp-area="" asp-page="/Index">Home</a>
+ <a class="nav-link text-dark" href="/">Home</a>

MVC-elrendezésfájlban:

- <a class="navbar-brand" asp-area="" asp-controller="Home" 
-     asp-action="Index">{PROJECT NAME}</a>
+ <a class="navbar-brand" href="/">BlazorHosted</a>
- <a class="nav-link text-dark" asp-area="" asp-controller="Home" 
-     asp-action="Index">Home</a>
+ <a class="nav-link text-dark" href="/">Home</a>

Frissítse az <footer> elem alkalmazásnevét. Az alábbi példa az alkalmazás nevét BlazorHostedhasználja:

- &copy; {DATE} - {DONOR NAME} - <a asp-area="" asp-page="/Privacy">Privacy</a>
+ &copy; {DATE} - BlazorHosted - <a asp-area="" asp-page="/Privacy">Privacy</a>

Az előző példában a helyőrző a {DATE} Pages vagy az MVC projektsablonból Razor létrehozott alkalmazás szerzői jogi dátumát jelöli.

Ha azt szeretné, hogy a Privacy hivatkozás egy adatvédelmi laphoz (Razor Pages) vezessen, adjon hozzá egy adatvédelmi lapot a Server projekthez.

Pages/Privacy.cshtml a Server projektben:

@page
@model PrivacyModel
@{
    ViewData["Title"] = "Privacy Policy";
}
<h1>@ViewData["Title"]</h1>

<p>Use this page to detail your site's privacy policy.</p>

MVC-alapú adatvédelmi nézet esetén hozzon létre egy adatvédelmi nézetet a Server projektben.

View/Home/Privacy.cshtml a Server projektben:

@{
    ViewData["Title"] = "Privacy Policy";
}
<h1>@ViewData["Title"]</h1>

<p>Use this page to detail your site's privacy policy.</p>

Home Az MVC alkalmazás vezérlőjében adja vissza a nézetet.

Adja hozzá a következő kódot a Controllers/HomeController.cs:

public IActionResult Privacy()
{
    return View();
}

Ha donoralkalmazásból importál fájlokat, mindenképpen frissítse a fájlokban lévő névtereket úgy, Serverhogy azok megfeleljenek a BlazorHosted.Server projektnek (például).

Statikus eszközök importálása a Server projektbe a donor projekt mappájából wwwroot :

  • wwwroot/css mappa és tartalom
  • wwwroot/js mappa és tartalom
  • wwwroot/lib mappa és tartalom

Ha a donorprojekt egy ASP.NET Core-projektsablonból jön létre, és a fájlok nem módosulnak, a teljes wwwroot mappát átmásolhatja a donorprojektből a Server projektbe, és eltávolíthatja az favicon ikonfájlt.

Figyelmeztetés

Kerülje el, hogy a statikus objektumot mind a Client mappába, mind a Serverwwwroot mappákba helyezze. Ha ugyanaz a fájl mindkét mappában megtalálható, kivételt jelent, mert az egyes mappák statikus objektuma ugyanazzal a webes gyökérútvonallal rendelkezik. Ezért csak az egyik wwwroot mappában üzemeltessen statikus erőforrást, ne mindkettőben.

Az előző konfiguráció bevezetése után ágyazza be Razor az összetevőket a Server projekt lapjaiba vagy nézeteibe. Használja a cikk következő szakaszaiban található útmutatást:

  • Összetevők renderelése egy lapon vagy nézetben az Összetevőcímke súgójával
  • Összetevők renderelése egy lapon vagy nézetben CSS-választóval

Összetevők renderelése egy lapon vagy nézetben az Összetevőcímke súgójával

A megoldás konfigurálása után , beleértve a további konfigurációt is, a Komponenscímke segéd két renderelési módot támogat egy összetevő egy alkalmazásból Blazor WebAssembly való megjelenítéséhez egy lapon vagy nézetben:

A következő Razor Pages-példában az Counter összetevő egy lapon jelenik meg. Az összetevő interaktívvá tétele érdekében a Blazor WebAssembly szkript szerepel a lap renderelési szakaszában. Ha el szeretné kerülni, hogy az Counter összetevő teljes névterét használja a Komponenscímke segéd{ASSEMBLY NAME}.Pages.Counter () segítségével, adjon hozzá egy @using irányelvet az ügyfélprojekt névteréhezPages. Az alábbi példában a Client projekt névtere a következő BlazorHosted.Client: .

A Server projektben, Pages/RazorPagesCounter1.cshtml:

@page
@using BlazorHosted.Client.Pages

<component type="typeof(Counter)" render-mode="WebAssemblyPrerendered" />

@section Scripts {
    <script src="_framework/blazor.webassembly.js"></script>
}

Futtassa a Server projektet. Navigáljon a Razor oldalra a /razorpagescounter1 helyen. Az előre berendezett Counter összetevő beágyazva van a lapba.

RenderMode beállítja, hogy a komponens:

  • Előre le van renderelve az oldalra.
  • Statikus HTML-ként jelenik meg a lapon, vagy ha tartalmazza a szükséges információkat az alkalmazás indításához a felhasználói ügynöktől Blazor.

Az összetevőcímke-segédről , beleértve a paraméterek és RenderMode a konfiguráció átadását is, a ASP.NET Core összetevőcímke-segédjében talál további információt.

További munkára lehet szükség az összetevők által használt statikus erőforrásoktól és az elrendezési lapok alkalmazásbeli rendszerezésétől függően. A szkriptek általában egy lap vagy nézet renderelési szakaszához Scripts lesznek hozzáadva, a stíluslapok pedig hozzáadódnak az elrendezés elemtartalmaihoz <head> .

Gyermek tartalom beállítása renderelő fragmentumon keresztül

Az összetevőcímke-segédeszköz nem támogatja, hogy egy RenderFragment delegáltat fogadjon gyerektartalomhoz ( például param-ChildContent="..."). Javasoljuk, hogy hozzon létre egy Razor összetevőt (.razor), amely hivatkozik arra az összetevőre, amelyet meg szeretne jeleníteni a továbbítani kívánt gyermek tartalommal, majd hívja meg az Razor összetevőt az oldalból vagy nézetből.

Győződjön meg arról, hogy a legfelső szintű előrerendelt összetevők nincsenek kivágva a közzétételkor

Ha egy összetevőcímke-segéd közvetlenül hivatkozik egy olyan erőforrástárból származó összetevőre, amelyre a közzétételkor vágás vonatkozik, előfordulhat, hogy az összetevőt a közzététel során levágják, mert az ügyféloldali alkalmazáskódból nincsenek rá mutató hivatkozások. Ennek eredményeképpen az összetevő nincs előrerendezve, így üres helyet hagy a kimenetben. Ha ez történik, utasítsa a trimmerrel, hogy őrizze meg a könyvtárkomponenst úgy, hogy egy DynamicDependency attribútumot ad hozzá az ügyféloldali alkalmazás bármely osztályához. Egy SomeLibraryComponentToBePreserved nevű összetevő megőrzéséhez adja hozzá a következőket bármelyik összetevőhöz:

@using System.Diagnostics.CodeAnalysis
@attribute [DynamicDependency(DynamicallyAccessedMemberTypes.All, 
    typeof(SomeLibraryComponentToBePreserved))]

Az előző megközelítés általában nem szükséges, mert az alkalmazás általában előrerendeli az összetevőit (amelyek nincsenek levágva), ami viszont a kódtárak összetevőire hivatkozik (ami miatt azokat sem kell levágni). Csak akkor használja a DynamicDependency elemet explicit módon egy könyvtárkomponens előfeldolgozására közvetlenül, ha a könyvtár vágás alá esik.

Összetevők renderelése egy lapon vagy nézetben CSS-választóval

Miután konfigurálta a megoldást, beleértve a további konfigurációt, adjon hozzá gyökérösszetevőket a Client fájlban Blazor WebAssembly található üzemeltetett Program.cs megoldás projektéhez. Az alábbi példában az Counter összetevő gyökérkomponensként van deklarálva, egy CSS-választóval, amely az id elemet választja ki, amely megfelel a counter-component feltételnek. Az alábbi példában a Client projekt névtere a következő BlazorHosted.Client: .

A Program.cs projekt fájljának Client részéhez adja hozzá a projekt Razor összetevőinek névterét a fájl elejére.

using BlazorHosted.Client.Pages;

Miután a builder létrejött a Program.cs-ben, adja hozzá az Counter komponenset gyökérkomponensként.

builder.RootComponents.Add<Counter>("#counter-component");

A következő Razor Pages-példában az Counter összetevő egy lapon jelenik meg. Az összetevő interaktívvá tétele érdekében a Blazor WebAssembly szkript szerepel a lap renderelési szakaszában.

A Server projektben, Pages/RazorPagesCounter2.cshtml:

@page

<div id="counter-component">Loading...</div>

@section Scripts {
    <script src="_framework/blazor.webassembly.js"></script>
}

Futtassa a Server projektet. Navigáljon a Razor oldalra a /razorpagescounter2 helyen. Az előre berendezett Counter összetevő beágyazva van a lapba.

További munkára lehet szükség az összetevők által használt statikus erőforrásoktól és az elrendezési lapok alkalmazásbeli rendszerezésétől függően. A szkriptek általában egy lap vagy nézet renderelési szakaszához Scripts lesznek hozzáadva, a stíluslapok pedig hozzáadódnak az elrendezés elemtartalmaihoz <head> .

Megjegyzés

Az előző példa JSException dob, ha egy Blazor WebAssembly alkalmazás előre van renderelve, és egy Pages vagy MVC alkalmazásba van integrálva Razor, a CSS-választó használatával. Amikor a Client projekt valamelyik összetevőjére navigál Razor, vagy beágyazott összetevővel rendelkező oldalra vagy nézetre navigál Server, az egy vagy több JSException okozhat.

Ez normális viselkedés, mert egy Blazor WebAssembly alkalmazás előrerenderése és útvonalazható Razor összetevőkkel való integrálása nem kompatibilis a CSS-választók használatával.

Ha az előző szakaszokban szereplő példákkal dolgozott, és csak azt szeretné látni, hogy a CSS-választó működik a mintaalkalmazásban, tegye megjegyzésbe a AppClient projekt fájljának fő összetevőjének specifikációját Program.cs :

- builder.RootComponents.Add<App>("#app");
+ //builder.RootComponents.Add<App>("#app");

Navigáljon a CSS-választót használó beágyazott Razor összetevővel (például /razorpagescounter2 az előző példával) rendelkező lapra vagy nézetre. A lap vagy a nézet betöltődik a beágyazott összetevővel, és a beágyazott összetevő a várt módon működik.

Előre beállított állapot megőrzése

Az előre beállított állapot megőrzése nélkül az előrendelés során használt állapot elveszik, és újra létre kell hozni az alkalmazás teljes betöltésekor. Ha bármely állapot aszinkron módon van beállítva, a felhasználói felület villanhat, mivel az előre renderelt felhasználói felületet ideiglenesen helyőrző elemek váltják fel, majd újra teljesen renderelődik.

Ezeknek a problémáknak a megoldásához a Blazor támogatja az állapot megőrzését egy előre összeállított lapon, a Komponensállapot-tartó címke segítő használatával. Helyezze a Tag Helper címkét, <persist-component-state />, a záró </body> címkén belül.

Pages/_Layout.cshtml:

<body>
    ...

    <persist-component-state />
</body>

Döntse el, hogy melyik állapotot kívánja megőrizni a PersistentComponentState szolgáltatással. PersistentComponentState.RegisterOnPersisting regisztrál egy visszahívást az összetevő állapotának megőrzéséhez az alkalmazás szüneteltetése előtt. A rendszer az alkalmazás folytatásakor kéri le az állapotot. Az inicializálási kód végén hajtsa végre a hívást, hogy elkerülje a lehetséges versenyhelyzetet az alkalmazás leállítása során.

Az alábbi példa egy FetchData üzemeltetett Blazor WebAssembly alkalmazás összetevőjének frissített verziója a Blazor projektsablon alapján. Az WeatherForecastPreserveState összetevő megőrzi az időjárás-előrejelzés állapotát az előrendelés során, majd lekéri az állapotot az összetevő inicializálásához. A Komponensállapotot megőrző tag asszisztens az összes összetevő-meghívás után is megőrzi az összetevő állapotát.

Pages/WeatherForecastPreserveState.razor:

@page "/weather-forecast-preserve-state"
@implements IDisposable
@using BlazorSample.Shared
@inject IWeatherForecastService WeatherForecastService
@inject PersistentComponentState ApplicationState

<PageTitle>Weather Forecast</PageTitle>

<h1>Weather forecast</h1>

<p>This component demonstrates fetching data from the server.</p>

@if (forecasts == null)
{
    <p><em>Loading...</em></p>
}
else
{
    <table class="table">
        <thead>
            <tr>
                <th>Date</th>
                <th>Temp. (C)</th>
                <th>Temp. (F)</th>
                <th>Summary</th>
            </tr>
        </thead>
        <tbody>
            @foreach (var forecast in forecasts)
            {
                <tr>
                    <td>@forecast.Date.ToShortDateString()</td>
                    <td>@forecast.TemperatureC</td>
                    <td>@forecast.TemperatureF</td>
                    <td>@forecast.Summary</td>
                </tr>
            }
        </tbody>
    </table>
}

@code {
    private WeatherForecast[] forecasts = Array.Empty<WeatherForecast>();
    private PersistingComponentStateSubscription persistingSubscription;

    protected override async Task OnInitializedAsync()
    {
        if (!ApplicationState.TryTakeFromJson<WeatherForecast[]>(
            nameof(forecasts), out var restored))
        {
            forecasts = 
                await WeatherForecastService.GetForecastAsync(DateTime.Now);
        }
        else
        {
            forecasts = restored!;
        }

        // Call at the end to avoid a potential race condition at app shutdown
        persistingSubscription = ApplicationState.RegisterOnPersisting(PersistData);
    }

    private Task PersistData()
    {
        ApplicationState.PersistAsJson(nameof(forecasts), forecasts);

        return Task.CompletedTask;
    }

    void IDisposable.Dispose()
    {
        persistingSubscription.Dispose();
    }
}

Az előrendelés során használt azonos állapotú összetevők inicializálásával a költséges inicializálási lépések csak egyszer lesznek végrehajtva. A renderelt felhasználói felület megegyezik az előre beállított felhasználói felülettel, így a böngészőben nem történik villódzás.

A rendszer átviszi a megőrzött előrerendelt állapotot az ügyfélnek, ahol az összetevő állapotának visszaállítására szolgál. Egy üzemeltetett Blazor WebAssembly alkalmazásban történő előzetes rendezéshez az adatok a böngészőben lesznek közzétéve, és nem tartalmazhatnak bizalmas, személyes adatokat.

További Blazor WebAssembly erőforrások

Az előzetes rendezés javíthatja a keresőmotor-optimalizálást (SEO) azáltal, hogy megjeleníti a kezdeti HTTP-válasz tartalmát, amellyel a keresőmotorok kiszámíthatják az oldal rangját.

Megoldáskonfiguráció

Előrenderelés konfigurációja

Előrerenderelés beállítása hostolt Blazor WebAssembly alkalmazáshoz:

  1. Blazor WebAssembly Az alkalmazást egy ASP.NET Core-alkalmazásban üzemelteti. Egy önálló Blazor WebAssembly alkalmazás hozzáadható egy ASP.NET Core megoldáshoz, vagy használhat egy Blazor WebAssembly létrehozott üzemeltetett Blazor WebAssembly alkalmazást az üzemeltetett opció használatával.

    • Visual Studio: A További információk párbeszédpanelen jelölje be a ASP.NET Központi üzemeltetésű jelölőnégyzetet az Blazor WebAssembly alkalmazás létrehozásakor. A jelen cikk példáiban a megoldás neve BlazorHosted.
    • Visual Studio Code/.NET CLI parancssori felület: dotnet new blazorwasm -ho (használja a -ho|--hosted lehetőséget). Ezzel a -o|--output {LOCATION} beállítással létrehozhat egy mappát a megoldáshoz, és beállíthatja a megoldás projektnévtereit. A cikk példáiban a megoldás neve BlazorHosted (dotnet new blazorwasm -ho -o BlazorHosted).

    A cikkben szereplő példák esetében az ügyfélprojekt névtere a BlazorHosted.Client, és a kiszolgálóprojekt névtere a BlazorHosted.Server.

  2. Törölje a wwwroot/index.html fájlt a Blazor WebAssemblyClient projektből.

  3. A projektben Clienttörölje a következő sort Program.cs:

    - builder.RootComponents.Add<App>("#app");
    
  4. Adjon hozzá egy Pages/_Host.cshtml fájlt a Server projekt mappájába Pages . A _Host.cshtml sablonból létrehozott projektből szerezhet be egy Blazor Server fájlt a parancssori környezetben használható dotnet new blazorserver -o BlazorServer paranccsal (a -o BlazorServer beállítás létrehoz egy mappát a projekthez). Miután elhelyezte a Pages/_Host.cshtml fájlt a Server üzemeltetett Blazor WebAssembly megoldás projektében, végezze el a következő módosításokat a fájlon:

    • Adjon meg egy @using irányelvet a Client projekthez (például @using BlazorHosted.Client).

    • Frissítse a stíluslap hivatkozásait, hogy a WebAssembly projekt stíluslapjaira mutasson. Az alábbi példában az ügyfélprojekt névtere a következő BlazorHosted.Client:

      - <link href="css/site.css" rel="stylesheet" />
      - <link href="_content/BlazorServer/_framework/scoped.styles.css" rel="stylesheet" />
      + <link href="css/app.css" rel="stylesheet" />
      + <link href="BlazorHosted.Client.styles.css" rel="stylesheet" />
      

      Megjegyzés

      Hagyja helyben a <link> Bootstrap stíluslapot (css/bootstrap/bootstrap.min.css) kérő elemet.

    • Frissítse a render-modeKomponenscímke segédprogramot , hogy a gyökérösszetevőt App előrerendelje a következővel WebAssemblyPrerendered:

      - <component type="typeof(App)" render-mode="ServerPrerendered" />
      + <component type="typeof(App)" render-mode="WebAssemblyPrerendered" />
      
    • Frissítse a Blazor szkript forrását, hogy az ügyféloldali Blazor WebAssembly szkriptet használja:

      - <script src="_framework/blazor.server.js"></script>
      + <script src="_framework/blazor.webassembly.js"></script>
      
  5. A Startup.Configure projekt Server részében változtassa meg a visszalépést a index.html fájlról a _Host.cshtml lapra.

    Startup.cs:

    - endpoints.MapFallbackToFile("index.html");
    + endpoints.MapFallbackToPage("/_Host");
    
  6. Ha a Client és a Server projektek egy vagy több közös szolgáltatást használnak az előrenderelés során, helyezze el a szolgáltatásregisztrációkat egy olyan eljárásba, amely mindkét projektből meghívható. További információért lásd a ASP.NET Core Blazor függőség-injektálás.

  7. Futtassa a Server projektet. A üzemeltetett Blazor WebAssembly alkalmazást a Server projekt előfeldolgozza az ügyfelek számára.

A Razor összetevők lapokba vagy nézetekbe való beágyazásának konfigurálása

Az alábbi szakaszok és példák a Razor ügyfélalkalmazás összetevőinek Blazor WebAssembly kiszolgálóalkalmazás lapjaiba vagy nézeteibe való beágyazásához további konfigurációt igényelnek.

Használjon alapértelmezett Razor Pages vagy MVC elrendezésfájlt a Server projektben. A Server projektnek a következő fájlokkal és mappával kell rendelkeznie.

Razor Oldalak:

  • Pages/Shared/_Layout.cshtml
  • Pages/_ViewImports.cshtml
  • Pages/_ViewStart.cshtml

MVC:

  • Views/Shared/_Layout.cshtml
  • Views/_ViewImports.cshtml
  • Views/_ViewStart.cshtml

Szerezze be az előző fájlokat a Pages vagy az Razor MVC projektsablonból létrehozott alkalmazásból. További információkért lásd: Oktatóanyag: Első lépések az Razor ASP.NET Core lapokkal vagy az ASP.NET Core MVC használatának első lépései.

Frissítse az importált _ViewImports.cshtml fájl névtereit úgy, hogy azok megfeleljenek a Server fájlokat fogadó projekt által használt névtereknek.

Frissítse az importált elrendezésfájlt (_Layout.cshtml) a Client projekt stílusainak belefoglalásához. Az alábbi példában a Client projekt névtere a következő BlazorHosted.Client: . Az <title> elem egyszerre frissíthető.

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

<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
-   <title>@ViewData["Title"] - DonorProject</title>
+   <title>@ViewData["Title"] - BlazorHosted</title>
    <link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.min.css" />
    <link rel="stylesheet" href="~/css/site.css" />
+   <link href="css/app.css" rel="stylesheet" />
+   <link href="BlazorHosted.Client.styles.css" rel="stylesheet" />
</head>

Az importált elrendezés tartalmaz Home és Privacy navigációs hivatkozásokat. A Home hivatkozást úgy módosítsa, hogy az az üzemeltetett Blazor WebAssembly alkalmazásra mutasson.

- <a class="nav-link text-dark" asp-area="" asp-page="/Index">Home</a>
+ <a class="nav-link text-dark" href="/">Home</a>

MVC-elrendezésfájlban:

- <a class="nav-link text-dark" asp-area="" asp-controller="Home" 
-     asp-action="Index">Home</a>
+ <a class="nav-link text-dark" href="/">Home</a>

Ahhoz, hogy a Privacy hivatkozás adatvédelmi laphoz vezessen, adjon hozzá egy adatvédelmi lapot a Server projekthez.

Pages/Privacy.cshtml a Server projektben:

@page
@model BlazorHosted.Server.Pages.PrivacyModel
@{
}

<h1>Privacy Policy</h1>

Ha előnyben részesíti az MVC-alapú adatvédelmi nézetet, hozzon létre egy adatvédelmi nézetet a Server projektben.

View/Home/Privacy.cshtml:

@{
    ViewData["Title"] = "Privacy Policy";
}

<h1>@ViewData["Title"]</h1>

A Home vezérlőben adja vissza a nézetet.

Controllers/HomeController.cs:

public IActionResult Privacy()
{
    return View();
}

Statikus eszközök importálása a Server projektbe a donor projekt mappájából wwwroot :

  • wwwroot/css mappa és tartalom
  • wwwroot/js mappa és tartalom
  • wwwroot/lib mappa és tartalom

Ha a donorprojekt egy ASP.NET Core-projektsablonból jön létre, és a fájlok nem módosulnak, a teljes wwwroot mappát átmásolhatja a donorprojektből a Server projektbe, és eltávolíthatja az favicon ikonfájlt.

Figyelmeztetés

Kerülje el, hogy a statikus objektumot mind a Client mappába, mind a Serverwwwroot mappákba helyezze. Ha ugyanaz a fájl mindkét mappában megtalálható, kivételt jelent, mert az egyes mappák statikus objektuma ugyanazzal a webes gyökérútvonallal rendelkezik. Ezért csak az egyik wwwroot mappában üzemeltessen statikus erőforrást, ne mindkettőben.

Összetevők renderelése egy lapon vagy nézetben az Összetevőcímke súgójával

A megoldás konfigurálása után , beleértve a további konfigurációt is, a Komponenscímke segéd két renderelési módot támogat egy összetevő egy alkalmazásból Blazor WebAssembly való megjelenítéséhez egy lapon vagy nézetben:

A következő Razor Pages-példában az Counter összetevő egy lapon jelenik meg. Az összetevő interaktívvá tétele érdekében a Blazor WebAssembly szkript szerepel a lap renderelési szakaszában. Ha el szeretné kerülni, hogy az Counter összetevő teljes névterét használja a Komponenscímke segéd{ASSEMBLY NAME}.Pages.Counter () segítségével, adjon hozzá egy @using irányelvet az ügyfélprojekt névteréhezPages. Az alábbi példában a Client projekt névtere a következő BlazorHosted.Client: .

A Server projektben, Pages/RazorPagesCounter1.cshtml:

@page
@using BlazorHosted.Client.Pages

<component type="typeof(Counter)" render-mode="WebAssemblyPrerendered" />

@section Scripts {
    <script src="_framework/blazor.webassembly.js"></script>
}

Futtassa a Server projektet. Navigáljon a Razor oldalra a /razorpagescounter1 helyen. Az előre berendezett Counter összetevő beágyazva van a lapba.

RenderMode beállítja, hogy a komponens:

  • Előre le van renderelve az oldalra.
  • Statikus HTML-ként jelenik meg a lapon, vagy ha tartalmazza a szükséges információkat az alkalmazás indításához a felhasználói ügynöktől Blazor.

Az összetevőcímke-segédről , beleértve a paraméterek és RenderMode a konfiguráció átadását is, a ASP.NET Core összetevőcímke-segédjében talál további információt.

További munkára lehet szükség az összetevők által használt statikus erőforrásoktól és az elrendezési lapok alkalmazásbeli rendszerezésétől függően. A szkriptek általában egy lap vagy nézet renderelési szakaszához Scripts lesznek hozzáadva, a stíluslapok pedig hozzáadódnak az elrendezés elemtartalmaihoz <head> .

Összetevők renderelése egy lapon vagy nézetben CSS-választóval

Miután konfigurálta a megoldást, beleértve a további konfigurációt, adjon hozzá gyökérösszetevőket egy üzemeltetett Client megoldás projektéhez a Blazor WebAssembly következőbenProgram.cs: . Az alábbi példában az Counter összetevő gyökérkomponensként van deklarálva, egy CSS-választóval, amely az id elemet választja ki, amely megfelel a counter-component feltételnek. Az alábbi példában a Client projekt névtere a következő BlazorHosted.Client: .

A Program.cs projekt Client-jában adja hozzá a projekt Razor összetevőinek névterét a fájl tetejére.

using BlazorHosted.Client.Pages;

Miután a builder létrejött a Program.cs-ben, adja hozzá az Counter komponenset gyökérkomponensként.

builder.RootComponents.Add<Counter>("#counter-component");

A következő Razor Pages-példában az Counter összetevő egy lapon jelenik meg. Az összetevő interaktívvá tétele érdekében a Blazor WebAssembly szkript szerepel a lap renderelési szakaszában.

A Server projektben, Pages/RazorPagesCounter2.cshtml:

@page

<div id="counter-component">Loading...</div>

@section Scripts {
    <script src="_framework/blazor.webassembly.js"></script>
}

Futtassa a Server projektet. Navigáljon a Razor oldalra a /razorpagescounter2 helyen. Az előre berendezett Counter összetevő beágyazva van a lapba.

További munkára lehet szükség az összetevők által használt statikus erőforrásoktól és az elrendezési lapok alkalmazásbeli rendszerezésétől függően. A szkriptek általában egy lap vagy nézet renderelési szakaszához Scripts lesznek hozzáadva, a stíluslapok pedig hozzáadódnak az elrendezés elemtartalmaihoz <head> .

Megjegyzés

Az előző példa kivált egy JSException-t, ha egy Blazor WebAssembly alkalmazás előre van renderelve, és Razor Pages vagy MVC alkalmazásba egyidejűleg integrálva van egy CSS-választóval. A projekt egyik Client összetevőjére Razor való navigálás a következő kivételt okozza:

Microsoft.JSInterop.JSException: Nem található az "#counter-component" választónak megfelelő elem.

Ez normális viselkedés, mert egy Blazor WebAssembly alkalmazás előrerenderése és útvonalazható Razor összetevőkkel való integrálása nem kompatibilis a CSS-választók használatával.

További Blazor WebAssembly erőforrások

A .NET 5-ös vagy újabb verziójú ASP.NET Core támogatja, hogy Razor összetevőket integráljon Razor a Pages- vagy MVC-alkalmazásokba egy üzemeltetett Blazor WebAssemblymegoldásban. Válassza ki a cikk .NET 5-ös vagy újabb verzióját.