Freigeben über


Freigeben von Ressourcen über Web- und native Clients mithilfe einer Razor-Klassenbibliothek (RCL)

Hinweis

Dies ist nicht die neueste Version dieses Artikels. Informationen zum aktuellen Release finden Sie in der .NET 8-Version dieses Artikels.

Wichtig

Diese Informationen beziehen sich auf ein Vorabversionsprodukt, das vor der kommerziellen Freigabe möglicherweise noch wesentlichen Änderungen unterliegt. Microsoft gibt keine Garantie, weder ausdrücklich noch impliziert, hinsichtlich der hier bereitgestellten Informationen.

Informationen zum aktuellen Release finden Sie in der .NET 8-Version dieses Artikels.

Verwenden Sie eine Razor-Klassenbibliothek (RCL), um Razor-Komponenten, C#-Code und statische Ressourcen für Web- und native Clientprojekte freizugeben.

Dieser Artikel baut auf den allgemeinen Konzepten auf, die in den folgenden Artikeln behandelt werden:

In den Beispielen in diesem Artikel werden Ressourcen von einer serverseitigen Blazor-App und einer .NET MAUIBlazor Hybrid-App in derselben Lösung gemeinsam genutzt:

  • Obwohl eine serverseitige Blazor-App verwendet wird, gilt die Anleitung gleichermaßen für Blazor WebAssembly-Apps, die Ressourcen für eine Blazor Hybrid-App freigeben.
  • Die Projekte befinden sich in derselben Projektmappe, aber eine RCL kann freigegebene Ressourcen für Projekte außerhalb einer Projektmappe bereitstellen.
  • Die RCL wird als Projekt zur Projektmappe hinzugefügt, aber jede RCL kann als NuGet-Paket veröffentlicht werden. Ein NuGet-Paket kann freigegebene Ressourcen für Web- und native Clientprojekte bereitstellen.
  • Die Reihenfolge, in der die Projekte erstellt werden, ist nicht wichtig. Allerdings müssen Projekte, die sich auf Ressourcen einer RCL stützen, einen Projektverweis auf die RCL erstellen, nachdem die RCL erstellt worden ist.

Einen Leitfaden zum Erstellen von RCLs finden Sie unter Nutzen von ASP.NET Core Razor-Komponenten über eine Razor-Klassenbibliothek (RCL). Greifen Sie optional auf die zusätzlichen Anleitungen für RCLs zu, die allgemein für ASP.NET Core-Apps gelten und in Wiederverwendbare Razor-Benutzeroberfläche in Klassenbibliotheken mit ASP.NET Core zu finden sind.

Zielframeworks für ClickOnce-Bereitstellungen

Um ein WPF- oder Windows Forms-Projekt mit einer Razor-Klassenbibliothek (RCL) in .NET 6 mit ClickOnce zu veröffentlichen, muss die RCL net6.0-windows zusätzlich zu net6.0 als Ziel haben.

Beispiel:

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

Weitere Informationen finden Sie in den folgenden Artikeln:

Freigeben von Web-UI-Razor-Komponenten, Code und statischen Ressourcen

Komponenten aus einer RCL können von Web- und nativen Client-Apps, die mit Blazor erstellt werden, gemeinsam genutzt werden. In der Anleitung in Nutzen von ASP.NET Core Razor-Komponenten über eine Razor-Klassenbibliothek (RCL) wird erläutert, wie Razor-Komponenten mithilfe einer Razor-Klassenbibliothek (RCL) freigegeben werden. Die gleiche Anleitung gilt für die Wiederverwendung von Razor-Komponenten aus einer RCL in einer Blazor Hybrid-App.

Die Namespaces von Komponenten werden aus der Paket-ID oder dem Assemblynamen der RCL und dem Ordnerpfad der Komponente innerhalb des RCL abgeleitet. Weitere Informationen finden Sie unter Razor-Komponenten in ASP.NET Core. @using-Anweisungen können in _Imports.razor-Dateien für Komponenten und Code platziert werden, wie im folgenden Beispiel für eine RCL namens SharedLibrary mit dem Ordner Shared für freigegebene Razor-Komponenten und dem Ordner Data für freigegebene Datenklassen gezeigt wird:

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

Platzieren Sie freigegebene statische Ressourcen im Ordner wwwroot der RCL, und aktualisieren Sie statische Ressourcenpfade in der App, sodass das folgende Pfadformat verwendet wird:

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

