在 ASP.NET Core 中使用 Razor 類別庫專案建立可重複使用的 UI

作者:Rick Anderson

您可以將 Razor 檢視、頁面、控制器、頁面模型、Razor 元件檢視元件和資料模型建置到 Razor 類別庫 (RCL) 中。 RCL 可以封裝和重複使用。 應用程式可以包括 RCL,以及覆寫它所包含的檢視和頁面。 在 Web 應用程式和 RCL 中,發現檢視、部分檢視或 Razor Page 時,應優先處理 Web 應用程式中的 Razor 標記 (.cshtml 檔案)。

如需如何將 npm 和 webpack 整合到 Razor 類別庫的建置流程的相關資訊,請參閱為 Razor 類別庫建置用戶端 Web 資產

建立包含 Razor UI 的類別庫

  • 從 Visual Studio 中,選取 [建立新專案]。
  • 選取 [Razor 類別庫]>[下一步]。
  • 命名程式庫 (例如 "RazorClassLib"),>[建立]。 若要避免與產生的檢視程式庫發生檔案名稱衝突,程式庫名稱結尾請務必不要使用 .Views
  • 如果您需要程式庫來包含頁面和/或檢視,請選取 [支援頁面和檢視]。 根據預設,僅支援 Razor 元件。 選取建立

預設情況下,Razor 類別庫 (RCL) 範本預設為 Razor 元件開發。 [支援頁面和檢視] 選項支援頁面和檢視。 如需關於 Blazor 中 RCL 支援的詳細資訊,請參閱從 Razor 類別庫 (RCL) 取用 ASP.NET Core Razor 元件

將 Razor 檔案新增至 RCL。

ASP.NET Core 範本假設 RCL 內容位於 Areas 資料夾中。 請參閱下面的 RCL 頁面配置,以建立在 ~/Pages (而不是 ~/Areas/Pages) 公開內容的 RCL。

參考 RCL 內容

RCL 可以由下列各項參考:

覆寫檢視、部分檢視和頁面

在 Web 應用程式和 RCL 中,發現檢視、部分檢視或 Razor Page 時,應優先處理 Web 應用程式中的 Razor 標記 (.cshtml 檔案)。 例如,將 WebApp1/Areas/MyFeature/Pages/Page1.cshtml 新增至 WebApp1,則 WebApp1 中 Page1 的優先順序將高於 RCL 中的 Page1。

在範例下載中,將 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 內容視為 Web 應用程式 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 檔案新增至 RCL 專案的 Pages 資料夾,以使用主機 Web 應用程式的 _Layout.cshtml 檔案:

@{
    Layout = "_Layout";
}

建立具有靜態資產的 RCL

RCL 可能需要 RCL 或 RCL 取用應用程式可以參考的附屬靜態資產。 ASP.NET Core 允許建立包含可供取用應用程式使用的靜態資產的 RCL。

若要在 RCL 中包含附屬資產,請在類別庫中建立 wwwroot 資料夾,並在該資料夾中包含所有必要的檔案。

封裝 RCL 時,wwwroot 資料夾中的所有附屬資產都會自動包含在套件中。

使用 dotnet pack 命令,而不是 NuGet.exe nuget pack 版。

將用戶端 Web 資產新增至建置程序

將用戶端 Web 資產整合到建置管線中並非易事。 如需詳細資訊,請參閱建置 Razor 類別庫的用戶端 Web 資產

排除靜態資產

若要排除靜態資產,請將所需的排除路徑新增至專案檔中的 $(DefaultItemExcludes) 屬性群組。 使用分號 (;) 來分隔項目。

在下列範例中,wwwroot 資料夾中的 lib.css 樣式表不視為靜態資產,且不包含在已發佈的 RCL 中:

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

TypeScript 整合

若要在 RCL 中包含 TypeScript 檔案,請執行下列作業:

  1. 參考專案中的 Microsoft.TypeScript.MSBuild NuGet 套件。

    注意

    如需將套件新增至 .NET 應用程式的指引,請參閱在套件取用工作流程 (NuGet 文件)安裝及管理套件底下的文章。 在 NuGet.org 確認正確的套件版本。

  2. 將 TypeScript 檔案 (.ts) 放在 wwwroot 資料夾外。 例如,將檔案放在 Client 資料夾中。

  3. 設定 wwwroot 資料夾的 TypeScript 建置輸出。 在專案檔中的 PropertyGroup 內設定 TypescriptOutDir 屬性:

    <TypescriptOutDir>wwwroot</TypescriptOutDir>
    
  4. 透過在專案檔中的 PropertyGroup 內新增下列目標,將 TypeScript 目標併入為 PrepareForBuildDependsOn 目標的相依性:

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

