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


Создание многоразового пользовательского интерфейса с помощью проекта библиотеки классов Razor в ASP.NET Core

Автор: Рик Андерсон (Rick Anderson)

В библиотеку классов Razor (RCL) можно встроить представления, страницы, контроллеры, модели страниц, компоненты , View-компоненты и модели данных Razor. RCL можно упаковать и использовать повторно. Приложения могут включать RCL и переопределять содержащиеся в нем представления и страницы. При обнаружении представления, частичного представления или страницы Razor как в веб-приложении, так и в RCL приоритетное значение имеет разметка Razor (файл .cshtml) в веб-приложении.

Сведения о том, как интегрировать npm и webpack в процесс сборки для RCL, см. в разделе "Сборка клиентских веб-ресурсов для Razor библиотеки классов".

Создание библиотеки классов с пользовательским интерфейсом Razor

  • В Visual Studio выберите Создать проект.
  • Выберите RazorБиблиотека классов>Далее.
  • Присвойте библиотеке имя (например, RazorClassLib), >create. Чтобы избежать конфликта имени файла с созданной библиотекой представлений, проверьте, что имя библиотеки не заканчивается на .Views.
  • Выберите страницы поддержки и представления, если необходимо, чтобы библиотека содержала страницы или представления. По умолчанию поддерживаются только компоненты Razor. Нажмите кнопку создания.

Шаблон библиотеки классов Razor по умолчанию служит для разработки компонентов Razor. При выборе параметра Представления и страницы поддержки поддерживаются страницы и представления. Дополнительные сведения о поддержке RCL см. в Blazorстатье "Использование компонентов ASP.NET Core Razor из Razor библиотеки классов (RCL)".

Добавьте файлы Razor в библиотеку RCL.

В шаблонах ASP.NET Core предполагается, что содержимое RCL находится в папке Areas. См. раздел Макет страниц RCL ниже, чтобы создать библиотеку RCL, которая отображает содержимое в ~/Pages, а не в ~/Areas/Pages.

Ссылка на содержимое RCL

На RCL могут ссылаться:

Переопределение представлений, частичных представлений и страниц

При обнаружении представления, частичного представления или страницы Razor и в веб-приложении, и в RCL приоритет имеет разметка Razor (файл .cshtml) в веб-приложении. Например, если вы добавите WebApp1/Areas/MyFeature/Pages/Page1.cshtml в WebApp1, Page1 в WebApp1 будет иметь приоритет над Page1 в RCL.

В примере загрузки переименуйте WebApp1/Areas/MyFeature2 в WebApp1/Areas/MyFeature, чтобы задать приоритет теста.

Скопируйте частичное представление RazorUIClassLib/Areas/MyFeature/Pages/Shared/_Message.cshtml в WebApp1/Areas/MyFeature/Pages/Shared/_Message.cshtml. Обновите разметку, чтобы указать новое расположение. Скомпилируйте и запустите приложение, чтобы убедиться, что используется версия частичной реализации в приложении.

Если RCL использует Razor Pages, активируйте службы и конечные точки Razor Pages в хост-приложении.

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddControllersWithViews();
builder.Services.AddRazorPages();

var app = builder.Build();

if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Home/Error");
    app.UseHsts();
}

app.UseHttpsRedirection();
app.UseStaticFiles();

app.UseRouting();

app.UseAuthorization();

app.MapControllerRoute(
    name: "default",
    pattern: "{controller=Home}/{action=Index}/{id?}");

app.MapRazorPages();
app.Run();

Макет страниц RCL

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

  • RazorUIClassLib/Pages
  • RazorUIClassLib/Pages/Shared

Предположим, что RazorUIClassLib/Pages/Shared содержит два частичных файла: _Header.cshtml и _Footer.cshtml. В файл <partial> можно добавить теги _Layout.cshtml:

<body>
  <partial name="_Header">
  @RenderBody()
  <partial name="_Footer">
</body>

Добавьте файл _ViewStart.cshtml в папку Pages проекта RCL, чтобы использовать файл _Layout.cshtml из ведущего веб-приложения:

@{
    Layout = "_Layout";
}

Создание библиотеки RCL со статическими ресурсами

Для библиотеки RCL могут быть необходимы сопутствующие статические элементы, на которые может ссылаться либо сама RCL-библиотека, либо приложение, использующее эту библиотеку. ASP.NET Core позволяет создавать библиотеки RCL со статическими ресурсами, которые доступны использующим библиотеки приложениям.

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

При упаковке RCL все сопутствующие ресурсы в папке wwwroot автоматически включаются в пакет.

Используйте команду dotnet pack, а не NuGet.exe версии nuget pack.

Добавьте клиентские веб-ресурсы в процесс сборки

Интеграция клиентских веб-ресурсов в конвейер сборки является нетривиальной. Дополнительные сведения см. статью «Создание клиентских веб-ресурсов для библиотеки Razor классов».

Исключение статических ресурсов

Чтобы исключить статические ресурсы, добавьте путь исключения в группу свойств $(DefaultItemExcludes) в файле проекта. Записи следует разделять точкой с запятой (;).

В следующем примере таблица стилей lib.css в папкеwwwroot не считается статическим ресурсом и не включается в опубликованную библиотеку RCL:

