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

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

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

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

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

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

По умолчанию для шаблона библиотеки классов Razor (RCL) используется разработка компонентов Razor. При выборе параметра Представления и страницы поддержки поддерживаются страницы и представления. Дополнительные сведения о поддержке RCL см. в Blazorстатье "Использование компонентов ASP.NET Core Razor из 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. В файл _Layout.cshtml можно добавить теги <partial>:

<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, выполните указанные ниже действия.

  1. Ссылка на Microsoft.TypeScript.MSBuild пакет NuGet в проекте.

    Примечание.

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

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

  3. Укажите папку wwwroot в качестве выходного пути сборки TypeScript. Задайте свойство 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");
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();

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

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

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

  • Ресурсы 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") и нажмите кнопку >Создать. Чтобы избежать конфликта имени файла с созданной библиотекой представлений, проверьте, что имя библиотеки не заканчивается на .Views.
  • Если должны поддерживаться представления, установите флажок Представления и страницы поддержки. По умолчанию поддерживаются только страницы Razor Pages. Нажмите кнопку создания.

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

Добавьте файлы 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. В файл _Layout.cshtml можно добавить теги <partial>:

<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. Укажите папку wwwroot в качестве выходного пути сборки TypeScript. Задайте свойство 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 создается манифест, в котором описывается расположение статических веб-ресурсов. Использующее библиотеку приложение считывает манифест во время выполнения для получения ресурсов из связанных проектов и пакетов. При добавлении нового ресурса в библиотеку RCL ее необходимо перестроить, чтобы обновить манифест. Только после этого приложение сможет получить доступ к новому ресурсу.

Публикация

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

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

В библиотеку классов Razor (RCL) можно встроить представления Razor, страницы, контроллеры, модели страниц, компоненты Razor, компоненты представления. 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.

Ссылка на содержимое 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. В файл _Layout.cshtml можно добавить теги <partial>:

<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. Укажите папку wwwroot в качестве выходного пути сборки TypeScript. Задайте свойство 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> в файле проекта библиотеки), используйте идентификатор пакета, указанный в файле проекта для {PACKAGE ID} при проверке папки wwwroot для опубликованных ресурсов.

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

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

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

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

  • В меню Файл Visual Studio откройте меню Создать>Проект.
  • Выберите Веб-приложение ASP.NET Core.
  • Назовите библиотеку (например, "RazorClassLib") и нажмите кнопку >ОК. Чтобы избежать конфликта имени файла с созданной библиотекой представлений, проверьте, что имя библиотеки не заканчивается на .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 с содержимым в папке ~/Pages, а не ~/Areas/Pages, см. в разделе Макет страниц RCL.

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

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

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

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

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

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

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

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

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

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

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

  • В меню Файл Visual Studio откройте меню Создать>Проект.
  • Выберите Веб-приложение ASP.NET Core.
  • Присвойте приложению имя RazorUIClassLib>ОК.
  • Убедитесь, что выбрано 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. В файл _Layout.cshtml можно добавить теги <partial>:

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

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

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

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

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

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

Добавьте файлы 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 и конечные точки в ведущем приложении:

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. В файл _Layout.cshtml можно добавить теги <partial>:

<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. Укажите папку wwwroot в качестве выходного пути сборки TypeScript. Задайте свойство 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> в файле проекта библиотеки), используйте идентификатор пакета, указанный в файле проекта для {PACKAGE ID} при проверке папки wwwroot для опубликованных ресурсов.

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