Поделиться через


Совместное использование ресурсов между веб-клиентами и собственными клиентами Razor с помощью библиотеки классов (RCL)

Примечание.

Это не последняя версия этой статьи. В текущем выпуске см . версию .NET 9 этой статьи.

Предупреждение

Эта версия ASP.NET Core больше не поддерживается. Дополнительные сведения см. в политике поддержки .NET и .NET Core. В текущем выпуске см . версию .NET 9 этой статьи.

Внимание

Эта информация относится к предварительному выпуску продукта, который может быть существенно изменен до его коммерческого выпуска. Майкрософт не предоставляет никаких гарантий, явных или подразумеваемых, относительно приведенных здесь сведений.

В текущем выпуске см . версию .NET 9 этой статьи.

Используйте библиотеку Razor классов (RCL) для совместного использования Razor компонентов, кода C# и статических ресурсов в веб-проектах и собственных клиентских проектах.

Эта статья основана на общих понятиях, приведенных в следующих статьях:

Примеры, приведенные в этой статье, используют ресурсы между серверным Blazor приложением и .NET MAUIBlazor Hybrid приложением в одном решении:

  • Хотя используется серверное Blazor приложение, руководство применяется одинаково к Blazor WebAssembly приложениям, совместно используемым ресурсами с приложением Blazor Hybrid .
  • Проекты находятся в одном решении, но RCL может предоставлять общие ресурсы проектам за пределами решения.
  • RCL добавляется в качестве проекта в решение, но любой RCL можно опубликовать как пакет NuGet. Пакет NuGet может предоставлять общие ресурсы для веб-проектов и собственных клиентских проектов.
  • Порядок создания проектов не важен. Однако проекты, использующие RCL для ресурсов, должны создать ссылку на проект rCL после создания RCL.

Инструкции по созданию RCL см. в статье "Использование компонентов ASP.NET Core Razor из Razor библиотеки классов (RCL)". При необходимости обратитесь к дополнительным рекомендациям по RC-адресам, которые широко применяются к приложениям ASP.NET Core в пользовательском интерфейсе повторного использования Razor в библиотеках классов с ASP.NET Core.

Целевые платформы для развертываний ClickOnce

Чтобы опубликовать проект WPF или Windows Forms с библиотекой Razor классов (RCL) в .NET 6 с помощью ClickOnce, RCL должен быть предназначен net6.0-windows в дополнение к net6.0.

Пример:

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

Дополнительные сведения см. в следующих статьях:

Пример приложения

Пример сценариев, описанных в этой статье, смотрите в приложении eShop Reference Application (AdventureWorks) (dotnet/eShop репозиторий GitHub) . Приложение .NET MAUIBlazor Hybrid находится в папке src/HybridApp.

См. в GitHub-репозитории Azure-Samples/eShopOnAzureсведения о версии примера приложения, адаптированного для размещения в Azure.

Пример приложения демонстрирует следующие технологии:

Совместное использование компонентов веб-пользовательского интерфейса Razor , кода и статических ресурсов

Компоненты из RCL могут одновременно предоставляться веб-приложениями и собственными клиентскими приложениями, созданными с помощью Blazor. В руководстве по использованию компонентов ASP.NET Core Razor из Razor библиотеки классов (RCL) объясняется, как совместно Razor использовать компоненты с помощью Razor библиотеки классов (RCL). Это же руководство относится к повторному использованию Razor компонентов из RCL в Blazor Hybrid приложении.

Пространства имен компонентов являются производными от идентификатора пакета или имени сборки RCL и пути к папке компонента в RCL. Дополнительные сведения см. в статье Компоненты Razor ASP.NET Core. @using Директивы можно поместить в _Imports.razor файлы для компонентов и кода, как показано в следующем примере для RCL SharedLibrary с Shared папкой общих Razor компонентов и Data папкой общих классов данных:

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

Поместите общие статические ресурсы в папку RCL wwwroot и обновите пути статических ресурсов в приложении, чтобы использовать следующий формат пути:

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

Заполнители:

  • {PACKAGE ID/ASSEMBLY NAME}: идентификатор пакета или имя сборки RCL.
  • {PATH}: необязательный путь в папке RCL wwwroot .
  • {FILE NAME}: имя файла статического ресурса.

Предыдущий формат пути также используется в приложении для статических ресурсов, предоставленных пакетом NuGet, добавленным в RCL.

Для имени SharedLibrary RCL и использования минимальной таблицы стилей Bootstrap в качестве примера:

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

Дополнительные сведения о совместном использовании статических ресурсов в проектах см. в следующих статьях:

Корневой index.html файл обычно зависит от приложения и должен оставаться в Blazor Hybrid приложении или Blazor WebAssembly приложении. Файл index.html обычно не является общим.

Корневой Razor компонент (App.razor или Main.razor) может быть общим, но часто может быть конкретным для приложения размещения. Например, App.razor отличается в шаблонах серверов Blazor и Blazor WebAssembly проектов при включенной проверке подлинности. Вы можете добавить AdditionalAssemblies параметр , чтобы указать расположение всех общих routable компонентов, и можно указать общий компонент макета по умолчанию для маршрутизатора по имени типа.

Предоставление кода и служб независимо от модели размещения

Если код должен отличаться между моделями размещения или целевыми платформами, абстрагирует код как интерфейсы и внедряет реализации служб в каждый проект.

В следующем примере данных о погоде абстрагируются различные реализации службы прогнозирования погоды:

  • Использование HTTP-запроса для Blazor Hybrid и Blazor WebAssembly.
  • Запрос данных непосредственно для серверного Blazor приложения.

В примере используются следующие спецификации и соглашения:

  • RCL называется SharedLibrary и содержит следующие папки и пространства имен:
    • Data: содержит WeatherForecast класс, который служит моделью для погодных данных.
    • Interfaces: содержит интерфейс службы для реализаций служб с именем IWeatherForecastService.
  • Компонент FetchData сохраняется в Pages папке RCL, которая является маршрутизируемой любым из приложений, потребляющих RCL.
  • Каждое Blazor приложение поддерживает реализацию службы, реализующую IWeatherForecastService интерфейс.

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

using SharedLibrary.Data;

namespace SharedLibrary.Interfaces;

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

Файл _Imports.razor в RCL включает следующие добавленные пространства имен:

@using SharedLibrary.Data
@using SharedLibrary.Interfaces

Services/WeatherForecastService.csв приложениях и Blazor Hybrid приложениях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");
}

В предыдущем примере {APP NAMESPACE} заполнитель — это пространство имен приложения.

Services/WeatherForecastService.cs в серверном Blazor приложении:

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

В предыдущем примере {APP NAMESPACE} заполнитель — это пространство имен приложения.

Приложения на Blazor Hybridстороне Blazor WebAssemblyBlazorсервера регистрируют реализацию службы прогнозирования погоды (Services.WeatherForecastService) для IWeatherForecastService.

Проект Blazor WebAssembly также регистрирует HttpClient. Для HttpClient этого достаточно зарегистрированного в приложении, созданном Blazor WebAssembly на основе шаблона проекта. Дополнительные сведения см. в статье Вызов веб-API в приложении ASP.NET Core Blazor.

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

Дополнительные ресурсы