從參考的 RCL 取用內容

RCL 的 wwwroot 資料夾中所包含的檔案,會使用前置詞 _content/{PACKAGE ID}/ 公開給 RCL 或取用應用程式。 例如,某程式庫的組件名稱為 Razor.Class.Lib 且在專案檔中未指定 <PackageId>,則造成靜態內容路徑為 _content/Razor.Class.Lib/。 產生 NuGet 套件且組件名稱與套件 ID (程式庫的專案檔中的 <PackageId>) 不同時,請使用專案檔中針對 {PACKAGE ID} 指定的套件 ID。

取用應用程式會參考程式庫所提供的靜態資產,其中包含 <script><style><img> 和其他 HTML 標籤。 取用應用程式必須在以下位置啟用靜態檔案支援

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) 執行取用應用程式時,預設會在開發環境中啟用靜態 Web 資產。 若要在從建置輸出執行時支援其他環境中的資產,請在 Program.cs 中的主機建置器上呼叫 UseStaticWebAssets

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 中的資產會保留在原始資料夾。 資產不會移至取用應用程式。
  • 在重建 RCL 後,RCL 的 wwwroot 資料夾內的任何變更都會反映在取用應用程式中,且無需重建取用應用程式。

建置 RCL 時,會產生一份描述靜態 Web 資產位置的資訊清單。 取用應用程式會在執行階段讀取資訊清單,以取用參考的專案和套件的資產。 將新的資產新增至 RCL 時,必須先重建 RCL 以更新其資訊清單,然後取用應用程式才能存取新的資產。

發行

發佈應用程式時,所有參考專案和套件的附屬資產都會複製到已發佈應用程式的 wwwroot 資料夾的 _content/{PACKAGE ID}/ 下。 產生 NuGet 套件且組件名稱與套件 ID (程式庫的專案檔中的 <PackageId>) 不同時,請在檢查已發佈資產的 wwwroot 資料夾時,使用專案檔中針對 {PACKAGE ID} 指定的套件 ID。

其他資源

您可以將 Razor 檢視、頁面、控制器、頁面模型、Razor 元件檢視元件和資料模型建置到 Razor 類別庫 (RCL) 中。 RCL 可以封裝和重複使用。 應用程式可以包括 RCL,以及覆寫它所包含的檢視和頁面。 在 Web 應用程式和 RCL 中,發現檢視、部分檢視或 Razor Page 時,應優先處理 Web 應用程式中的 Razor 標記 (.cshtml 檔案)。

如需如何將 npm 和 webpack 整合到 Razor 類別庫的建置流程的相關資訊,請參閱為 Razor 類別庫建置用戶端 Web 資產

建立包含 Razor UI 的類別庫

  • 從 Visual Studio 中,選取 [建立新專案]。
  • 選取 [Razor 類別庫]>[下一步]。
  • 命名程式庫 (例如 "RazorClassLib"),>[建立]。 若要避免與產生的檢視程式庫發生檔案名稱衝突,程式庫名稱結尾請務必不要使用 .Views
  • 如果您需要支援檢視,請選取 [支援頁面和檢視]。 根據預設,僅支援 Razor Pages。 選取建立

預設情況下,Razor 類別庫 (RCL) 範本預設為 Razor 元件開發。 [支援頁面和檢視] 選項支援頁面和檢視。

將 Razor 檔案新增至 RCL。

ASP.NET Core 範本假設 RCL 內容位於 Areas 資料夾中。 請參閱下面的 RCL 頁面配置,以建立在 ~/Pages (而不是 ~/Areas/Pages) 公開內容的 RCL。

參考 RCL 內容

RCL 可以由下列各項參考:

覆寫檢視、部分檢視和頁面

在 Web 應用程式和 RCL 中,發現檢視、部分檢視或 Razor Page 時,應優先處理 Web 應用程式中的 Razor 標記 (.cshtml 檔案)。 例如,將 WebApp1/Areas/MyFeature/Pages/Page1.cshtml 新增至 WebApp1,則 WebApp1 中 Page1 的優先順序將高於 RCL 中的 Page1。

