.NET 6中从Razor类库引用ViewComponent失败的问题排查
问题背景
需创建包含ViewComponent的独立RCL,同一项目中ViewComponent可正常工作,但移至RCL后ASP.NET应用无法找到该组件。
当前配置与错误信息
解决方案结构
解决方案包含两个项目:
- AspNetTestApp:ASP.NET Core Web应用项目
- TestLib:Razor类库项目,存放
ProductListViewComponent
视图调用代码
在Index视图中调用ViewComponent的代码:
@await Component.InvokeAsync("ProductList", new { maxPriority = 5, isDone = false } )
Program.cs配置
添加了RCL路径的RuntimeCompilation配置:
builder.Services.Configure<MvcRazorRuntimeCompilationOptions>(options => { var libraryPath = Path.GetFullPath( Path.Combine(builder.Environment.ContentRootPath, "..", "TestLib")); options.FileProviders.Add(new PhysicalFileProvider(libraryPath)); });
错误信息
System.InvalidOperationException: 找不到名为'ProductList'的ViewComponent。ViewComponent必须是公共非抽象类,不包含泛型参数,且需带有ViewComponentAttribute特性或类名以'ViewComponent'后缀结尾,同时不能带有NonViewComponentAttribute特性。
(省略后续堆栈跟踪信息)
ViewComponent代码
ProductListViewComponent.cs的实现:
public class ProductListViewComponent : ViewComponent { private readonly DemoContext db; public ProductListViewComponent(DemoContext context) { db = context; } public async Task<IViewComponentResult> InvokeAsync(string template, int maxPriority, bool isDone) { var items = await GetItemsAsync(maxPriority, isDone); return View(template, items); } private Task<List<Product>> GetItemsAsync(int maxPriority, bool isDone) { return db!.Products!.ToListAsync(); } }
解决步骤
添加项目引用
在AspNetTestApp项目中添加对TestLib项目的直接引用,确保编译时能获取到RCL中的程序集。注册RCL程序集到MVC
在Program.cs中添加代码,让MVC框架发现RCL中的ViewComponent:// 注册ViewComponent所在的程序集 builder.Services.AddControllersWithViews() .AddApplicationPart(typeof(ProductListViewComponent).Assembly);确保ViewComponent视图路径正确
在RCL项目中,ViewComponent的视图需要放在**/Components/[组件名]/**目录下,例如:- TestLib/Components/ProductList/Default.cshtml
- 如果有自定义模板,对应创建
TestLib/Components/ProductList/[模板名].cshtml
验证依赖注入配置
确保DemoContext在AspNetTestApp的Program.cs中已正确注册,例如:builder.Services.AddDbContext<DemoContext>(options => options.UseSqlServer(builder.Configuration.GetConnectionString("DefaultConnection")));调整RuntimeCompilation配置(可选)
如果需要运行时编译RCL中的视图,原来的文件提供者配置可以保留,但需确保路径正确。如果不需要运行时编译,可移除该配置。
验证
完成上述配置后,重新编译并运行AspNetTestApp,ViewComponent应该能被正常发现并渲染。
内容的提问来源于stack exchange,提问作者Yevhenii Podzolkin