<PropertyGroup>
  <DefaultItemExcludes>$(DefaultItemExcludes);wwwroot\lib.css</DefaultItemExcludes>
</PropertyGroup>

Интеграция с TypeScript

Чтобы включить файлы TypeScript в библиотеку RCL, выполните указанные ниже действия.

  • Подключите пакет NuGet Microsoft.TypeScript.MSBuild в проекте.

    Примечание.

    Рекомендации по добавлению пакетов в приложения .NET см. в разделе Способы установки пакетов NuGet в статье Рабочий процесс использования пакета (документация по NuGet). Проверьте правильность версий пакета на сайте NuGet.org.

  • Поместите файлы TypeScript (.ts) в папку, отличную от wwwroot. Например, их можно поместить в папку Client.

  • Добавьте следующую разметку в файл проекта:

    • Настройте выходные данные сборки TypeScript для папки wwwroot с помощью свойства TypescriptOutDir.
    • Включите целевой объект TypeScript в качестве зависимости целевого объекта PrepareForBuildDependsOn.
    • Удалите вывод в wwwroot folder.
<Project Sdk="Microsoft.NET.Sdk.Razor">

  <PropertyGroup>
    // Markup removed for brevity.
    <TypescriptOutDir>wwwroot</TypescriptOutDir>
    <PrepareForBuildDependsOn>
      CompileTypeScriptWithTSConfig;
      GetTypeScriptOutputForPublishing;$(PrepareForBuildDependsOn)
    </PrepareForBuildDependsOn>
  </PropertyGroup>

  <ItemGroup>
    <Content Remove="wwwroot\{path-to-typescript-outputs}" />
  </ItemGroup>

</Project>

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

Файлы в папке wwwroot библиотеки RCL доступны для самой библиотеки RCL или использующего приложения под префиксом _content/{PACKAGE ID}/. Например, библиотека с именем сборки Razor.Class.Lib и без указания <PackageId> в файле проекта приводит к формированию пути к статическому контенту в _content/Razor.Class.Lib/. При создании пакета NuGet имя сборки не совпадает с идентификатором пакета (<PackageId> в файле проекта библиотеки), используйте идентификатор пакета, как указано в файле проекта для {PACKAGE ID}.

Использующее библиотеку приложение ссылается на предоставляемые ею статические ресурсы с помощью тегов HTML <script>, <style>, <img> и других. Для приложения-потребителя необходимо включить поддержку статических файлов следующим образом:

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddControllersWithViews();
builder.Services.AddRazorPages();

var app = builder.Build();

if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Home/Error");
    app.UseHsts();
}

app.UseHttpsRedirection();
app.UseStaticFiles();

app.UseRouting();

app.UseAuthorization();

app.MapControllerRoute(
    name: "default",
    pattern: "{controller=Home}/{action=Index}/{id?}");

app.MapRazorPages();
app.Run();

Когда приложение запускается из результата сборки (dotnet run), в среде разработки статические веб-ресурсы включаются по умолчанию. Для поддержки ресурсов в других средах при запуске из выходного пути сборки вызовите метод UseStaticWebAssets построителя узла в файле Program.cs:

var builder = WebApplication.CreateBuilder(args);

builder.WebHost.UseWebRoot("wwwroot");
builder.WebHost.UseStaticWebAssets();

builder.Services.AddRazorPages();

var app = builder.Build();

if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Error");
    app.UseHsts();
}

app.UseHttpsRedirection();
app.UseStaticFiles();

app.UseRouting();

app.UseAuthorization();

app.MapRazorPages();

app.Run();

При запуске приложения из опубликованного выхода (UseStaticWebAssets) вызывать dotnet publish не нужно.

Процесс разработки нескольких проектов

Когда запускается потребляющее приложение:

  • Ресурсы RCL остаются в исходных папках. Активы не перемещаются в потребляющее приложение.
  • Любые изменения в папке wwwroot библиотеки RCL отражаются в приложении после перестроения RCL, причем приложение перестраивать не требуется.

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

Публикация

При публикации приложения сопутствующие ресурсы из всех связанных проектов и пакетов копируются в папку wwwroot опубликованного приложения в папке _content/{PACKAGE ID}/. При создании пакета NuGet, если имя сборки не совпадает с идентификатором пакета (<PackageId> в файле проекта библиотеки), используйте идентификатор пакета, указанный в файле проекта для {PACKAGE ID} при проверке папки wwwroot на наличие опубликованных ресурсов.

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

В библиотеку классов Razor (RCL) можно встроить представления Razor, страницы, контроллеры, модели страниц, компоненты Razor, компоненты представлений, и модели данных. RCL можно упаковать и использовать повторно. Приложения могут включать RCL и переопределять представления и страницы, содержащиеся в нем. При обнаружении представления, частичного представления или страницы Razor и в веб-приложении, и в RCL приоритет имеет разметка Razor (файл .cshtml) в веб-приложении.

Для получения информации о том, как интегрировать npm и webpack в процесс сборки библиотеки классов, см. раздел Сборка клиентских веб-ресурсов для Razor библиотеки Razor классов.

Создание библиотеки классов с пользовательским интерфейсом Razor

  • В Visual Studio выберите Создать проект.
  • Выберите RazorБиблиотека классов>Далее.
  • Присвойте библиотеке имя (например, RazorClassLib), >create. Чтобы избежать конфликта имени файла с созданной библиотекой представлений, проверьте, что имя библиотеки не заканчивается на .Views.
  • Если должны поддерживаться представления, установите флажок Представления и страницы поддержки. По умолчанию поддерживаются только страницы Razor Pages. Нажмите кнопку создания.

