ASP.NET Core 5.0设置RazorCompileOnBuild=false后外部ViewComponent失效
基于ASP.Net Core 5.0开发Web应用时使用ViewComponents功能,所有ViewComponent类均定义在独立的外部项目中。由于主项目视图文件数量过多,为将编译时长从120秒压缩至10秒,在主项目的.csproj文件中添加了如下配置:
<PropertyGroup> <RazorCompileOnBuild>false</RazorCompileOnBuild> <RazorCompileOnPublish>true</RazorCompileOnPublish> </PropertyGroup>
配置生效后出现异常:主项目无法检测到外部项目定义的ViewComponents,组件既无法在视图中正常渲染结果,也不会出现在IntelliSense智能提示列表中。
涉及的ViewComponent示例代码如下:
[ViewComponent(Name = "EntityForm")] public class EntityFormViewComponent : ViewComponent { public async Task<IViewComponentResult> InvokeAsync() { if (ViewData.ContainsKey("ViewMode") && ((ViewMode)ViewData["ViewMode"] == ViewMode.Create || (ViewMode)ViewData["ViewMode"] == ViewMode.Edit || (ViewMode)ViewData["ViewMode"] == ViewMode.Delete)) return View("EntityForm"); else return View("EntityGrid"); } }
项目层级结构:
当RazorCompileOnBuild设置为false时,所有外部项目中的ViewComponent均无法正常工作,视图中调用组件的方式为:
<vc:entity-form />
RazorCompileOnBuild配置为false时,本地构建阶段会跳过Razor视图编译步骤,同时默认会暂停Razor的组件/TagHelper全量扫描流程。默认情况下,Razor在编译视图时会扫描主项目及所有引用项目中的ViewComponent、TagHelper类型并生成对应注册信息,跳过该步骤后,外部项目中定义的组件没有被纳入Razor的识别范围,就会出现标签渲染失败、智能提示缺失的问题。
可根据实际场景选择以下任意一种方案,既能保留关闭构建时Razor编译带来的编译速度提升,也能让外部ViewComponent正常工作:
- 方案1:在主项目的
Views/_ViewImports.cshtml文件中,手动添加所有外部ViewComponent所在项目的TagHelper引用,每一个存放组件的独立项目对应一行配置,格式如下:
配置完成后,Razor设计时和运行时都会自动扫描对应程序集内的ViewComponent,无需依赖构建时的全量扫描流程。@addTagHelper *, 外部组件项目的程序集名称 - 方案2:在主项目.csproj的配置中追加设计时编译配置,在关闭构建时编译的同时保留Razor的设计时扫描能力,修改后的PropertyGroup配置如下:
<PropertyGroup> <RazorCompileOnBuild>false</RazorCompileOnBuild> <RazorCompileOnPublish>true</RazorCompileOnPublish> <RazorDesignTimeCompile>true</RazorDesignTimeCompile> </PropertyGroup> - 方案3:如果上述配置仍无法识别组件,可在服务注册阶段手动加载外部组件所在的程序集。首先需要安装NuGet包
Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation,随后在服务配置代码中添加程序集引用:
有多个外部组件项目的,重复调用services.AddControllersWithViews() .AddRazorRuntimeCompilation() .AddApplicationPart(typeof(EntityFormViewComponent).Assembly);AddApplicationPart传入对应项目中任意一个类型的Assembly即可。
注意:使用
<vc:xxx />标签语法调用ViewComponent的核心前提是组件所在程序集被Razor的TagHelper扫描机制覆盖,只要完成对应程序集的注册,关闭构建时Razor编译不会影响组件的正常运行。
内容的提问来源于stack exchange,提问作者Bamdad

