Dela via


Integrera ASP.NET Core Razor-komponenter med MVC eller Razor-sidor i hostade Blazor WebAssembly-lösningar

Anmärkning

Värdbaserade Blazor WebAssembly lösningar stöds fortfarande, men projektmallen har tagits bort och stöds inte längre i .NET 8 eller senare. Denna artikel finns i innehållsförteckningen upp till .NET 7 som referens, men notera att .NET 7 är en Standard Support Term-version som inte längre stöds.

Varning

Den här versionen av ASP.NET Core stöds inte längre. Mer information finns i .NET och .NET Core Support Policy.

I den här artikeln beskrivs Razor scenarier för komponentintegrering för värdbaserade Blazor WebAssembly appar, inklusive förinläsning av Razor komponenter på servern.

Viktigt!

Framework-ändringar i ASP.NET Core-versioner ledde till olika uppsättningar instruktioner i den här artikeln. Innan du använder den här artikelns vägledning kontrollerar du att dokumentversionsväljaren överst i den här artikeln matchar den version av ASP.NET Core som du tänker använda för din app.

Prerendering kan förbättra sökmotoroptimering (SEO) genom att återge innehåll för det första HTTP-svaret som sökmotorer kan använda för att beräkna sidrankning.

Lösningskonfiguration

Förkonfigurationsinställningar

Så här konfigurerar du prerendering för en värdbaserad Blazor WebAssembly app:

  1. Värd för Blazor WebAssembly appen i en ASP.NET Core-app. En fristående Blazor WebAssembly app kan läggas till i en ASP.NET Core-lösning, eller så kan du använda en värd Blazor WebAssembly app skapad från Blazor WebAssembly projektmallen med värdalternativet:

    • Visual Studio: I dialogrutan Ytterligare information markerar du kryssrutan ASP.NET Core Hosted när du Blazor WebAssembly skapar appen. I den här artikelns exempel heter BlazorHostedlösningen .
    • Visual Studio Code/.NET CLI-kommandogränssnittet: dotnet new blazorwasm -ho (använd alternativet -ho|--hosted ). Använd alternativet -o|--output {LOCATION} för att skapa en mapp för lösningen och ställ in lösningens projektnamnrymder. I exemplen i den här artikeln är lösningen namngiven BlazorHosted (dotnet new blazorwasm -ho -o BlazorHosted).

    För exemplen i den här artikeln är namnet på den värdbaserade lösningen (samlingens namn) BlazorHosted. Namnrymden för klientprojektet är BlazorHosted.Client, och namnrymden för serverprojektet är BlazorHosted.Server.

  2. Ta bortwwwroot/index.html filen från Blazor WebAssemblyClient projektet.

  3. I projektet Client, ta bort följande rader i Program.cs:

    - builder.RootComponents.Add<App>("#app");
    - builder.RootComponents.Add<HeadOutlet>("head::after");
    
  4. Lägg till _Host.cshtml filen i Server projektets Pages mapp. Du kan hämta filerna från ett projekt som skapats från mallen Blazor Server med hjälp av Visual Studio eller med hjälp av .NET CLI med dotnet new blazorserver -o BlazorServer kommandot i ett kommandogränssnitt ( -o BlazorServer alternativet skapar en mapp för projektet). När du har placerat filerna i Server projektets Pages mapp gör du följande ändringar i filerna.

    Gör följande ändringar i _Host.cshtml filen:

    • Uppdatera Pages-namnrymden överst i filen så att den matchar namnrymden för Server-appens sidor. {APP NAMESPACE}-platshållaren i följande exempel representerar namnområdet för donatorappens sidor som tillhandahöll _Host.cshtml-filen.

      Ta bort:

      - @namespace {APP NAMESPACE}.Pages
      

      Lägg till

      @namespace BlazorHosted.Server.Pages
      
    • Lägg till en @using direktiv för Client projektet högst upp i filen.

      @using BlazorHosted.Client
      
    • Uppdatera stilkods-länkarna så att de pekar på WebAssembly-projektets stilark. I följande exempel är klientprojektets namnområde BlazorHosted.Client. {APP NAMESPACE}-platshållaren representerar namnrymden för den givande appen som tillhandahöll _Host.cshtml-filen. Uppdatera komponenttaggens hjälp (<component> tagg) för komponenten HeadOutlet för att förebygga komponenten.

      Ta bort:

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

      Lägg till

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

      Anmärkning

      Lämna <link>-elementet som begär Bootstrap-stilmallen (css/bootstrap/bootstrap.min.css) på plats.

    • Blazor Uppdatera skriptkällan så att skriptet på klientsidan Blazor WebAssembly används:

      Ta bort:

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

      Lägg till

      <script src="_framework/blazor.webassembly.js"></script>
      
    • render-mode Uppdatera komponenttaggens hjälp för att förebygga rotkomponenten App med WebAssemblyPrerendered:

      Ta bort:

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

      Lägg till

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

      Viktigt!

      Förberedande rendering stöds inte för autentiseringsändpunkter (/authentication/-vägsegment). Mer information finns i ASP.NET Core Blazor WebAssembly ytterligare säkerhetsscenarier.

  5. I Program.cs-filen i Server-projektet, ändra fallback-endpunkten från index.html-filen till _Host.cshtml-sidan.

    Ta bort:

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

    Lägg till

    app.MapFallbackToPage("/_Host");
    
  6. Client Om projekten och Server använder en eller flera vanliga tjänster under förinläsningen ska du ta med tjänstregistreringarna i en metod som kan anropas från båda projekten. Mer information finns i ASP.NET Core Blazor beroendeinjektion.

  7. Kör projektet Server. Den värdbaserade Blazor WebAssembly appen förebyggs av Server projektet för klienter.