在範例下載中,將 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 內容視為 Web 應用程式 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 檔案新增至 RCL 專案的 Pages 資料夾,以使用主機 Web 應用程式的 _Layout.cshtml 檔案:

@{
    Layout = "_Layout";
}

建立具有靜態資產的 RCL

RCL 可能需要 RCL 或 RCL 取用應用程式可以參考的附屬靜態資產。 ASP.NET Core 允許建立包含可供取用應用程式使用的靜態資產的 RCL。

若要在 RCL 中包含附屬資產,請在類別庫中建立 wwwroot 資料夾,並在該資料夾中包含所有必要的檔案。

封裝 RCL 時,wwwroot 資料夾中的所有附屬資產都會自動包含在套件中。

使用 dotnet pack 命令,而不是 NuGet.exe nuget pack 版。

排除靜態資產

若要排除靜態資產,請將所需的排除路徑新增至專案檔中的 $(DefaultItemExcludes) 屬性群組。 使用分號 (;) 來分隔項目。

在下列範例中,wwwroot 資料夾中的 lib.css 樣式表不視為靜態資產,且不包含在已發佈的 RCL 中:

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

TypeScript 整合

若要在 RCL 中包含 TypeScript 檔案,請執行下列作業:

  1. 參考專案中的 Microsoft.TypeScript.MSBuild NuGet 套件。

    注意

    如需將套件新增至 .NET 應用程式的指引,請參閱在套件取用工作流程 (NuGet 文件)安裝及管理套件底下的文章。 在 NuGet.org 確認正確的套件版本。

  2. 將 TypeScript 檔案 (.ts) 放在 wwwroot 資料夾外。 例如,將檔案放在 Client 資料夾中。

  3. 設定 wwwroot 資料夾的 TypeScript 建置輸出。 在專案檔中的 PropertyGroup 內設定 TypescriptOutDir 屬性:

    <TypescriptOutDir>wwwroot</TypescriptOutDir>
    
  4. 透過在專案檔中的 PropertyGroup 內新增下列目標,將 TypeScript 目標併入為 PrepareForBuildDependsOn 目標的相依性:

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

從參考的 RCL 取用內容

RCL 的 wwwroot 資料夾中所包含的檔案,會使用前置詞 _content/{PACKAGE ID}/ 公開給 RCL 或取用應用程式。 例如,某程式庫的組件名稱為 Razor.Class.Lib 且在專案檔中未指定 <PackageId>,則造成靜態內容路徑為 _content/Razor.Class.Lib/。 產生 NuGet 套件且組件名稱與套件 ID (程式庫的專案檔中的 <PackageId>) 不同時,請使用專案檔中針對 {PACKAGE ID} 指定的套件 ID。

取用應用程式會參考程式庫所提供的靜態資產,其中包含 <script><style><img> 和其他 HTML 標籤。 取用應用程式必須在以下位置啟用靜態檔案支援

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) 執行取用應用程式時,預設會在開發環境中啟用靜態 Web 資產。 若要在從建置輸出執行時支援其他環境中的資產,請在 Program.cs 中的主機建置器上呼叫 UseStaticWebAssets

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 中的資產會保留在原始資料夾。 資產不會移至取用應用程式。
  • 在重建 RCL 後,RCL 的 wwwroot 資料夾內的任何變更都會反映在取用應用程式中,且無需重建取用應用程式。

建置 RCL 時,會產生一份描述靜態 Web 資產位置的資訊清單。 取用應用程式會在執行階段讀取資訊清單,以取用參考的專案和套件的資產。 將新的資產新增至 RCL 時,必須先重建 RCL 以更新其資訊清單,然後取用應用程式才能存取新的資產。

發行

發佈應用程式時,所有參考專案和套件的附屬資產都會複製到已發佈應用程式的 wwwroot 資料夾的 _content/{PACKAGE ID}/ 下。 產生 NuGet 套件且組件名稱與套件 ID (程式庫的專案檔中的 <PackageId>) 不同時,請在檢查已發佈資產的 wwwroot 資料夾時,使用專案檔中針對 {PACKAGE ID} 指定的套件 ID。

其他資源