Шаблон Razor библиотеки классов (RCL) предназначен для разработки компонентов по умолчанию. При выборе параметра Представления и страницы поддержки поддерживаются страницы и представления.

Добавьте файлы Razor в библиотеку RCL.

В шаблонах ASP.NET Core предполагается, что содержимое RCL находится в папке Areas. Проектируйте библиотеку RCL, которая раскрывает содержимое в ~/Pages, вместо ~/Areas/Pages. Подробнее см. в разделе Макет страницы RCL ниже.

Ссылка на содержимое RCL

На RCL могут ссылаться:

Переопределение представлений, частичных представлений и страниц

При обнаружении представления, частичного представления или страницы Razor как в веб-приложении, так и в RCL, приоритет имеет разметка Razor (файл .cshtml) в веб-приложении. Например, если вы добавите WebApp1/Areas/MyFeature/Pages/Page1.cshtml в WebApp1, Page1 в WebApp1 будет иметь приоритет над Page1 в RCL.

В примере загрузки переименуйте WebApp1/Areas/MyFeature2 в WebApp1/Areas/MyFeature, чтобы задать приоритет теста.

Скопируйте частичное представление RazorUIClassLib/Areas/MyFeature/Pages/Shared/_Message.cshtml в WebApp1/Areas/MyFeature/Pages/Shared/_Message.cshtml. Обновите разметку, чтобы указать новое расположение. Скомпилируйте и запустите приложение, чтобы убедиться, что используется версия частичного представления из приложения.

Если RCL использует Razor Pages, включите службы Razor Pages и конечные точки в хост-приложении.

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddControllersWithViews();
builder.Services.AddRazorPages();

var app = builder.Build();

if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Home/Error");
    app.UseHsts();
}

app.UseHttpsRedirection();
app.UseStaticFiles();

app.UseRouting();

app.UseAuthorization();

app.MapControllerRoute(
    name: "default",
    pattern: "{controller=Home}/{action=Index}/{id?}");

app.MapRazorPages();
app.Run();

Макет страниц RCL

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

  • RazorUIClassLib/Pages
  • RazorUIClassLib/Pages/Shared

Предположим, что RazorUIClassLib/Pages/Shared содержит два частичных файла: _Header.cshtml и _Footer.cshtml. В файл <partial> можно добавить теги _Layout.cshtml:

<body>
  <partial name="_Header">
  @RenderBody()
  <partial name="_Footer">
</body>

Добавьте файл _ViewStart.cshtml в папку Pages проекта RCL, чтобы использовать файл _Layout.cshtml из ведущего веб-приложения:

@{
    Layout = "_Layout";
}

Создание библиотеки RCL со статическими ресурсами

Для библиотеки RCL могут понадобиться связанные статические ресурсы, которые могут быть использованы как самой библиотекой RCL, так и приложением, использующим ее. ASP.NET Core позволяет создавать библиотеки RCL со статическими ресурсами, которые доступны использующим библиотеки приложениям.

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

При упаковке RCL все сопутствующие ресурсы в папке wwwroot автоматически включаются в пакет.

Используйте команду dotnet pack, а не NuGet.exe версии nuget pack.

Исключение статических ресурсов

Чтобы исключить статические ресурсы, добавьте путь исключения в группу свойств $(DefaultItemExcludes) в файле проекта. Записи следует разделять точкой с запятой (;).

В следующем примере таблица стилей lib.css в папкеwwwroot не считается статическим ресурсом и не включается в опубликованную библиотеку RCL:

<PropertyGroup>
  <DefaultItemExcludes>$(DefaultItemExcludes);wwwroot\lib.css</DefaultItemExcludes>
</PropertyGroup>

Интеграция с TypeScript

Чтобы включить файлы TypeScript в библиотеку RCL, выполните указанные ниже действия.

  1. Добавьте ссылку на пакет NuGet Microsoft.TypeScript.MSBuild в проекте.

    Примечание.

    Рекомендации по добавлению пакетов в приложения .NET см. в разделе Способы установки пакетов NuGet в статье Рабочий процесс использования пакета (документация по NuGet). Проверьте правильность версий пакета на сайте NuGet.org.

  2. Поместите файлы TypeScript (.ts) в папку, отличную от wwwroot. Например, их можно поместить в папку Client.

  3. Настройте выходные данные сборки TypeScript для папки wwwroot. Задайте свойство TypescriptOutDir внутри PropertyGroup в файле проекта.

    <TypescriptOutDir>wwwroot</TypescriptOutDir>
    
  4. Включите целевой объект TypeScript в качестве зависимости целевого объекта PrepareForBuildDependsOn, добавив следующий целевой объект в группу PropertyGroup в файле проекта:

    <PrepareForBuildDependsOn>
      CompileTypeScript;
      GetTypeScriptOutputForPublishing;$(PrepareForBuildDependsOn)
    </PrepareForBuildDependsOn>
    

Потребление контента из ссылочной библиотеки RCL