Konfiguration för inbäddning av Razor-komponenter i sidor eller vyer

Följande avsnitt och exempel för att bädda in Razor-komponenter från ClientBlazor WebAssembly-appen i sidor eller vyer av serverappen kräver ytterligare konfiguration.

Projektet Server måste ha följande filer och mappar.

Razor Sidor:

  • 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

De följande filerna kan erhållas genom att generera en app från ASP.NET Core-projektmallarna med:

  • Visual Studios nya verktyg för att skapa projekt.
  • Öppna ett kommandoskal och kör dotnet new webapp -o {PROJECT NAME} (Razor Sidor) eller dotnet new mvc -o {PROJECT NAME} (MVC). Alternativet -o|--output med ett värde för {PROJECT NAME} platshållaren ger ett namn till appen och skapar en mapp för appen.

Uppdatera namnområdena i den importerade _ViewImports.cshtml-filen så att de matchar de som används av Server-projektet som tar emot filerna.

Pages/_ViewImports.cshtml (Razor Sidor):

@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

Uppdatera den importerade layoutfilen, som är Pages/Shared/_Layout.cshtml för Razor-sidor eller Views/Shared/_Layout.cshtml för MVC.

Först, ta bort titeln och stilmallen från donatorprojektet, vilket är RPDonor.styles.css i följande exempel. Platshållaren {PROJECT NAME} representerar donatorprojektets appnamn.

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

Client Inkludera projektets formatmallar i layoutfilen. I följande exempel Client är BlazorHosted.Clientprojektets namnområde . Elementet <title> kan uppdateras samtidigt.

Placera följande rader i <head> layoutfilens innehåll:

<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" />

Den importerade layouten innehåller två Home (Index sida) och Privacy navigeringslänkar. För att få Home-länkarna att peka på den hostade Blazor WebAssembly-appen, ändra hyperlänkarna:

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

I en MVC-layoutfil:

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

Uppdatera elementets <footer> appnamn. I följande exempel används appnamnet BlazorHosted:

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

I det föregående exemplet representerar platshållaren {DATE} upphovsrättsdatumet i en app som genererats från Razor Pages- eller MVC-projektmallen.

För att få Privacy länken att leda till en sekretessida (Razor Sidor), lägg till en sekretessida i Server projektet.

Pages/Privacy.cshtml i Server projektet:

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

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

För en MVC-baserad sekretessvy, skapa en sekretessvy i Server-projektet.

View/Home/Privacy.cshtml i Server projektet:

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

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

I kontrollanten Home för MVC-appen returnerar du vyn.

Lägg till följande kod i Controllers/HomeController.cs:

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

Om du importerar filer från en givarapp måste du uppdatera alla namnområden i filerna så att de Server matchar projektets (till exempel BlazorHosted.Server).

Importera statiska tillgångar till Server-projektet från givarprojektets wwwroot-mapp.

  • wwwroot/css mapp och innehåll
  • wwwroot/js mapp och innehåll
  • wwwroot/lib mapp och innehåll

Om donatorprojektet är skapat från en ASP.NET Core-projektmall och filerna inte har modifierats, kan du kopiera hela wwwroot-mappen från donatorprojektet till Server-projektet och ta bort favicon-ikonfilen.

Varning

Undvik att placera den statiska resursen i både Client och Serverwwwroot mapparna. Om samma fil finns i båda mapparna, kastas ett undantag eftersom de statiska resurserna delar samma webbrotväg. Värd ett statiskt objekt i någon av wwwroot-mapparna, inte båda.

Efter att ha antagit den föregående konfigurationen, integrera Razor komponenter i sidor eller vyer av Server projektet. Använd vägledningen i följande avsnitt av denna artikel:

  • Rendera komponenter på en sida eller vy med Component Tag Helper
  • Rendera komponenter på en sida eller vy med en CSS-selektor

Rendera komponenter på en sida eller vy med hjälp av Component Tag Helper

Efter att ha konfigurerat lösningen, inklusive ytterligare konfigurationer, stöder Component Tag Helper två renderingslägen för att rendera en komponent från en Blazor WebAssembly app på en sida eller i en vy.

I det följande Razor Pages-exemplet renderas Counter-komponenten på en sida. För att göra komponenten interaktiv inkluderas Blazor WebAssembly-skriptet i sidans renderingssektion. För att undvika att använda det fullständiga namnområdet för Counter-komponenten med Component Tag Helper ({ASSEMBLY NAME}.Pages.Counter), lägg till en @using-direktiv för klientprojektets Pages-namnområde. I följande exempel Client är BlazorHosted.Clientprojektets namnområde .

I Server projektet, Pages/RazorPagesCounter1.cshtml:

@page
@using BlazorHosted.Client.Pages

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

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

Kör projektet Server. Gå till sidan Razor på /razorpagescounter1. Den förhandsrenderade Counter-komponenten är inbäddad på sidan.

RenderMode konfigurerar huruvida komponenten:

  • Är förhandsrenderad på sidan.
  • Återges som statisk HTML på sidan eller om den innehåller nödvändig information för att starta en Blazor app från användaragenten.

Mer information om komponenttagghjälpen, inklusive att skicka parametrar och RenderMode konfiguration, finns i Komponenttagghjälp i ASP.NET Core.

Ytterligare arbete kan krävas beroende på de statiska resurser som komponenterna använder och hur layout sidorna är organiserade i en app. Vanligtvis läggs skript till i en sidas eller visnings Scripts renderingssektion och stilmallar läggs till i layoutens <head> elementinnehåll.

Ange barninnehåll genom ett renderfragment.