Platzhalter:

  • {PACKAGE ID/ASSEMBLY NAME}: Die Paket-ID oder der Assemblyname der RCL.
  • {PATH}: Optionaler Pfad im Ordner wwwroot der RCL.
  • {FILE NAME}: Der Dateiname der statischen Ressource.

Das obige Pfadformat wird in der App auch für statische Ressourcen verwendet, die von einem der RCL hinzugefügten NuGet-Paket bereitgestellt werden.

Für eine RCL namens SharedLibrary und die Verwendung des verkleinerten Bootstrap-Stylesheets als Beispiel gilt:

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

Weitere Informationen zum Freigeben statischer Ressourcen für mehrere Projekte finden Sie in den folgenden Artikeln:

Die Stammdatei index.html ist für gewöhnlich App-spezifisch und sollte in der Blazor Hybrid-App oder der Blazor WebAssembly-App verbleiben. Die index.html-Datei wird in der Regel nicht freigegeben.

Die Stammkomponente Razor (App.razor oder Main.razor) kann freigegeben werden, muss aber oft für die Host-App spezifisch sein. So unterscheidet sich App.razor beispielsweise in den Projektvorlagen für serverseitige Blazor und Blazor WebAssembly, wenn die Authentifizierung aktiviert ist. Sie können den AdditionalAssemblies-Parameter hinzufügen, um den Speicherort aller freigegebenen Routingkomponenten anzugeben, und Sie können eine freigegebene Standardlayoutkomponente für den Router nach Typname angeben.

Bereitstellen von Code und Diensten unabhängig vom Hostingmodell

Wenn sich der Code für verschiedene Hostingmodelle oder Zielplattformen unterscheiden muss, abstrahieren Sie den Code als Schnittstellen und fügen Sie die Dienstimplementierungen in jedes Projekt ein.

Im folgenden Wetterdatenbeispiel werden verschiedene Implementierungen eines Wettervorhersagediensts abstrahiert:

  • Verwenden einer HTTP-Anforderung für Blazor Hybrid und Blazor WebAssembly.
  • Direktes Anfordern von Daten für eine serverseitige Blazor-App.

Im Beispiel werden die folgenden Spezifikationen und Konventionen verwendet:

  • Die RCL erhält den Namen SharedLibrary, und sie enthält die folgenden Ordner und Namespaces:
    • Data: Enthält die WeatherForecast-Klasse, die als Modell für Wetterdaten dient.
    • Interfaces: Enthält die Dienstschnittstelle für die Dienstimplementierungen namens IWeatherForecastService.
  • Die FetchData-Komponente wird im Pages-Ordner der RCL verwaltet, der von allen Apps, die die RCL verwenden, weitergeleitet werden kann.
  • Jede Blazor-App verwaltet eine Dienstimplementierung, welche die IWeatherForecastService-Schnittstelle implementiert.

Data/WeatherForecast.cs in der 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 in der RCL:

using SharedLibrary.Data;

namespace SharedLibrary.Interfaces;

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

Die _Imports.razor-Datei in der RCL enthält die folgenden hinzugefügten Namespaces:

@using SharedLibrary.Data
@using SharedLibrary.Interfaces

Services/WeatherForecastService.cs in den Blazor Hybrid- und Blazor WebAssembly-Apps:

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

Im Beispiel oben steht der Platzhalter {APP NAMESPACE} für den Namespace der App.

Services/WeatherForecastService.cs in der serverseitigen Blazor-App:

using SharedLibrary.Data;
using SharedLibrary.Interfaces;

namespace {APP NAMESPACE}.Services;

public class WeatherForecastService : IWeatherForecastService
{
    private static readonly string[] Summaries = new[]
    {
        "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());
}

Im Beispiel oben steht der Platzhalter {APP NAMESPACE} für den Namespace der App.

Die Blazor Hybrid-, Blazor WebAssembly- und serverseitigen Blazor-Apps registrieren ihre Implementierungen des Wettervorhersagediensts (Services.WeatherForecastService) für IWeatherForecastService.

Das Blazor WebAssembly-Projekt registriert auch einen HttpClient. Der HttpClient, der standardmäßig in einer mit der Blazor WebAssembly-Projektvorlage erstellten App registriert wird, ist für diesen Zweck ausreichend. Weitere Informationen finden Sie unter Aufrufen einer Web-API über eine ASP.NET Core Blazor-App.

Pages/FetchData.razor in der 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);
    }
}

Zusätzliche Ressourcen