您可以將 Razor 檢視、頁面、控制器、頁面模型、Razor 元件檢視元件和資料模型建置到 Razor 類別庫 (RCL) 中。 RCL 可以封裝和重複使用。 應用程式可以包括 RCL,以及覆寫它所包含的檢視和頁面。 在 Web 應用程式和 RCL 中,發現檢視、部分檢視或 Razor Page 時,應優先處理 Web 應用程式中的 Razor 標記 (.cshtml 檔案)。

檢視或下載範例程式碼 \(英文\) (如何下載)

建立包含 Razor UI 的類別庫

  • 從 Visual Studio 中,選取 [建立新專案]。
  • 選取 [Razor 類別庫]>[下一步]。
  • 命名程式庫 (例如 "RazorClassLib"),>[建立]>[下一步]。 若要避免與產生的檢視程式庫發生檔案名稱衝突,程式庫名稱結尾請務必不要使用 .Views
  • 選取 [目標 Framework]。 檢查 [☑支援頁面和檢視],以支援檢視。 根據預設,僅支援 Razor 元件。 選取建立

預設情況下,Razor 類別庫 (RCL) 範本預設為 Razor 元件開發。 [支援頁面和檢視] 選項支援頁面和檢視。

將 Razor 檔案新增至 RCL。

ASP.NET Core 範本假設 RCL 內容位於 Areas 資料夾中。 請參閱 RCL 頁面配置,以建立在 ~/Pages (而不是 ~/Areas/Pages) 公開內容的 RCL。

參考 RCL 內容

RCL 可以由下列各項參考:

覆寫檢視、部分檢視和頁面

在 Web 應用程式和 RCL 中,發現檢視、部分檢視或 Razor Page 時,應優先處理 Web 應用程式中的 Razor 標記 (.cshtml 檔案)。 例如,將 WebApp1/Areas/MyFeature/Pages/Page1.cshtml 新增至 WebApp1,則 WebApp1 中 Page1 的優先順序將高於 RCL 中的 Page1。

在範例下載中,將 WebApp1/Areas/MyFeature2 重新命名為 WebApp1/Areas/MyFeature,以測試優先順序。

RazorUIClassLib/Areas/MyFeature/Pages/Shared/_Message.cshtml 部分檢視複製到 WebApp1/Areas/MyFeature/Pages/Shared/_Message.cshtml。 更新標記來指示新的位置。 建置並執行應用程式,以確認正在使用部分檢視的應用程式版本。

RCL 頁面配置

若要將 RCL 內容視為 Web 應用程式 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 檔案新增至 RCL 專案的 Pages 資料夾,以使用主機 Web 應用程式的 _Layout.cshtml 檔案:

@{
    Layout = "_Layout";
}

建立具有靜態資產的 RCL

RCL 可能需要 RCL 或 RCL 取用應用程式可以參考的附屬靜態資產。 ASP.NET Core 允許建立包含可供取用應用程式使用的靜態資產的 RCL。

若要在 RCL 中包含附屬資產,請在類別庫中建立 wwwroot 資料夾,並在該資料夾中包含所有必要的檔案。

封裝 RCL 時,wwwroot 資料夾中的所有附屬資產都會自動包含在套件中。

使用 dotnet pack 命令,而不是 NuGet.exe nuget pack 版。

排除靜態資產

若要排除靜態資產,請將所需的排除路徑新增至專案檔中的 $(DefaultItemExcludes) 屬性群組。 使用分號 (;) 來分隔項目。

在下列範例中,wwwroot 資料夾中的 lib.css 樣式表不視為靜態資產,且不包含在已發佈的 RCL 中:

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

TypeScript 整合

若要在 RCL 中包含 TypeScript 檔案,請執行下列作業:

  1. 參考專案中的 Microsoft.TypeScript.MSBuild NuGet 套件。

    注意

    如需將套件新增至 .NET 應用程式的指引,請參閱在套件取用工作流程 (NuGet 文件)安裝及管理套件底下的文章。 在 NuGet.org 確認正確的套件版本。

  2. 將 TypeScript 檔案 (.ts) 放在 wwwroot 資料夾外。 例如,將檔案放在 Client 資料夾中。

  3. 設定 wwwroot 資料夾的 TypeScript 建置輸出。 在專案檔中的 PropertyGroup 內設定 TypescriptOutDir 屬性:

    <TypescriptOutDir>wwwroot</TypescriptOutDir>
    
  4. 透過在專案檔中的 PropertyGroup 內新增下列目標,將 TypeScript 目標併入為 ResolveCurrentProjectStaticWebAssets 目標的相依性:

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