Файлы, находящиеся в папке wwwroot библиотеки RCL, открыты для самой библиотеки RCL или для использующего приложения под префиксом _content/{PACKAGE ID}/. Например, библиотека с именем сборки Razor.Class.Lib и без указания <PackageId> в файле проекта приводит к указанию пути к статическому содержимому в _content/Razor.Class.Lib/. При создании пакета NuGet имя сборки не совпадает с идентификатором пакета (<PackageId> в файле проекта библиотеки), используйте идентификатор пакета, как указано в файле проекта для {PACKAGE ID}.

Использующее библиотеку приложение ссылается на предоставляемые ею статические ресурсы с помощью тегов HTML <script>, <style>, <img> и других. Для приложения-потребителя необходимо включить поддержку статических файлов следующим образом:

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddControllersWithViews();
builder.Services.AddRazorPages();

var app = builder.Build();

if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Home/Error");
    app.UseHsts();
}

app.UseHttpsRedirection();
app.UseStaticFiles();

app.UseRouting();

app.UseAuthorization();

app.MapControllerRoute(
    name: "default",
    pattern: "{controller=Home}/{action=Index}/{id?}");

app.MapRazorPages();
app.Run();

Когда приложение запускается из результатов сборки (dotnet run), статические веб-ресурсы в среде разработки включены по умолчанию. Для поддержки ресурсов в других средах при запуске из выходного пути сборки вызовите метод UseStaticWebAssets построителя хоста в Program.cs:

var builder = WebApplication.CreateBuilder(args);

builder.WebHost.UseWebRoot("wwwroot").UseStaticWebAssets();

builder.Services.AddRazorPages();

var app = builder.Build();

if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Error");
    app.UseHsts();
}

app.UseHttpsRedirection();
app.UseStaticFiles();

app.UseRouting();

app.UseAuthorization();

app.MapRazorPages();

app.Run();

Примечание. Для .NET 6 требуется только вызов builder.WebHost.UseWebRoot("wwwroot").UseStaticWebAssets. Дополнительные сведения см. здесь на GitHub.

При запуске приложения из опубликованного результата (dotnet publish) вызывать UseStaticWebAssets не нужно.

Процесс разработки нескольких проектов

При запуске потребляющего приложения

  • Ресурсы RCL остаются в исходных папках. Активы не перемещаются в приложение-потребитель.
  • Любые изменения в папке wwwroot библиотеки RCL отражаются в приложении, которое использует библиотеку, после её перестроения, и само приложение перестраивать не требуется.

При сборке библиотеки RCL создается манифест, в котором описывается расположение статических веб-ресурсов. Приложение-потребитель загружает манифест во время выполнения для получения ресурсов из связанных проектов и пакетов. При добавлении нового ресурса в библиотеку RCL её необходимо перестроить, чтобы обновить манифест. Только после этого приложение, использующее библиотеку, сможет получить доступ к новому ресурсу.

Публикация

При публикации приложения сопутствующие ресурсы из всех связанных проектов и пакетов копируются в папку wwwroot опубликованного приложения в папке _content/{PACKAGE ID}/. При создании пакета NuGet, если имя сборки не совпадает с идентификатором пакета (<PackageId> в файле проекта библиотеки), используйте указанный в файле проекта идентификатор пакета в случае рассмотрения папки wwwroot для опубликованных активов.

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

В библиотеку классов (RCL) можно встроить представления, страницы, контроллеры, модели страниц, компоненты , View components, а также модели данных . RCL можно упаковать и использовать повторно. Приложения могут включать компонент RCL и переопределять представления и страницы, содержащиеся в нем. При обнаружении представления, частичного представления или страницы Razor как в веб-приложении, так и в RCL, приоритет имеет разметка Razor (файл .cshtml) в веб-приложении.

Просмотреть или скачать образец кода (описание загрузки)

Создание библиотеки классов с пользовательским интерфейсом Razor

  • В Visual Studio выберите Создать проект.
  • Выберите RazorБиблиотека классов>Далее.
  • Присвойте библиотеке имя (например, "RazorClassLib"), >Создать>, Далее. Чтобы избежать конфликта имени файла с созданной библиотекой представлений, проверьте, что имя библиотеки не заканчивается на .Views.
  • Выберите целевую платформу. Установите флажок ☑ Support pages and views для поддержки страниц и представлений. По умолчанию поддерживаются только компоненты Razor. Нажмите кнопку создания.

Шаблон библиотеки классов Razor (RCL) по умолчанию предназначен для разработки компонентов Razor. Опция Страницы и представления поддержки поддерживает страницы и представления.

Добавьте файлы Razor в библиотеку RCL.

В шаблонах ASP.NET Core предполагается, что содержимое RCL находится в папке Areas. Чтобы создать библиотеку RCL, которая раскрывает содержимое в ~/Pages, а не ~/Areas/Pages, см. RCL Pages layout.

Ссылка на содержимое RCL

На RCL могут ссылаться:

Переопределение представлений, частичных представлений и страниц

Когда представление, частичное представление или страница Razor находятся и в веб-приложении, и в RCL, то разметка Razor (файл .cshtml) в веб-приложении имеет приоритет. Например, если вы добавите WebApp1/Areas/MyFeature/Pages/Page1.cshtml в WebApp1, Page1 в WebApp1 будет иметь приоритет над Page1 в RCL.