Component Tag Helper stöder inte mottagning av en RenderFragment delegering för underordnat innehåll (till exempel, param-ChildContent="..."). Vi rekommenderar att du skapar en Razor-komponent (.razor) som refererar till den komponent du vill rendera tillsammans med det barninnehåll du vill lämna över, och sedan kalla på Razor-komponenten från sidan eller vyn.

Säkerställ att översta nivån av förrenderade komponenter inte tas bort vid publicering.

Om en Component Tag Helper direkt refererar till en komponent från ett bibliotek som kan beskäras vid publicering, kan komponenten beskäras bort under publiceringen eftersom det inte finns några referenser till den från klientens app-kod. Som ett resultat av detta för-renderas inte komponenten, vilket lämnar ett tomt utrymme i utdata. Om detta inträffar instruerar du trimmern att bevara bibliotekskomponenten genom att lägga till ett DynamicDependency attribut till alla klasser i klientsidans app. För att bevara en komponent kallad SomeLibraryComponentToBePreserved, lägg till följande i valfri komponent:

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

Den tidigare metoden är vanligtvis inte nödvändig eftersom appen normalt förrenders sina komponenter (som inte är beskurna), som i sin tur refererar till komponenter från bibliotek (vilket gör att de också inte beskärs). Använd endast DynamicDependency explicit för att förframställa en bibliotekskomponent direkt när biblioteket är föremål för beskärning.

Rendera komponenter på en sida eller vy med en CSS-selektor

Efter konfigurering av lösningen, inklusive ytterligare konfigurering, lägg till rotkomponenter i Client projektet av en värdbaserad Blazor WebAssembly lösning i Program.cs filen. I följande exempel deklareras komponenten Counter som en rotkomponent med en CSS-väljare som väljer elementet med id det som matchar counter-component. I följande exempel Client är BlazorHosted.Clientprojektets namnområde .

I Program.cs-filen i Client-projektet, lägg till namnområdet för projektets Razor-komponenter högst upp i filen.

using BlazorHosted.Client.Pages;

Efter att builder är etablerad i Program.cs, lägg till Counter komponenten som en rotkomponent:

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

I det följande Razor Pages-exemplet renderas Counter-komponenten på en sida. För att göra komponenten interaktiv inkluderas Blazor WebAssembly-skriptet i sidans renderingssektion.

I Server projektet, Pages/RazorPagesCounter2.cshtml:

@page

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

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

Kör projektet Server. Gå till sidan Razor på /razorpagescounter2. Den förhandsrenderade Counter-komponenten är inbäddad på sidan.

Ytterligare arbete kan krävas beroende på de statiska resurser som komponenterna använder och hur layout sidorna är organiserade i en app. Vanligtvis läggs skript till i en sidas eller visnings Scripts renderingssektion och stilmallar läggs till i layoutens <head> elementinnehåll.

Anmärkning

Det föregående exemplet kastar ett JSException om en Blazor WebAssembly app är förkonstruerad och integrerad i en Razor Pages- eller MVC-app samtidigt med användning av en CSS-väljare. Navigera till en av projektets Client komponenter eller navigera till en sida eller vy av Razor med en inbäddad komponent kastar ett eller flera Server.

Det här är ett normalt beteende eftersom förinläsning och integrering av en Blazor WebAssembly app med dirigerbara Razor komponenter inte är kompatibel med användningen av CSS-väljare.

Om du har arbetat med exemplen i föregående avsnitt och bara vill se CSS-väljaren arbeta i exempelappen kommenterar du ut specifikationen App för rotkomponenten i Client projektets Program.cs fil:

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

Navigera till sidan eller vyn med den inbäddade Razor-komponenten som använder en CSS-selektor (till exempel /razorpagescounter2 i det föregående exemplet). Sidan eller vyn läses in med den inbäddade komponenten och de inbäddade komponentfunktionerna som förväntat.

Bevara fördefinierat tillstånd

Utan att det förgenererade tillståndet bevaras går tillståndet som används under förgenereringen förlorat och måste återskapas när appen är fullt inladdad. Om något tillstånd konfigureras asynkront kan användargränssnittet flimra när det förinstallerade användargränssnittet ersätts med tillfälliga platshållare och sedan återges helt igen.

För att bevara tillståndet för förberenderade komponenter, använd Persist Component State Tag Helper (referenskälla). Lägg till Tag Helper-taggen, <persist-component-state />, inuti den avslutande </body>-taggen på _Host-sidan i en app som förberender komponenter.

Anmärkning

Dokumentationslänkar till .NET-referenskällan läser vanligtvis in lagringsplatsens standardgren, vilket representerar den aktuella utvecklingen för nästa version av .NET. Om du vill välja en tagg för en specifik version använder du listrutan Välj bland grenar eller taggar. Mer information finns i Så här väljer du en versionstagg för ASP.NET Core-källkod (dotnet/AspNetCore.Docs #26205).

I Pages/_Host.cshtml av Blazor appar som är WebAssembly-förberedda (WebAssemblyPrerendered) i en hostad Blazor WebAssembly app:

<body>
    ...

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

Bestäm vilket tillstånd som ska sparas med hjälp av PersistentComponentState tjänsten. PersistentComponentState.RegisterOnPersisting registrerar ett återanrop för att bevara komponenttillståndet innan appen pausas. Tillståndet hämtas när applikationen återupptas. Gör anropet i slutet av initieringskoden för att undvika ett potentiellt låsningstillstånd under appavstängningen.

I följande exempel:

  • Platshållaren {TYPE} representerar den typ av data som ska sparas (till exempel WeatherForecast[]).
  • Platshållaren {TOKEN} är en tillståndsidentifierarsträng (till exempel 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();
    }
}