從參考的 RCL 取用內容

RCL 的 wwwroot 資料夾中所包含的檔案,會使用前置詞 _content/{PACKAGE ID}/ 公開給 RCL 或取用應用程式。 例如,某程式庫的組件名稱為 Razor.Class.Lib 且在專案檔中未指定 <PackageId>,則造成靜態內容路徑為 _content/Razor.Class.Lib/。 產生 NuGet 套件且組件名稱與套件 ID (程式庫的專案檔中的 <PackageId>) 不同時,請使用專案檔中針對 {PACKAGE ID} 指定的套件 ID。

取用應用程式會參考程式庫所提供的靜態資產,其中包含 <script><style><img> 和其他 HTML 標籤。 取用應用程式必須在 Startup.Configure 中啟用靜態檔案支援

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

    app.UseStaticFiles();

    ...
}

從建置輸出 (dotnet run) 執行取用應用程式時,預設會在開發環境中啟用靜態 Web 資產。 若要在從建置輸出執行時支援其他環境中的資產,請在 Program.cs 中的主機建置器上呼叫 UseStaticWebAssets

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 中的資產會保留在原始資料夾。 資產不會移至取用應用程式。
  • 在重建 RCL 後,RCL 的 wwwroot 資料夾內的任何變更都會反映在取用應用程式中,且無需重建取用應用程式。

建置 RCL 時,會產生一份描述靜態 Web 資產位置的資訊清單。 取用應用程式會在執行階段讀取資訊清單,以取用參考的專案和套件的資產。 將新的資產新增至 RCL 時,必須先重建 RCL 以更新其資訊清單,然後取用應用程式才能存取新的資產。

發行

發佈應用程式時,所有參考專案和套件的附屬資產都會複製到已發佈應用程式的 wwwroot 資料夾的 _content/{PACKAGE ID}/ 下。 產生 NuGet 套件且組件名稱與套件 ID (程式庫的專案檔中的 <PackageId>) 不同時,請在檢查已發佈資產的 wwwroot 資料夾時,使用專案檔中針對 {PACKAGE ID} 指定的套件 ID。

其他資源

您可以將 Razor 檢視、頁面、控制器、頁面模型、Razor 元件檢視元件和資料模型建置到 Razor 類別庫 (RCL) 中。 RCL 可以封裝和重複使用。 應用程式可以包括 RCL,以及覆寫它所包含的檢視和頁面。 在 Web 應用程式和 RCL 中,發現檢視、部分檢視或 Razor Page 時,應優先處理 Web 應用程式中的 Razor 標記 (.cshtml 檔案)。

檢視或下載範例程式碼 \(英文\) (如何下載)