В примере загрузки переименуйте WebApp1/Areas/MyFeature2 в WebApp1/Areas/MyFeature, чтобы задать приоритет теста.

Скопируйте частичное представление RazorUIClassLib/Areas/MyFeature/Pages/Shared/_Message.cshtml в WebApp1/Areas/MyFeature/Pages/Shared/_Message.cshtml. Обновите разметку, чтобы указать новое расположение. Скомпилируйте и запустите приложение, чтобы убедиться, что используется версия частичного компонента приложения.

Макет страниц RCL

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

  • RazorUIClassLib/Pages
  • RazorUIClassLib/Pages/Shared

Предположим, что RazorUIClassLib/Pages/Shared содержит два частичных файла: _Header.cshtml и _Footer.cshtml. В файл <partial> можно добавить теги _Layout.cshtml:

<body>
  <partial name="_Header">
  @RenderBody()
  <partial name="_Footer">
</body>

Добавьте файл _ViewStart.cshtml в папку Pages проекта RCL, чтобы использовать файл _Layout.cshtml из ведущего веб-приложения:

@{
    Layout = "_Layout";
}

Создание библиотеки RCL со статическими ресурсами

Для библиотеки RCL могут потребоваться сопутствующие статические ресурсы, на которые может ссылаться либо сама данная библиотека RCL, либо приложение, использующее библиотеку. ASP.NET Core позволяет создавать библиотеки RCL со статическими ресурсами, которые доступны использующим библиотеки приложениям.

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

При упаковке RCL все сопутствующие ресурсы в папке wwwroot автоматически включаются в пакет.

Используйте команду dotnet pack, а не NuGet.exe версии nuget pack.

Исключение статических ресурсов

Чтобы исключить статические ресурсы, добавьте путь исключения в группу свойств $(DefaultItemExcludes) в файле проекта. Записи следует разделять точкой с запятой (;).

В следующем примере таблица стилей lib.css в папкеwwwroot не считается статическим ресурсом и не включается в опубликованную библиотеку RCL:

<PropertyGroup>
  <DefaultItemExcludes>$(DefaultItemExcludes);wwwroot\lib.css</DefaultItemExcludes>
</PropertyGroup>

Интеграция с TypeScript

Чтобы включить файлы TypeScript в библиотеку RCL, выполните указанные ниже действия.

  1. Добавьте пакет NuGet Microsoft.TypeScript.MSBuild в проект.

    Примечание.

    Рекомендации по добавлению пакетов в приложения .NET см. в разделе Способы установки пакетов NuGet в статье Рабочий процесс использования пакета (документация по NuGet). Проверьте правильность версий пакета на сайте NuGet.org.

  2. Поместите файлы TypeScript (.ts) в папку, отличную от wwwroot. Например, их можно поместить в папку Client.

  3. Настройте выходные данные сборки TypeScript для папки wwwroot. Установите свойство TypescriptOutDir внутри PropertyGroup в файле проекта.

    <TypescriptOutDir>wwwroot</TypescriptOutDir>
    
  4. Включите целевой объект TypeScript в качестве зависимости целевого объекта ResolveCurrentProjectStaticWebAssets, добавив следующий целевой объект в группу PropertyGroup в файле проекта:

    <ResolveCurrentProjectStaticWebAssetsInputsDependsOn>
      CompileTypeScript;
      $(ResolveCurrentProjectStaticWebAssetsInputs)
    </ResolveCurrentProjectStaticWebAssetsInputsDependsOn>
    

Потребление контента из связанной библиотеки RCL

Файлы в папке wwwroot библиотеки RCL предоставляются самой библиотеке RCL или использующему приложению по префиксу _content/{PACKAGE ID}/. Например, библиотека с именем сборки Razor.Class.Lib и без указания <PackageId> в файле проекта приводит к указанию пути к статическому содержимому в _content/Razor.Class.Lib/. При создании пакета NuGet имя сборки не совпадает с идентификатором пакета (<PackageId> в файле проекта библиотеки), используйте идентификатор пакета, как указано в файле проекта для {PACKAGE ID}.

Использующее библиотеку приложение ссылается на предоставляемые ею статические ресурсы с помощью тегов HTML <script>, <style>, <img> и других. Для приложения необходимо включить поддержку статических файлов в Startup.Configure:

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    ...

    app.UseStaticFiles();

    ...
}

Когда приложение запускается из сборочного выхода (dotnet run), в среде разработки статические веб-ресурсы включены по умолчанию. Для поддержки ресурсов в других средах при запуске из выходного пути сборки выполните вызов UseStaticWebAssets у построителя хоста в Program.cs:

using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Hosting;

public class Program
{
    public static void Main(string[] args)
    {
        CreateHostBuilder(args).Build().Run();
    }

    public static IHostBuilder CreateHostBuilder(string[] args) =>
        Host.CreateDefaultBuilder(args)
            .ConfigureWebHostDefaults(webBuilder =>
            {
                webBuilder.UseStaticWebAssets();
                webBuilder.UseStartup<Startup>();
            });
}

При запуске приложения из опубликованного выхода (dotnet publish) вызов UseStaticWebAssets не требуется.

Процесс разработки нескольких проектов