Följande exempel är en uppdaterad version av FetchData-komponenten i en värd Blazor WebAssembly app baserad på Blazor-projektmallen. Komponenten WeatherForecastPreserveState bevarar väderprognostillståndet under förinläsningen och hämtar sedan tillståndet för att initiera komponenten. Persist Component State Tag Helper bevarar komponentens tillstånd efter alla komponentanrop.

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

Genom att initiera komponenter med samma tillstånd som används under förinläsningen körs eventuella dyra initieringssteg bara en gång. Det renderade användargränssnittet matchar också det förinstallerade användargränssnittet, så inget flimmer förekommer i webbläsaren.

Det beständiga förinstallerade tillståndet överförs till klienten, där det används för att återställa komponenttillståndet. För föråtergivning i en värdbaserad Blazor WebAssembly app exponeras data för webbläsaren och får inte innehålla känslig, privat information.

Ytterligare Blazor WebAssembly resurser

Prerendering kan förbättra sökmotoroptimering (SEO) genom att återge innehåll för det första HTTP-svaret som sökmotorer kan använda för att beräkna sidrankning.

Lösningskonfiguration

Förkonfigurationsinställningar

Så här konfigurerar du prerendering för en värdbaserad Blazor WebAssembly app:

  1. Värd för Blazor WebAssembly appen i en ASP.NET Core-app. En fristående Blazor WebAssembly app kan läggas till i en ASP.NET Core-lösning, eller så kan du använda en värd Blazor WebAssembly app skapad från Blazor WebAssembly projektmallen med värdalternativet:

    • Visual Studio: I dialogrutan Ytterligare information markerar du kryssrutan ASP.NET Core Hosted när du Blazor WebAssembly skapar appen. I den här artikelns exempel heter BlazorHostedlösningen .
    • Visual Studio Code/.NET CLI-kommandogränssnittet: dotnet new blazorwasm -ho (använd alternativet -ho|--hosted ). Använd alternativet -o|--output {LOCATION} för att skapa en mapp för lösningen och ställ in lösningens projektnamnrymder. I exemplen i den här artikeln är lösningen namngiven BlazorHosted (dotnet new blazorwasm -ho -o BlazorHosted).

    För exemplen i den här artikeln är BlazorHosted.Clientklientprojektets namnområde , och serverprojektets namnområde är BlazorHosted.Server.

  2. Ta bortwwwroot/index.html filen från Blazor WebAssemblyClient projektet.

  3. I projektet Client, ta bort följande rader i Program.cs:

    - builder.RootComponents.Add<App>("#app");
    - builder.RootComponents.Add<HeadOutlet>("head::after");
    
  4. Lägg till _Host.cshtml och _Layout.cshtml-filer i Server-projektets Pages-mapp. Du kan hämta filerna från ett projekt som skapats från mallen Blazor Server med hjälp av Visual Studio eller med hjälp av .NET CLI med dotnet new blazorserver -o BlazorServer kommandot i ett kommandogränssnitt ( -o BlazorServer alternativet skapar en mapp för projektet). När du har placerat filerna i Server projektets Pages mapp gör du följande ändringar i filerna.

    Viktigt!

    Användning av en layoutsida (_Layout.cshtml) med en komponenttagghjälp för en HeadOutlet komponent krävs för att styra <head> innehållet, till exempel sidans rubrik (PageTitle komponent) och andra huvudelement (HeadContent komponent). Mer information finns i Kontrollera huvudinnehåll i ASP.NET Core-apparBlazor.

    Gör följande ändringar i _Layout.cshtml filen:

    • Uppdatera Pages-namnrymden överst i filen så att den matchar namnrymden för Server-appens sidor. {APP NAMESPACE}-platshållaren i följande exempel representerar namnområdet för donatorappens sidor som tillhandahöll _Layout.cshtml-filen.

      Ta bort:

      - @namespace {APP NAMESPACE}.Pages
      

      Lägg till

      @namespace BlazorHosted.Server.Pages
      
    • Lägg till en @using direktiv för Client projektet högst upp i filen.

      @using BlazorHosted.Client
      
    • Uppdatera stilkods-länkarna så att de pekar på WebAssembly-projektets stilark. I följande exempel är klientprojektets namnområde BlazorHosted.Client. {APP NAMESPACE}-platshållaren representerar namnrymden för den givande appen som tillhandahöll _Layout.cshtml-filen. Uppdatera komponenttaggens hjälp (<component> tagg) för komponenten HeadOutlet för att förebygga komponenten.

      Ta bort:

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

      Lägg till

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

      Anmärkning

      Lämna <link>-elementet som begär Bootstrap-stilmallen (css/bootstrap/bootstrap.min.css) på plats.

    • Blazor Uppdatera skriptkällan så att skriptet på klientsidan Blazor WebAssembly används:

      Ta bort:

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

      Lägg till

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

    _Host.cshtml I filen:

    • Ändra namnområdet Pages till det i Client-projektet. Platshållaren {APP NAMESPACE} representerar namnutrymmet för sidorna i givaren-appen som tillhandahöll filen _Host.cshtml.

      Ta bort:

      - @namespace {APP NAMESPACE}.Pages
      

      Lägg till

      @namespace BlazorHosted.Client
      
    • render-mode Uppdatera komponenttaggens hjälp för att förebygga rotkomponenten App med WebAssemblyPrerendered:

      Ta bort:

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

      Lägg till

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

      Viktigt!

      Förberedande rendering stöds inte för autentiseringsändpunkter (/authentication/-vägsegment). Mer information finns i ASP.NET Core Blazor WebAssembly ytterligare säkerhetsscenarier.

  5. I slutpunktsmappning av Server-projektet i Program.cs, ändra fallback från index.html-filen till _Host.cshtml-sidan.

    Ta bort:

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

    Lägg till

    app.MapFallbackToPage("/_Host");
    
  6. Client Om projekten och Server använder en eller flera vanliga tjänster under förinläsningen ska du ta med tjänstregistreringarna i en metod som kan anropas från båda projekten. Mer information finns i ASP.NET Core Blazor beroendeinjektion.

  7. Kör projektet Server. Den värdbaserade Blazor WebAssembly appen förebyggs av Server projektet för klienter.

