Dela via


Dela tillgångar mellan webbklienter och interna klienter med hjälp av ett Razor klassbibliotek (RCL)

Obs

Det här är inte den senaste versionen av den här artikeln. Den aktuella versionen finns i den .NET 9-versionen av den här artikeln.

Varning

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

Viktig

Den här informationen gäller en förhandsversionsprodukt som kan ändras avsevärt innan den släpps kommersiellt. Microsoft lämnar inga garantier, uttryckliga eller underförstådda, med avseende på den information som tillhandahålls här.

Den aktuella versionen finns i den .NET 9-versionen av den här artikeln.

Använd ett Razor klassbibliotek (RCL) för att dela Razor komponenter, C#-kod och statiska tillgångar i webb- och interna klientprojekt.

Den här artikeln bygger på de allmänna begrepp som finns i följande artiklar:

Exemplen i den här artikeln delar tillgångar mellan en Blazor app på serversidan och en .NET MAUIBlazor Hybrid app i samma lösning:

  • Även om en Blazor app på serversidan används gäller vägledningen lika för Blazor WebAssembly appar som delar tillgångar med en Blazor Hybrid app.
  • Projekt finns i samma lösning, men en RCL kan tillhandahålla delade tillgångar till projekt utanför en lösning.
  • RCL läggs till som ett projekt i lösningen, men alla RCL:er kan publiceras som ett NuGet-paket. Ett NuGet-paket kan tillhandahålla delade tillgångar till webb- och interna klientprojekt.
  • Ordningen som projekten skapas i är inte viktig. Projekt som förlitar sig på en RCL för tillgångar måste dock skapa en projektreferens till RCL-efter att RCL har skapats.

Vägledning om hur du skapar en RCL finns i Använda ASP.NET Core Razor-komponenter från ett Razor-klassbibliotek (RCL). Du kan också få tillgång till ytterligare vägledning om RCL:er som gäller allmänt för ASP.NET Core-appar i Återanvändbart Razor användargränssnitt i klassbibliotek för ASP.NET Core.

Målramverk för ClickOnce-distributioner

Om du vill publicera ett WPF- eller Windows Forms-projekt med ett Razor-klassbibliotek (RCL) i .NET 6 med ClickOncemåste RCL:en rikta net6.0-windows utöver net6.0.

Exempel:

<TargetFrameworks>net6.0;net6.0-windows</TargetFrameworks>

Mer information finns i följande artiklar:

Exempelapp

Ett exempel på de scenarier som beskrivs i den här artikeln finns i eShop Reference Application (AdventureWorks) (dotnet/eShop GitHub-lagringsplats). Den .NET MAUIBlazor Hybrid appen finns i mappen src/HybridApp.

En version av exempelappen som är anpassad för Azure hosting finns i Azure-Samples/eShopOnAzure GitHub repository.

Exempelappen visar följande tekniker:

Dela komponenter, kod och statiska resurser i webbgränssnittet Razor