При запуске использующего библиотеку приложения происходит следующее:

  • Ресурсы RCL остаются в исходных папках. Активы не перемещаются в потребляющее приложение.
  • Любые изменения в папке wwwroot библиотеки RCL отражаются в потребляющем приложении после перестроения RCL, и перестраивать само приложение при этом не требуется.

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

Публикация

При публикации приложения сопутствующие ресурсы из всех связанных проектов и пакетов копируются в папку wwwroot опубликованного приложения в папке _content/{PACKAGE ID}/. При создании пакета NuGet, когда имя сборки не совпадает с идентификатором пакета (<PackageId> в файле проекта библиотеки), используйте идентификатор пакета, указанный в файле проекта, чтобы проверить папку wwwroot на предмет опубликованных ресурсов.

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

В библиотеку классов Razor (RCL) можно встроить представления, страницы, контроллеры, модели страниц, компоненты Razor, компоненты представлений , и модели данных. RCL можно упаковать и использовать повторно. Приложения могут включать RCL и переопределять содержащиеся в нем представления и страницы. При обнаружении представления, частичного представления или страницы Razor как в веб-приложении, так и в RCL, приоритет имеет разметка Razor (файл .cshtml) в веб-приложении.

Просмотреть или скачать образец кода (описание загрузки)

Создание библиотеки классов с пользовательским интерфейсом Razor

  • В меню Файл Visual Studio откройте меню Создать>Проект.
  • Выберите Веб-приложение ASP.NET Core.
  • Назовите библиотеку (например, RazorClassLib) >OK. Чтобы избежать конфликта имени файла с созданной библиотекой представлений, проверьте, что имя библиотеки не заканчивается на .Views.
  • Убедитесь, что выбрано ASP.NET Core 2.1 или более поздней версии.
  • Выберите RazorБиблиотека классов>ОК.

У библиотеки RCL имеется следующий файл проекта:

<Project Sdk="Microsoft.NET.Sdk.Razor">

    <PropertyGroup>
        <TargetFramework>netcoreapp3.1</TargetFramework>
        <AddRazorSupportForMvc>true</AddRazorSupportForMvc>
    </PropertyGroup>

    <ItemGroup>
        <FrameworkReference Include="Microsoft.AspNetCore.App" />
    </ItemGroup>


</Project>

Добавьте файлы Razor в библиотеку RCL.

В шаблонах ASP.NET Core предполагается, что содержимое RCL находится в папке Areas. Смотрите раздел Оформление страниц RCL, чтобы создать библиотеку RCL, которая отображает содержимое в ~/Pages, а не в ~/Areas/Pages.

Ссылка на содержимое RCL

На RCL могут ссылаться:

Пошаговая инструкция: Создание проекта RCL и использование в проекте Pages Razor.

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

Тестирование приложения загрузки

Если вы еще не загрузили завершенное приложение и вместо этого хотите создать проект пошагового руководства, перейдите к следующему разделу.

.sln Откройте файл в Visual Studio. Запустить приложение.

Следуйте инструкциям в разделе Тестирование WebApp1

Создание библиотеки RCL

В этом разделе создается библиотека повторно используемых компонентов (RCL). Файлы Razor добавляются в RCL.

Создание проекта RCL:

  • В меню Файл Visual Studio откройте меню Создать>Проект.
  • Выберите Веб-приложение ASP.NET Core.
  • Назовите приложение RazorUIClassLib>OK.
  • Убедитесь, что выбрано ASP.NET Core 2.1 или более поздней версии.
  • Выберите RazorБиблиотека классов>ОК.
  • Добавьте файл частичного представления Razor с именем RazorUIClassLib/Areas/MyFeature/Pages/Shared/_Message.cshtml.

Добавление файлов и папок Razor в проект

  • Замените разметку в RazorUIClassLib/Areas/MyFeature/Pages/Shared/_Message.cshtml следующем коде:

    <h3>_Message.cshtml partial view.</h3>
    
    <p>RazorUIClassLib\Areas\MyFeature\Pages\Shared\_Message.cshtml</p>
    
  • Замените разметку в RazorUIClassLib/Areas/MyFeature/Pages/Page1.cshtml следующем коде:

    @page
    @addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
    
    <h2>Hello from a Razor UI class library!</h2>
    <p> From  RazorUIClassLib\Areas\MyFeature\Pages\Page1.cshtml</p>
    
    <partial name="_Message" />
    

    @addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers требуется для использования частичного представления (<partial name="_Message" />). Вместо включения @addTagHelper директивы можно добавить _ViewImports.cshtml файл. Например:

    dotnet new viewimports -o RazorUIClassLib/Areas/MyFeature/Pages
    

    Дополнительные сведения о _ViewImports.cshtml см. в разделе Импорт общих директив.

  • Создайте библиотеку классов, чтобы убедиться в отсутствии ошибок компилятора:

    dotnet build RazorUIClassLib
    

Выходные данные сборки содержат RazorUIClassLib.dll и RazorUIClassLib.Views.dll. RazorUIClassLib.Views.dll содержит скомпилированное содержимое Razor.

Использование библиотеки пользовательского интерфейса Razor в проекте Razor Pages