Konfiguration för inbäddning av Razor-komponenter i sidor eller vyer

Följande avsnitt och exempel för att bädda in Razor-komponenter från ClientBlazor WebAssembly-appen i sidor eller vyer av serverappen kräver ytterligare konfiguration.

Projektet Server måste ha följande filer och mappar.

Razor Sidor:

  • 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

Viktigt!

Användning av en layoutsida (_Layout.cshtml) med en komponenttagghjälp för en HeadOutlet komponent krävs för att styra <head> innehållet, till exempel sidans rubrik (PageTitle komponent) och andra huvudelement (HeadContent komponent). Mer information finns i Kontrollera huvudinnehåll i ASP.NET Core-apparBlazor.

De följande filerna kan erhållas genom att generera en app från ASP.NET Core-projektmallarna med:

  • Visual Studios nya verktyg för att skapa projekt.
  • Öppna ett kommandoskal och kör dotnet new webapp -o {PROJECT NAME} (Razor Sidor) eller dotnet new mvc -o {PROJECT NAME} (MVC). Alternativet -o|--output med ett värde för {PROJECT NAME} platshållaren ger ett namn till appen och skapar en mapp för appen.

Uppdatera namnområdena i den importerade _ViewImports.cshtml-filen så att de matchar de som används av Server-projektet som tar emot filerna.

Pages/_ViewImports.cshtml (Razor Sidor):

@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

Uppdatera den importerade layoutfilen, som är Pages/Shared/_Layout.cshtml för Razor-sidor eller Views/Shared/_Layout.cshtml för MVC.

Först, ta bort titeln och stilmallen från donatorprojektet, vilket är RPDonor.styles.css i följande exempel. Platshållaren {PROJECT NAME} representerar donatorprojektets appnamn.

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

Client Inkludera projektets formatmallar i layoutfilen. I följande exempel Client är BlazorHosted.Clientprojektets namnområde . Elementet <title> kan uppdateras samtidigt.

Placera följande rader i <head> layoutfilens innehåll:

<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" />

Den importerade layouten innehåller två Home (Index sida) och Privacy navigeringslänkar. För att få Home-länkarna att peka på den hostade Blazor WebAssembly-appen, ändra hyperlänkarna:

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

I en MVC-layoutfil:

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

Uppdatera elementets <footer> appnamn. I följande exempel används appnamnet BlazorHosted:

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

I det föregående exemplet representerar platshållaren {DATE} upphovsrättsdatumet i en app som genererats från Razor Pages- eller MVC-projektmallen.

För att få Privacy länken att leda till en sekretessida (Razor Sidor), lägg till en sekretessida i Server projektet.

Pages/Privacy.cshtml i Server projektet:

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

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

För en MVC-baserad sekretessvy, skapa en sekretessvy i Server-projektet.

View/Home/Privacy.cshtml i Server projektet:

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

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

I kontrollanten Home för MVC-appen returnerar du vyn.

Lägg till följande kod i Controllers/HomeController.cs:

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

Om du importerar filer från en givarapp måste du uppdatera alla namnområden i filerna så att de Server matchar projektets (till exempel BlazorHosted.Server).

Importera statiska tillgångar till Server-projektet från givarprojektets wwwroot-mapp.

  • wwwroot/css mapp och innehåll
  • wwwroot/js mapp och innehåll
  • wwwroot/lib mapp och innehåll

Om donatorprojektet är skapat från en ASP.NET Core-projektmall och filerna inte har modifierats, kan du kopiera hela wwwroot-mappen från donatorprojektet till Server-projektet och ta bort favicon-ikonfilen.

Varning

Undvik att placera den statiska resursen i både Client och Serverwwwroot mapparna. Om samma fil finns i båda mapparna kastas ett undantag eftersom den statiska asset i varje mapp delar samma webbrotsväg. Därför, värd en statisk resurs i antingen wwwroot-mappen, inte båda.

Efter att ha antagit den föregående konfigurationen, integrera Razor komponenter i sidor eller vyer av Server projektet. Använd vägledningen i följande avsnitt av denna artikel:

  • Rendera komponenter på en sida eller vy med Component Tag Helper
  • Rendera komponenter på en sida eller vy med en CSS-selektor

Rendera komponenter på en sida eller vy med hjälp av Component Tag Helper

Efter att ha konfigurerat lösningen, inklusive ytterligare konfigurationer, stöder Component Tag Helper två renderingslägen för att rendera en komponent från en Blazor WebAssembly app på en sida eller i en vy.

I det följande Razor Pages-exemplet renderas Counter-komponenten på en sida. För att göra komponenten interaktiv inkluderas Blazor WebAssembly-skriptet i sidans renderingssektion. För att undvika att använda det fullständiga namnområdet för Counter-komponenten med Component Tag Helper ({ASSEMBLY NAME}.Pages.Counter), lägg till en @using-direktiv för klientprojektets Pages-namnområde. I följande exempel Client är BlazorHosted.Clientprojektets namnområde .

I Server projektet, Pages/RazorPagesCounter1.cshtml:

@page
@using BlazorHosted.Client.Pages

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

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

Kör projektet Server. Gå till sidan Razor på /razorpagescounter1. Den förhandsrenderade Counter-komponenten är inbäddad på sidan.

RenderMode konfigurerar huruvida komponenten:

  • Är förhandsrenderad på sidan.
  • Återges som statisk HTML på sidan eller om den innehåller nödvändig information för att starta en Blazor app från användaragenten.

Mer information om komponenttagghjälpen, inklusive att skicka parametrar och RenderMode konfiguration, finns i Komponenttagghjälp i ASP.NET Core.

Ytterligare arbete kan krävas beroende på de statiska resurser som komponenterna använder och hur layout sidorna är organiserade i en app. Vanligtvis läggs skript till i en sidas eller visnings Scripts renderingssektion och stilmallar läggs till i layoutens <head> elementinnehåll.

Ange barninnehåll genom ett renderfragment.

Component Tag Helper stöder inte mottagning av en RenderFragment delegering för underordnat innehåll (till exempel, param-ChildContent="..."). Vi rekommenderar att du skapar en Razor-komponent (.razor) som refererar till den komponent du vill rendera tillsammans med det barninnehåll du vill lämna över, och sedan kalla på Razor-komponenten från sidan eller vyn.

Säkerställ att översta nivån av förrenderade komponenter inte tas bort vid publicering.

Om en Component Tag Helper direkt refererar till en komponent från ett bibliotek som kan beskäras vid publicering, kan komponenten beskäras bort under publiceringen eftersom det inte finns några referenser till den från klientens app-kod. Som ett resultat av detta för-renderas inte komponenten, vilket lämnar ett tomt utrymme i utdata. Om detta inträffar instruerar du trimmern att bevara bibliotekskomponenten genom att lägga till ett DynamicDependency attribut till alla klasser i klientsidans app. För att bevara en komponent kallad SomeLibraryComponentToBePreserved, lägg till följande i valfri komponent:

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

Den tidigare metoden är vanligtvis inte nödvändig eftersom appen normalt förrenders sina komponenter (som inte är beskurna), som i sin tur refererar till komponenter från bibliotek (vilket gör att de också inte beskärs). Använd endast DynamicDependency explicit för att förframställa en bibliotekskomponent direkt när biblioteket är föremål för beskärning.

Rendera komponenter på en sida eller vy med en CSS-selektor

Efter konfigurering av lösningen, inklusive ytterligare konfigurering, lägg till rotkomponenter i Client projektet av en värdbaserad Blazor WebAssembly lösning i Program.cs filen. I följande exempel deklareras komponenten Counter som en rotkomponent med en CSS-väljare som väljer elementet med id det som matchar counter-component. I följande exempel Client är BlazorHosted.Clientprojektets namnområde .

I Program.cs-filen i Client-projektet, lägg till namnområdet för projektets Razor-komponenter högst upp i filen.

using BlazorHosted.Client.Pages;

Efter att builder är etablerad i Program.cs, lägg till Counter komponenten som en rotkomponent:

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

I det följande Razor Pages-exemplet renderas Counter-komponenten på en sida. För att göra komponenten interaktiv inkluderas Blazor WebAssembly-skriptet i sidans renderingssektion.

I Server projektet, Pages/RazorPagesCounter2.cshtml:

@page

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

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

Kör projektet Server. Gå till sidan Razor på /razorpagescounter2. Den förhandsrenderade Counter-komponenten är inbäddad på sidan.

Ytterligare arbete kan krävas beroende på de statiska resurser som komponenterna använder och hur layout sidorna är organiserade i en app. Vanligtvis läggs skript till i en sidas eller visnings Scripts renderingssektion och stilmallar läggs till i layoutens <head> elementinnehåll.

Anmärkning

Det föregående exemplet kastar ett JSException om en Blazor WebAssembly app är förkonstruerad och integrerad i en Razor Pages- eller MVC-app samtidigt med användning av en CSS-väljare. Navigera till en av projektets Client komponenter eller navigera till en sida eller vy av Razor med en inbäddad komponent kastar ett eller flera Server.

Det här är ett normalt beteende eftersom förinläsning och integrering av en Blazor WebAssembly app med dirigerbara Razor komponenter inte är kompatibel med användningen av CSS-väljare.

Om du har arbetat med exemplen i föregående avsnitt och bara vill se CSS-väljaren arbeta i exempelappen kommenterar du ut specifikationen App för rotkomponenten i Client projektets Program.cs fil:

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

Navigera till sidan eller vyn med den inbäddade Razor-komponenten som använder en CSS-selektor (till exempel /razorpagescounter2 i det föregående exemplet). Sidan eller vyn läses in med den inbäddade komponenten och de inbäddade komponentfunktionerna som förväntat.

Bevara fördefinierat tillstånd

Utan att det förgenererade tillståndet bevaras går tillståndet som används under förgenereringen förlorat och måste återskapas när appen är fullt inladdad. Om något tillstånd konfigureras asynkront kan användargränssnittet flimra när det förinstallerade användargränssnittet ersätts med tillfälliga platshållare och sedan återges helt igen.

För att lösa dessa problem stödjer Blazor bestående tillstånd på en förberenderad sida med hjälp av Tag Helper för att bevara komponenttillstånd. Lägg till Tag Helper-taggen <persist-component-state /> inuti den avslutande </body>-taggen.

Pages/_Layout.cshtml:

<body>
    ...

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