建立包含 Razor UI 的類別庫

  • 從 Visual Studio 的 [檔案] 功能表中,選取 [新增]>[專案]
  • 選取 [ASP.NET Core Web 應用程式]
  • 命名程式庫 (例如,"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 問題留下意見反應以及您對下載範例與逐步指示的評論。

測試下載應用程式

如果您尚未下載已完成的應用程式,而是要建立逐步解說專案,請跳至下一節

在 Visual Studio 中開啟 .sln 檔案。 執行應用程式。

遵循測試 WebApp1 中的指示執行。

建立 RCL

在本節中,會建立一個 RCL。 Razor 檔案已新增至 RCL。

建立 RCL 專案:

  • 從 Visual Studio 的 [檔案] 功能表中,選取 [新增]>[專案]
  • 選取 [ASP.NET Core Web 應用程式]
  • 命名應用程式 (RazorUIClassLib),>[確定]。
  • 確認已選取 ASP.NET Core 2.1 或更新版本。
  • 選取 [Razor 類別庫]>[確定]。
  • 新增名為 RazorUIClassLib/Areas/MyFeature/Pages/Shared/_Message.cshtml 的 Razor 部分檢視檔案。

將 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" />)。 您可以新增 _ViewImports.cshtml 檔案,而不是包含 @addTagHelper 指示詞。 例如:

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

    如需 _ViewImports.cshtml 的詳細資訊,請參閱匯入共用指示詞

  • 建置類別庫,以確認沒有任何編譯器錯誤:

    dotnet build RazorUIClassLib
    

建置輸出包含 RazorUIClassLib.dllRazorUIClassLib.Views.dllRazorUIClassLib.Views.dll 包含已編譯的 Razor 內容。

使用 Razor Pages 專案中的 Razor UI 程式庫

建立 Razor Pages Web 應用程式:

  • 在 [方案總管] 中,以滑鼠右鍵按一下解決方案 >[新增]>[新增專案]。

  • 選取 [ASP.NET Core Web 應用程式]

  • 將應用程式命名為 WebApp1

  • 確認已選取 ASP.NET Core 2.1 或更新版本。

  • 選取 [Web 應用程式]>[確定]

  • 從 [方案總管],以滑鼠右鍵按一下 WebApp1,然後選取 [設定為啟始專案]

  • 從方案總管,以滑鼠右鍵按一下 WebApp1,然後選取 [建置相依性]>[專案相依性]

  • 核取 [RazorUIClassLib] 作為 WebApp1 的相依性。

  • 從 [方案總管],以滑鼠右鍵按一下 WebApp1,然後選取 [新增]>[參考]

  • 在 [參考管理員] 對話方塊中,核取 [RazorUIClassLib]>[確定]。

執行應用程式。

測試 WebApp1

瀏覽至 /MyFeature/Page1,以確認 Razor UI 類別庫正在使用中。

覆寫檢視、部分檢視和頁面

在 Web 應用程式和 RCL 中,發現檢視、部分檢視或 Razor Page 時,應優先處理 Web 應用程式中的 Razor 標記 (.cshtml 檔案)。 例如,將 WebApp1/Areas/MyFeature/Pages/Page1.cshtml 新增至 WebApp1,則 WebApp1 中 Page1 的優先順序將高於 RCL 中的 Page1。

在範例下載中,將 WebApp1/Areas/MyFeature2 重新命名為 WebApp1/Areas/MyFeature,以測試優先順序。

RazorUIClassLib/Areas/MyFeature/Pages/Shared/_Message.cshtml 部分檢視複製到 WebApp1/Areas/MyFeature/Pages/Shared/_Message.cshtml。 更新標記來指示新的位置。 建置並執行應用程式,以確認正在使用部分檢視的應用程式版本。

RCL 頁面配置

若要將 RCL 內容視為 Web 應用程式 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 檢視、頁面、控制器、頁面模型、Razor 元件檢視元件和資料模型建置到 Razor 類別庫 (RCL) 中。 RCL 可以封裝和重複使用。 應用程式可以包括 RCL,以及覆寫它所包含的檢視和頁面。 在 Web 應用程式和 RCL 中,發現檢視、部分檢視或 Razor Page 時,應優先處理 Web 應用程式中的 Razor 標記 (.cshtml 檔案)。

檢視或下載範例程式碼 \(英文\) (如何下載)

建立包含 Razor UI 的類別庫

  • 從 Visual Studio 中,選取 [建立新專案]。
  • 選取 [Razor 類別庫]>[下一步]。
  • 命名程式庫 (例如 "RazorClassLib"),>[建立]。 若要避免與產生的檢視程式庫發生檔案名稱衝突,程式庫名稱結尾請務必不要使用 .Views
  • 如果您需要支援檢視,請選取 [支援頁面和檢視]。 根據預設,僅支援 Razor Pages。 選取建立

預設情況下,Razor 類別庫 (RCL) 範本預設為 Razor 元件開發。 [支援頁面和檢視] 選項支援頁面和檢視。

將 Razor 檔案新增至 RCL。

ASP.NET Core 範本假設 RCL 內容位於 Areas 資料夾中。 請參閱下面的 RCL 頁面配置,以建立在 ~/Pages (而不是 ~/Areas/Pages) 公開內容的 RCL。

參考 RCL 內容

RCL 可以由下列各項參考:

覆寫檢視、部分檢視和頁面

在 Web 應用程式和 RCL 中,發現檢視、部分檢視或 Razor Page 時,應優先處理 Web 應用程式中的 Razor 標記 (.cshtml 檔案)。 例如,將 WebApp1/Areas/MyFeature/Pages/Page1.cshtml 新增至 WebApp1,則 WebApp1 中 Page1 的優先順序將高於 RCL 中的 Page1。

在範例下載中,將 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 內容視為 Web 應用程式 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 檔案新增至 RCL 專案的 Pages 資料夾,以使用主機 Web 應用程式的 _Layout.cshtml 檔案:

@{
    Layout = "_Layout";
}

建立具有靜態資產的 RCL

RCL 可能需要 RCL 或 RCL 取用應用程式可以參考的附屬靜態資產。 ASP.NET Core 允許建立包含可供取用應用程式使用的靜態資產的 RCL。

若要在 RCL 中包含附屬資產,請在類別庫中建立 wwwroot 資料夾,並在該資料夾中包含所有必要的檔案。

封裝 RCL 時,wwwroot 資料夾中的所有附屬資產都會自動包含在套件中。

使用 dotnet pack 命令,而不是 NuGet.exe nuget pack 版。

排除靜態資產

若要排除靜態資產,請將所需的排除路徑新增至專案檔中的 $(DefaultItemExcludes) 屬性群組。 使用分號 (;) 來分隔項目。

在下列範例中,wwwroot 資料夾中的 lib.css 樣式表不視為靜態資產,且不包含在已發佈的 RCL 中:

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

TypeScript 整合

若要在 RCL 中包含 TypeScript 檔案,請執行下列作業:

  1. 參考專案中的 Microsoft.TypeScript.MSBuild NuGet 套件。

    注意

    如需將套件新增至 .NET 應用程式的指引,請參閱在套件取用工作流程 (NuGet 文件)安裝及管理套件底下的文章。 在 NuGet.org 確認正確的套件版本。

  2. 將 TypeScript 檔案 (.ts) 放在 wwwroot 資料夾外。 例如,將檔案放在 Client 資料夾中。

  3. 設定 wwwroot 資料夾的 TypeScript 建置輸出。 在專案檔中的 PropertyGroup 內設定 TypescriptOutDir 屬性:

    <TypescriptOutDir>wwwroot</TypescriptOutDir>
    
  4. 透過在專案檔中的 PropertyGroup 內新增下列目標,將 TypeScript 目標併入為 ResolveCurrentProjectStaticWebAssets 目標的相依性:

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

從參考的 RCL 取用內容

RCL 的 wwwroot 資料夾中所包含的檔案,會使用前置詞 _content/{PACKAGE ID}/ 公開給 RCL 或取用應用程式。 例如,某程式庫的組件名稱為 Razor.Class.Lib 且在專案檔中未指定 <PackageId>,則造成靜態內容路徑為 _content/Razor.Class.Lib/。 產生 NuGet 套件且組件名稱與套件 ID (程式庫的專案檔中的 <PackageId>) 不同時,請使用專案檔中針對 {PACKAGE ID} 指定的套件 ID。

取用應用程式會參考程式庫所提供的靜態資產,其中包含 <script><style><img> 和其他 HTML 標籤。 取用應用程式必須在 Startup.Configure 中啟用靜態檔案支援

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

    app.UseStaticFiles();

    ...
}

從建置輸出 (dotnet run) 執行取用應用程式時,預設會在開發環境中啟用靜態 Web 資產。 若要在從建置輸出執行時支援其他環境中的資產,請在 Program.cs 中的主機建置器上呼叫 UseStaticWebAssets

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 中的資產會保留在原始資料夾。 資產不會移至取用應用程式。
  • 在重建 RCL 後,RCL 的 wwwroot 資料夾內的任何變更都會反映在取用應用程式中,且無需重建取用應用程式。

建置 RCL 時,會產生一份描述靜態 Web 資產位置的資訊清單。 取用應用程式會在執行階段讀取資訊清單,以取用參考的專案和套件的資產。 將新的資產新增至 RCL 時,必須先重建 RCL 以更新其資訊清單,然後取用應用程式才能存取新的資產。

發行

發佈應用程式時,所有參考專案和套件的附屬資產都會複製到已發佈應用程式的 wwwroot 資料夾的 _content/{PACKAGE ID}/ 下。 產生 NuGet 套件且組件名稱與套件 ID (程式庫的專案檔中的 <PackageId>) 不同時,請在檢查已發佈資產的 wwwroot 資料夾時,使用專案檔中針對 {PACKAGE ID} 指定的套件 ID。

其他資源