Создание веб-приложения Razor Pages:

  • В Обозревателе решений щелкните решение правой кнопкой мыши >Добавить>Новый проект.

  • Выберите Веб-приложение ASP.NET Core.

  • Назовите приложение WebApp1.

  • Убедитесь, что выбрано ASP.NET Core 2.1 или более поздней версии.

  • Выберите Веб-приложение>OK.

  • В обозревателе решений щелкните правой кнопкой мыши WebApp1 и выберите Назначить запускаемым проектом.

  • В обозревателе решений щелкните правой кнопкой мыши WebApp1 и выберите Зависимости сборки>Зависимости проекта.

  • Отметьте RazorUIClassLib как зависимость от WebApp1.

  • В обозревателе решений щелкните правой кнопкой мыши WebApp1 и выберите Добавить>Ссылка.

  • В диалоговом окне Диспетчер ссылок нажмите RazorUIClassLib>ОК.

Запустить приложение.

Тест WebApp1

Перейдите по адресу /MyFeature/Page1, чтобы убедиться в том, что используется библиотека классов пользовательского интерфейса Razor.

Переопределение представлений, частичных представлений и страниц

При наличии представления, частичного представления или страницы Razor как в веб-приложении, так и в RCL, приоритет имеет разметка Razor (файл .cshtml) в веб-приложении. Например, если вы добавите WebApp1/Areas/MyFeature/Pages/Page1.cshtml в WebApp1, Page1 в WebApp1 будет иметь приоритет над Page1 в RCL.

В примере загрузки переименуйте WebApp1/Areas/MyFeature2 в WebApp1/Areas/MyFeature, чтобы задать приоритет теста.

Скопируйте частичное представление RazorUIClassLib/Areas/MyFeature/Pages/Shared/_Message.cshtml в WebApp1/Areas/MyFeature/Pages/Shared/_Message.cshtml. Обновите разметку, чтобы указать новое расположение. Скомпилируйте и запустите приложение, чтобы убедиться, что используется частичная версия приложения.

Макет страниц RCL

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

  • RazorUIClassLib/Pages
  • RazorUIClassLib/Pages/Shared

Предположим, что RazorUIClassLib/Pages/Shared содержит два частичных файла: _Header.cshtml и _Footer.cshtml. В файл <partial> можно добавить теги _Layout.cshtml:

<body>
  <partial name="_Header">
  @RenderBody()
  <partial name="_Footer">
</body>

В библиотеку классов Razor (RCL) можно встроить представления, страницы, контроллеры, модели страниц, компоненты Razor, компоненты представления , и модели данных. RCL можно упаковать и использовать повторно. Приложения могут включать RCL и переопределять содержащиеся в нем представления и страницы. При обнаружении представления, частичного представления или страницы Razor как в веб-приложении, так и в RCL, приоритет имеет разметка Razor (файл .cshtml) из веб-приложения.

Просмотреть или скачать образец кода (описание загрузки)

Создание библиотеки классов с пользовательским интерфейсом Razor

  • В Visual Studio выберите Создать проект.
  • Выберите RazorБиблиотека классов>Далее.
  • Присвойте библиотеке имя (например, RazorClassLib), >create. Чтобы избежать конфликта имени файла с созданной библиотекой представлений, проверьте, что имя библиотеки не заканчивается на .Views.
  • Если должны поддерживаться представления, установите флажок Представления и страницы поддержки. По умолчанию поддерживаются только Razor страницы. Нажмите кнопку создания.

Шаблон библиотеки классов Razor (RCL) по умолчанию предназначен для разработки компонентов Razor. При выборе параметра Поддержка страниц и представлений поддерживаются страницы и представления.

Добавьте файлы Razor в библиотеку RCL.

В шаблонах ASP.NET Core предполагается, что содержимое RCL находится в папке Areas. См. макет страниц RCL ниже, чтобы создать RCL, который содержит контент в ~/Pages, а не в ~/Areas/Pages.

Ссылка на содержимое RCL

На RCL могут ссылаться:

Переопределение представлений, частичных представлений и страниц

При наличии представления, частичного представления или страницы Razor как в веб-приложении, так и в RCL, приоритет имеет разметка Razor (файл .cshtml) из веб-приложения. Например, если вы добавите WebApp1/Areas/MyFeature/Pages/Page1.cshtml в WebApp1, Page1 в WebApp1 будет иметь приоритет над Page1 в RCL.

В примере загрузки переименуйте WebApp1/Areas/MyFeature2 в WebApp1/Areas/MyFeature, чтобы задать приоритет теста.

Скопируйте частичное представление RazorUIClassLib/Areas/MyFeature/Pages/Shared/_Message.cshtml в WebApp1/Areas/MyFeature/Pages/Shared/_Message.cshtml. Обновите разметку, чтобы указать новое расположение. Скомпилируйте и запустите приложение, чтобы убедиться, что используется частичная версия из приложения.

Если RCL использует Razor Pages, включите службы Razor Pages и конечные точки в хостовом приложении:

public void ConfigureServices(IServiceCollection services)
{
    services.AddControllersWithViews();
    services.AddRazorPages();
}

public void Configure(IApplicationBuilder app)
{
    app.UseStaticFiles();
    app.UseRouting();
    app.UseEndpoints(endpoints =>
    {
        endpoints.MapControllerRoute(
            name: "default",
            pattern: "{controller=Home}/{action=Index}/{id?}");

        endpoints.MapRazorPages();
    });
}

Макет страниц RCL

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

  • RazorUIClassLib/Pages
  • RazorUIClassLib/Pages/Shared