Bestäm vilket tillstånd som ska sparas med hjälp av PersistentComponentState tjänsten. PersistentComponentState.RegisterOnPersisting registrerar ett återanrop för att bevara komponenttillståndet innan appen pausas. Tillståndet hämtas när applikationen återupptas. Gör anropet i slutet av initieringskoden för att undvika ett potentiellt låsningstillstånd under appavstängningen.

Följande exempel är en uppdaterad version av FetchData-komponenten i en värd Blazor WebAssembly app baserad på Blazor-projektmallen. Komponenten WeatherForecastPreserveState bevarar väderprognostillståndet under förinläsningen och hämtar sedan tillståndet för att initiera komponenten. Persist Component State Tag Helper bevarar komponentens tillstånd efter alla komponentanrop.

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

Genom att initiera komponenter med samma tillstånd som används under förinläsningen körs eventuella dyra initieringssteg bara en gång. Det renderade användargränssnittet matchar också det förinstallerade användargränssnittet, så inget flimmer förekommer i webbläsaren.

Det beständiga förinstallerade tillståndet överförs till klienten, där det används för att återställa komponenttillståndet. För föråtergivning i en värdbaserad Blazor WebAssembly app exponeras data för webbläsaren och får inte innehålla känslig, privat information.

Ytterligare Blazor WebAssembly resurser

Prerendering kan förbättra sökmotoroptimering (SEO) genom att återge innehåll för det första HTTP-svaret som sökmotorer kan använda för att beräkna sidrankning.

Lösningskonfiguration

Förkonfigurationsinställningar

Så här konfigurerar du prerendering för en värdbaserad Blazor WebAssembly app:

  1. Värd för Blazor WebAssembly appen i en ASP.NET Core-app. En fristående Blazor WebAssembly app kan läggas till i en ASP.NET Core-lösning, eller så kan du använda en värd Blazor WebAssembly app skapad från Blazor WebAssembly projektmallen med värdalternativet:

    • Visual Studio: I dialogrutan Ytterligare information markerar du kryssrutan ASP.NET Core Hosted när du Blazor WebAssembly skapar appen. I den här artikelns exempel heter BlazorHostedlösningen .
    • Visual Studio Code/.NET CLI-kommandogränssnittet: dotnet new blazorwasm -ho (använd alternativet -ho|--hosted ). Använd alternativet -o|--output {LOCATION} för att skapa en mapp för lösningen och ställ in lösningens projektnamnrymder. I exemplen i den här artikeln är lösningen namngiven BlazorHosted (dotnet new blazorwasm -ho -o BlazorHosted).

    För exemplen i den här artikeln är BlazorHosted.Clientklientprojektets namnområde , och serverprojektets namnområde är BlazorHosted.Server.

  2. Ta bortwwwroot/index.html filen från Blazor WebAssemblyClient projektet.

  3. I Client-projektet, radera följande rad i Program.cs:

    - builder.RootComponents.Add<App>("#app");
    
  4. Lägg till en Pages/_Host.cshtml fil i Server projektets Pages mapp. Du kan hämta en _Host.cshtml fil från ett projekt som skapats från mallen dotnet new blazorserver -o BlazorServerBlazor Server med kommandot i ett kommandogränssnitt (-o BlazorServeralternativet skapar en mapp för projektet). När du har placerat Pages/_Host.cshtml-filen i Server-projektet för den värdbaserade Blazor WebAssembly-lösningen, gör följande ändringar i filen:

    • Ange ett @using direktiv för Client projektet (till exempel @using BlazorHosted.Client).

    • Uppdatera stilkods-länkarna så att de pekar på WebAssembly-projektets stilark. I följande exempel är klientprojektets namnrymd 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" />
      

      Anmärkning

      Lämna <link>-elementet som begär Bootstrap-stilmallen (css/bootstrap/bootstrap.min.css) på plats.

    • render-mode Uppdatera komponenttaggens hjälp för att förebygga rotkomponenten App med WebAssemblyPrerendered:

      - <component type="typeof(App)" render-mode="ServerPrerendered" />
      + <component type="typeof(App)" render-mode="WebAssemblyPrerendered" />
      
    • Blazor Uppdatera skriptkällan så att skriptet på klientsidan Blazor WebAssembly används:

      - <script src="_framework/blazor.server.js"></script>
      + <script src="_framework/blazor.webassembly.js"></script>
      
  5. I Startup.Configure projektet Server ändrar du återställningen index.html från filen till sidan _Host.cshtml .

    Startup.cs:

    - endpoints.MapFallbackToFile("index.html");
    + endpoints.MapFallbackToPage("/_Host");
    
  6. Client Om projekten och Server använder en eller flera vanliga tjänster under förinläsningen ska du ta med tjänstregistreringarna i en metod som kan anropas från båda projekten. Mer information finns i ASP.NET Core Blazor beroendeinjektion.

  7. Kör projektet Server. Den värdbaserade Blazor WebAssembly appen förebyggs av Server projektet för klienter.

Konfiguration för inbäddning av Razor-komponenter i sidor eller vyer

Följande avsnitt och exempel i denna artikel för inbäddning av komponenter från klientappen i sidor eller vyer av serverappen kräver ytterligare konfiguration.

Använd en standard Razor Pages- eller MVC-layoutfil i Server projektet. Projektet Server måste ha följande filer och mappar.

Razor Sidor:

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

MVC:

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

Hämta de föregående filerna från en app skapad från Razor Pages- eller MVC-projektmallen. För mer information, se Handledning: Kom igång med Razor Pages i ASP.NET Core eller Kom igång med ASP.NET Core MVC.

Uppdatera namnområdena i den importerade _ViewImports.cshtml-filen så att de matchar de som används av Server-projektet som tar emot filerna.

