Razor类库

在 ASP.NET Core 中使用 Razor 类库项目创建可重用的 UI

作者:Rick Anderson

Razor 视图、页、控制器、页模型、 razor 组件视图组件和数据模型可以内置于 Razor 类库(RCL)中。 RCL 可以打包并重复使用。 应用程序可以包括 RCL,并重写其中包含的视图和页面。 如果在 Web 应用和 RCL 中都能找到视图、分部视图或 Razor 页面,则 Web 应用中的 Razor 标记(.cshtml 文件)优先。

查看或下载示例代码如何下载

创建一个包含 Razor UI 的类库

将 Razor 文件添加到 RCL。

ASP.NET Core 模板假设 RCL 内容位于 "区域" 文件夹中。 请参阅RCL Pages layout ,以创建 RCL,以在 ~/Pages 而不是 ~/Areas/Pages公开内容。

引用 RCL 内容

可以通过以下方式引用 RCL:

重写视图、分部视图和页面

如果在 Web 应用和 RCL 中都能找到视图、分部视图或 Razor 页面,则 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 <partial> 标记可以添加到 _Layout cshtml文件中:

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

使用静态资产创建 RCL

RCL 可能需要随附静态资产,这些资产可由 RCL 的 RCL 或使用应用程序引用。 ASP.NET Core 允许创建包含可用于使用中的应用的静态资产的 RCLs。

若要将配套资产作为 RCL 的一部分包括在内,请在类库中创建wwwroot文件夹,并在该文件夹中包含所有必需的文件。

当对 RCL 进行打包时, wwwroot文件夹中的所有伴随资产将自动包含在包中。

排除静态资产

若要排除静态资产,请将所需的排除路径添加到项目文件中的 $(DefaultItemExcludes) 属性组。 用分号(;)分隔条目。

在下面的示例中, wwwroot文件夹中的lib样式表不被视为静态资产,而且不包含在已发布的 RCL 中:

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

Typescript 集成

若要在 RCL 中包含 TypeScript 文件:

  1. 将 TypeScript 文件(ts)置于wwwroot文件夹之外。 例如,将文件放在客户端文件夹中。

  2. wwwroot文件夹配置 TypeScript 生成输出。 在项目文件中的 PropertyGroup 内设置 TypescriptOutDir 属性:

    <TypescriptOutDir>wwwroot</TypescriptOutDir>
    
  3. 将 TypeScript 目标作为 ResolveCurrentProjectStaticWebAssets 目标的依赖项,方法是将以下目标添加到项目文件中的 PropertyGroup 内:

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

使用引用 RCL 中的内容

RCL 的wwwroot文件夹中包含的文件会公开给 RCL 或应用程序下的前缀 _content/{LIBRARY NAME}/ 例如,名为Razor的库会导致 _content/Razor.Class.Lib/的静态内容的路径。 如果生成 NuGet 包,并且程序集名称与包 ID 不同,请使用包 ID 进行 {LIBRARY NAME}

使用应用引用库提供的静态资产,其中包含 <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 以更新其清单,然后使用的应用才能访问新资产。

发布

在发布应用程序时,所有被引用项目和包中的助理资产都将复制到 _content/{LIBRARY NAME}/下的已发布应用程序的wwwroot文件夹中。

Razor 视图、页、控制器、页模型、 razor 组件视图组件和数据模型可以内置于 Razor 类库(RCL)中。 RCL 可以打包并重复使用。 应用程序可以包括 RCL,并重写其中包含的视图和页面。 如果在 Web 应用和 RCL 中都能找到视图、分部视图或 Razor 页面,则 Web 应用中的 Razor 标记(.cshtml 文件)优先。

查看或下载示例代码如何下载

创建一个包含 Razor UI 的类库

将 Razor 文件添加到 RCL。

ASP.NET Core 模板假设 RCL 内容位于 "区域" 文件夹中。 请参阅RCL Pages layout ,以创建 RCL,以在 ~/Pages 而不是 ~/Areas/Pages公开内容。

引用 RCL 内容

可以通过以下方式引用 RCL:

演练:创建 RCL 项目并从 Razor Pages 项目使用

可以下载并测试完整项目,无需创建项目。 示例下载包含附加代码和链接,以方便测试项目。 可以在此 GitHub 问题中留下反馈,评论下载示例和分步说明的对比。

测试下载应用

如果尚未下载已完成的应用,并更愿意创建演练项目,请跳转至下一节

“测试 Test WebApp1”中的说明进行操作

创建 RCL

在本部分中,将创建一个 RCL。 将 Razor 文件添加到 RCL。

将 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.dll 和 RazorUIClassLib.Views.dll。 RazorUIClassLib.Views.dll 包含已编译的 Razor 内容。

从 Razor 页面项目使用 Razor UI 库

测试 WebApp1

浏览到 /MyFeature/Page1,验证 Razor UI 类库是否正在使用中。

重写视图、分部视图和页面

如果在 Web 应用和 RCL 中都能找到视图、分部视图或 Razor 页面,则 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 <partial> 标记可以添加到 _Layout cshtml文件中:

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

其他资源