Freigeben von Ressourcen über Web- und native Clients mithilfe einer Razor-Klassenbibliothek (RCL)
Hinweis
Dies ist nicht die neueste Version dieses Artikels. Die aktuelle Version finden Sie in der .NET 9-Version dieses Artikels.
Warnung
Diese Version von ASP.NET Core wird nicht mehr unterstützt. Weitere Informationen finden Sie in der .NET- und .NET Core-Supportrichtlinie. Die aktuelle Version finden Sie in der .NET 9-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.
Die aktuelle Version finden Sie in der .NET 9-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:
- Nutzen von ASP.NET Core Razor-Komponenten über eine Razor-Klassenbibliothek (RCL)
- Razor-Benutzeroberfläche in Klassenbibliotheken mit ASP.NET Core
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:
Beispiel-App
Ein Beispiel für die in diesem Artikel beschriebenen Szenarien finden Sie in der eShop-Referenzanwendung (AdventureWorks) (dotnet/eShop
GitHub-Repository). Die .NET MAUIBlazor Hybrid-App befindet sich im ordner src/HybridApp
.
Eine Version der Beispiel-App, die auf das Azure-Hosting zugeschnitten ist, finden Sie im GitHub-Repository Azure-Samples/eShopOnAzure
.
Die Beispiel-App zeigt die folgenden Technologien:
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 Ordnerwwwroot
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:
- Nutzen von ASP.NET Core Razor-Komponenten über eine Razor-Klassenbibliothek (RCL)
- Razor-Benutzeroberfläche in Klassenbibliotheken mit ASP.NET Core
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 dieWeatherForecast
-Klasse, die als Modell für Wetterdaten dient.Interfaces
: Enthält die Dienstschnittstelle für die Dienstimplementierungen namensIWeatherForecastService
.
- Die
FetchData
-Komponente wird imPages
-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
- Nutzen von ASP.NET Core Razor-Komponenten über eine Razor-Klassenbibliothek (RCL)
- Razor-Benutzeroberfläche in Klassenbibliotheken mit ASP.NET Core
- CSS-Isolationsunterstützung mit Razor-Klassenbibliotheken