Uppdatera den importerade layoutfilen (_Layout.cshtml) för att inkludera Client-projektets stilar. I följande exempel Client är BlazorHosted.Clientprojektets namnområde . Elementet <title> kan uppdateras samtidigt.

Pages/Shared/_Layout.cshtml (Razor Sidor) eller 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>

Den importerade layouten innehåller Home och Privacy navigeringslänkar. För att få Home-länken att peka på den hostade Blazor WebAssembly-appen, ändra hyperlänken.

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

I en MVC-layoutfil:

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

För att göra så att Privacy-länken leder till en sekretessida, lägg till en sekretessida i Server-projektet.

Pages/Privacy.cshtml i Server projektet:

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

<h1>Privacy Policy</h1>

Om en MVC-baserad integritetsvy föredras, skapa en integritetsvy i Server-projektet.

View/Home/Privacy.cshtml:

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

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

I Home-kontrollern, returnera vyn.

Controllers/HomeController.cs:

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

Importera statiska tillgångar till Server-projektet från givarprojektets wwwroot-mapp.

  • wwwroot/css mapp och innehåll
  • wwwroot/js mapp och innehåll
  • wwwroot/lib mapp och innehåll

Om donatorprojektet är skapat från en ASP.NET Core-projektmall och filerna inte har modifierats, kan du kopiera hela wwwroot-mappen från donatorprojektet till Server-projektet och ta bort favicon-ikonfilen.

Varning

Undvik att placera den statiska resursen i både Client och Serverwwwroot mapparna. Om samma fil finns i båda mapparna kastas ett undantag eftersom den statiska asset i varje mapp delar samma webbrotsväg. Därför, värd en statisk resurs i antingen wwwroot-mappen, inte båda.

Rendera komponenter på en sida eller vy med hjälp av Component Tag Helper

Efter att ha konfigurerat lösningen, inklusive ytterligare konfigurationer, stöder Component Tag Helper två renderingslägen för att rendera en komponent från en Blazor WebAssembly app på en sida eller i en vy.

I det följande Razor Pages-exemplet renderas Counter-komponenten på en sida. För att göra komponenten interaktiv inkluderas Blazor WebAssembly-skriptet i sidans renderingssektion. För att undvika att använda det fullständiga namnområdet för Counter-komponenten med Component Tag Helper ({ASSEMBLY NAME}.Pages.Counter), lägg till en @using-direktiv för klientprojektets Pages-namnområde. I följande exempel Client är BlazorHosted.Clientprojektets namnområde .

I Server projektet, Pages/RazorPagesCounter1.cshtml:

@page
@using BlazorHosted.Client.Pages

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

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

Kör projektet Server. Gå till sidan Razor på /razorpagescounter1. Den förhandsrenderade Counter-komponenten är inbäddad på sidan.

RenderMode konfigurerar huruvida komponenten:

  • Är förhandsrenderad på sidan.
  • Återges som statisk HTML på sidan eller om den innehåller nödvändig information för att starta en Blazor app från användaragenten.

Mer information om komponenttagghjälpen, inklusive att skicka parametrar och RenderMode konfiguration, finns i Komponenttagghjälp i ASP.NET Core.

Ytterligare arbete kan krävas beroende på de statiska resurser som komponenterna använder och hur layout sidorna är organiserade i en app. Vanligtvis läggs skript till i en sidas eller visnings Scripts renderingssektion och stilmallar läggs till i layoutens <head> elementinnehåll.

Rendera komponenter på en sida eller vy med en CSS-selektor

Efter att ha konfigurerat lösningen, inklusive ytterligare konfiguration, lägg till rotkomponenter till Client-projektet av en värd Blazor WebAssembly-lösning i Program.cs. I följande exempel deklareras komponenten Counter som en rotkomponent med en CSS-väljare som väljer elementet med id det som matchar counter-component. I följande exempel Client är BlazorHosted.Clientprojektets namnområde .

I Program.cs av Client-projektet, lägg till namnområdet för projektets Razor-komponenter högst upp i filen.

using BlazorHosted.Client.Pages;

Efter att builder är etablerad i Program.cs, lägg till Counter komponenten som en rotkomponent:

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

I det följande Razor Pages-exemplet renderas Counter-komponenten på en sida. För att göra komponenten interaktiv inkluderas Blazor WebAssembly-skriptet i sidans renderingssektion.

I Server projektet, Pages/RazorPagesCounter2.cshtml:

@page

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

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

Kör projektet Server. Gå till sidan Razor på /razorpagescounter2. Den förhandsrenderade Counter-komponenten är inbäddad på sidan.

Ytterligare arbete kan krävas beroende på de statiska resurser som komponenterna använder och hur layout sidorna är organiserade i en app. Vanligtvis läggs skript till i en sidas eller visnings Scripts renderingssektion och stilmallar läggs till i layoutens <head> elementinnehåll.

Anmärkning

Det föregående exemplet kastar ett JSException om en Blazor WebAssembly-app förrenderas och integreras i en Razor Pages- eller MVC-app samtidigt med en CSS-väljare. När man navigerar till en av projektets komponenter ClientRazor genereras följande undantag:

Microsoft.JSInterop.JSException: Kunde inte hitta något element som matchar selektorn '#counter-component'.

Det här är ett normalt beteende eftersom förinläsning och integrering av en Blazor WebAssembly app med dirigerbara Razor komponenter inte är kompatibel med användningen av CSS-väljare.

Ytterligare Blazor WebAssembly resurser

Integrering av Razor komponenter i Razor Pages- eller MVC-appar i en värdbaseradBlazor WebAssembly lösning stöds i ASP.NET Core i .NET 5 eller senare. Välj en .NET 5- eller senare version av den här artikeln.