Предположим, что RazorUIClassLib/Pages/Shared содержит два частичных файла: _Header.cshtml и _Footer.cshtml. В файл <partial> можно добавить теги _Layout.cshtml:

<body>
  <partial name="_Header">
  @RenderBody()
  <partial name="_Footer">
</body>

Добавьте файл _ViewStart.cshtml в папку Pages проекта RCL, чтобы использовать файл _Layout.cshtml из ведущего веб-приложения:

@{
    Layout = "_Layout";
}

Создание библиотеки RCL со статическими ресурсами

Для библиотеки RCL могут потребоваться сопутствующие статические активы, которые могут быть использованы либо самой библиотекой RCL, либо приложением, которое её использует. ASP.NET Core позволяет создавать библиотеки RCL со статическими ресурсами, которые доступны использующим библиотеки приложениям.

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

При упаковке RCL все сопутствующие ресурсы в папке wwwroot автоматически включаются в пакет.

Используйте команду dotnet pack, а не NuGet.exe версии nuget pack.

Исключение статических ресурсов

Чтобы исключить статические ресурсы, добавьте путь исключения в группу свойств $(DefaultItemExcludes) в файле проекта. Записи следует разделять точкой с запятой (;).

В следующем примере таблица стилей lib.css в папкеwwwroot не считается статическим ресурсом и не включается в опубликованную библиотеку RCL:

<PropertyGroup>
  <DefaultItemExcludes>$(DefaultItemExcludes);wwwroot\lib.css</DefaultItemExcludes>
</PropertyGroup>

Интеграция с TypeScript

Чтобы включить файлы TypeScript в библиотеку RCL, выполните указанные ниже действия.

  1. Добавьте пакет Microsoft.TypeScript.MSBuild NuGet в проект.

    Примечание.

    Рекомендации по добавлению пакетов в приложения .NET см. в разделе Способы установки пакетов NuGet в статье Рабочий процесс использования пакета (документация по NuGet). Проверьте правильность версий пакета на сайте NuGet.org.

  2. Поместите файлы TypeScript (.ts) в папку, отличную от wwwroot. Например, их можно поместить в папку Client.

  3. Настройте вывод сборки TypeScript для папки wwwroot. Задайте свойство TypescriptOutDir внутри PropertyGroup в файле проекта:

    <TypescriptOutDir>wwwroot</TypescriptOutDir>
    
  4. Включите целевой объект TypeScript в качестве зависимости целевого объекта ResolveCurrentProjectStaticWebAssets, добавив следующий целевой объект в группу PropertyGroup в файле проекта:

    <ResolveCurrentProjectStaticWebAssetsInputsDependsOn>
      CompileTypeScript;
      $(ResolveCurrentProjectStaticWebAssetsInputs)
    </ResolveCurrentProjectStaticWebAssetsInputsDependsOn>
    

Использовать содержимое из относящейся к RCL библиотеки

Файлы, размещенные в папке wwwroot библиотеки RCL, доступны как для самой библиотеки RCL, так и для использующего ее приложения под префиксом _content/{PACKAGE ID}/. Например, библиотека с именем сборки Razor.Class.Lib и без указания <PackageId> в файле проекта приводит к пути к статическому содержимому в _content/Razor.Class.Lib/. При создании пакета NuGet имя сборки не совпадает с идентификатором пакета (<PackageId> в файле проекта библиотеки), используйте идентификатор пакета, как указано в файле проекта для {PACKAGE ID}.

Использующее библиотеку приложение ссылается на предоставляемые ею статические ресурсы с помощью тегов HTML <script>, <style>, <img> и других. Для приложения необходимо включить поддержку статических файлов в Startup.Configure:

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    ...

    app.UseStaticFiles();

    ...
}

Когда приложение запускается из результатов сборки (dotnet run), в среде разработки статические веб-ресурсы включены по умолчанию. Для поддержки ресурсов в других средах при запуске из выходного пути сборки вызовите UseStaticWebAssets на построителе хоста в Program.cs:

using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Hosting;

public class Program
{
    public static void Main(string[] args)
    {
        CreateHostBuilder(args).Build().Run();
    }

    public static IHostBuilder CreateHostBuilder(string[] args) =>
        Host.CreateDefaultBuilder(args)
            .ConfigureWebHostDefaults(webBuilder =>
            {
                webBuilder.UseStaticWebAssets();
                webBuilder.UseStartup<Startup>();
            });
}

Не нужно вызывать UseStaticWebAssets, когда вы запускаете приложение из опубликованного выхода (dotnet publish).

Процесс разработки нескольких проектов

При запуске потребляющего приложения:

  • Ресурсы RCL остаются в исходных папках. Активы не перемещаются в приложение-потребитель.
  • Любые изменения в папке wwwroot библиотеки RCL отражаются в приложении после перестроения библиотеки RCL, причем приложение перестраивать не требуется.

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

Публикация

При публикации приложения сопутствующие ресурсы из всех связанных проектов и пакетов копируются в папку wwwroot опубликованного приложения в папке _content/{PACKAGE ID}/. При создании пакета NuGet, если имя сборки не совпадает с идентификатором пакета (<PackageId> в файле проекта библиотеки), используйте идентификатор пакета, указанный в файле проекта для {PACKAGE ID}, при проверке папки wwwroot с опубликованными ресурсами.

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