Komponenter från en RCL kan delas samtidigt av webbappar och interna klientappar som skapats med hjälp av Blazor. I vägledningen i Consume ASP.NET Core components from a class library (RCL) (Consume ASP.NET Core components from a class library (RCL) ( Class Library) (RCL) förklarar hur du delar komponenter med hjälp av ett -klassbibliotek (RCL). Samma vägledning gäller för återanvändning av Razor komponenter från en RCL i en Blazor Hybrid app.

Komponentnamnområden härleds från RCL:s paket-ID eller sammansättningsnamn och komponentens mappsökväg inom RCL. Mer information finns i ASP.NET Core Razor-komponenter. @using direktiv kan placeras i _Imports.razor filer för komponenter och kod, vilket i följande exempel visas för en RCL med namnet SharedLibrary med en Shared mapp med delade Razor komponenter och en Data mapp med delade dataklasser:

@using SharedLibrary
@using SharedLibrary.Shared
@using SharedLibrary.Data

Placera delade statiska tillgångar i RCL:s wwwroot-mapp och uppdatera sökvägar för statiska tillgångar i appen för att använda följande sökvägsformat:

_content/{PACKAGE ID/ASSEMBLY NAME}/{PATH}/{FILE NAME}

Platshållare:

  • {PACKAGE ID/ASSEMBLY NAME}: Paket-ID eller sammansättningsnamn för RCL.
  • {PATH}: Valfri sökväg i RCL:s wwwroot mapp.
  • {FILE NAME}: Filnamnet för den statiska tillgången.

Föregående sökvägsformat används också i appen för statiska tillgångar som tillhandahålls av ett NuGet-paket som lagts till i RCL.

För en RCL med namnet SharedLibrary och med den minifierade Bootstrap-formatmallen som exempel:

_content/SharedLibrary/css/bootstrap/bootstrap.min.css

Mer information om hur du delar statiska tillgångar mellan projekt finns i följande artiklar:

Rotfilen index.html är vanligtvis specifik för appen och bör finnas kvar i Blazor Hybrid-appen eller den Blazor WebAssembly appen. Filen index.html delas vanligtvis inte.

Rotkomponenten Razor (App.razor eller Main.razor) kan delas, men kan ofta behöva vara specifik för värdappen. Till exempel är App.razor olika i serversidans Blazor- och Blazor WebAssembly-projektmallar när autentisering är aktiverat. Du kan lägga till parametern AdditionalAssemblies för att ange platsen för delade routningsbara komponenter, och du kan ange en delad standardlayoutkomponent för routern efter typnamn.

Tillhandahålla kod och tjänster oberoende av värdmodell

När koden måste skilja sig åt mellan värdmodeller eller målplattformar abstraherar du koden som gränssnitt och matar in tjänstimplementeringarna i varje projekt.

Följande exempel på väderdata sammanfattar olika implementeringar av väderprognostjänsten:

  • Använda en HTTP-begäran för Blazor Hybrid och Blazor WebAssembly.
  • Begära data direkt för en Blazor app på serversidan.

I exemplet används följande specifikationer och konventioner:

  • RCL:en heter SharedLibrary och innehåller följande mappar och namnområden:
    • Data: Innehåller klassen WeatherForecast, som fungerar som en modell för väderdata.
    • Interfaces: Innehåller tjänstgränssnittet för tjänstimplementeringarna med namnet IWeatherForecastService.
  • Komponenten FetchData underhålls i mappen Pages för RCL, som kan dirigeras av någon av de appar som använder RCL.
  • Varje Blazor app har en tjänstimplementering som implementerar IWeatherForecastService-gränssnittet.

Data/WeatherForecast.cs i RCL:

namespace SharedLibrary.Data;

public class WeatherForecast
{
    public DateTime Date { get; set; }
    public int TemperatureC { get; set; }
    public int TemperatureF => 32 + (int)(TemperatureC / 0.5556);
    public string? Summary { get; set; }
}

Interfaces/IWeatherForecastService.cs i RCL:

using SharedLibrary.Data;

namespace SharedLibrary.Interfaces;

public interface IWeatherForecastService
{
    Task<WeatherForecast[]?> GetForecastAsync(DateTime startDate);
}

Den _Imports.razor filen i RCL innehåller följande tillagda namnområden:

@using SharedLibrary.Data
@using SharedLibrary.Interfaces

Services/WeatherForecastService.cs i apparna Blazor Hybrid och Blazor WebAssembly:

using System.Net.Http.Json;
using SharedLibrary.Data;
using SharedLibrary.Interfaces;

namespace {APP NAMESPACE}.Services;

public class WeatherForecastService : IWeatherForecastService
{
    private readonly HttpClient http;

    public WeatherForecastService(HttpClient http)
    {
        this.http = http;
    }

    public async Task<WeatherForecast[]?> GetForecastAsync(DateTime startDate) =>
        await http.GetFromJsonAsync<WeatherForecast[]?>("WeatherForecast");
}

I föregående exempel är platshållaren {APP NAMESPACE} appens namespace.

Services/WeatherForecastService.cs i Blazor-appen på serversidan:

using SharedLibrary.Data;
using SharedLibrary.Interfaces;

namespace {APP NAMESPACE}.Services;

public class WeatherForecastService : IWeatherForecastService
{
    private static readonly string[] Summaries = 
    [
        "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot"
    ];

    public async Task<WeatherForecast[]?> GetForecastAsync(DateTime startDate) =>
        await Task.FromResult(Enumerable.Range(1, 5)
            .Select(index => new WeatherForecast
            {
                Date = startDate.AddDays(index),
                TemperatureC = Random.Shared.Next(-20, 55),
                Summary = Summaries[Random.Shared.Next(Summaries.Length)]
            }).ToArray());
}

I föregående exempel är platshållaren {APP NAMESPACE} appens namnområde.

Apparna Blazor Hybrid, Blazor WebAssemblyoch Blazor på serversidan registrerar sina implementeringar av väderprognostjänsten (Services.WeatherForecastService) för IWeatherForecastService.

Projektet Blazor WebAssembly registrerar även en HttpClient. Den HttpClient som har registrerats i en app som skapats från Blazor WebAssembly-projektmallen räcker för detta ändamål. Mer information finns i Anropa ett webb-API från en ASP.NET Core Blazor-app.

Pages/FetchData.razor i RCL:

@page "/fetchdata"
@inject IWeatherForecastService ForecastService

<PageTitle>Weather forecast</PageTitle>

<h1>Weather forecast</h1>

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

    protected override async Task OnInitializedAsync()
    {
        forecasts = await ForecastService.GetForecastAsync(DateTime.Now);
    }
}

Ytterligare resurser