.NET Core 2.0控制台应用如何查找并渲染预编译Razor视图?
解决.NET Core 2.0控制台应用预编译Razor视图查找问题
我之前也踩过这个坑——本地运行时嵌入式视图没问题,一发布预编译视图就找不到,核心原因是预编译会把Razor视图从嵌入式资源转换成程序集中的强类型类,原来基于嵌入式资源的查找逻辑自然就失效了。下面是亲测有效的解决步骤:
1. 调整Mvc服务配置,注册预编译视图程序集
首先要确保你的Mvc服务能识别预编译视图所在的程序集。如果视图和主控制台项目在同一个工程里,在ConfigureServices里添加AddApplicationPart来注册当前程序集:
services.AddMvc() // 注册当前程序集,让Mvc能找到预编译的视图类型 .AddApplicationPart(Assembly.GetExecutingAssembly()) .AddRazorOptions(options => { // 配置视图位置格式,匹配你的视图文件结构 // 比如~/Views/Email/Welcome.cshtml对应预编译的Views.Email.Welcome类 options.ViewLocationFormats.Add("/Views/{1}/{0}.cshtml"); options.ViewLocationFormats.Add("/Views/Shared/{0}.cshtml"); });
如果视图是单独的类库项目,把Assembly.GetExecutingAssembly()换成视图类库的程序集即可。
2. 修正视图渲染器的FindView逻辑
确保你的RazorViewToStringRenderer使用标准的IViewEngine.FindView方法,并且传入完整的视图路径(比如"~/Views/Email/Welcome.cshtml"),而不是只传文件名。这里是关键的渲染方法示例:
public async Task<string> RenderViewToStringAsync<TModel>(string viewName, TModel model) { var actionContext = new ActionContext( _httpContextAccessor.HttpContext, new RouteData(), new ActionDescriptor()); using (var sw = new StringWriter()) { var viewResult = _viewEngine.FindView(actionContext, viewName, isMainPage: false); if (!viewResult.Success) { throw new InvalidOperationException($"找不到视图: '{viewName}'"); } var viewData = new ViewDataDictionary<TModel>( new EmptyModelMetadataProvider(), new ModelStateDictionary()) { Model = model }; var viewContext = new ViewContext( actionContext, viewResult.View, viewData, new TempDataDictionary(actionContext.HttpContext, _tempDataProvider), sw, new HtmlHelperOptions()); await viewResult.View.RenderAsync(viewContext); return sw.ToString(); } }
注意:不要自己手动读取嵌入式资源,完全依赖Mvc的视图引擎来查找预编译视图。
3. 检查项目文件的预编译配置
在你的控制台项目的.csproj文件里,确保启用了Razor视图预编译,添加以下配置:
<PropertyGroup> <!-- 发布时启用Razor视图预编译 --> <MvcRazorCompileOnPublish>true</MvcRazorCompileOnPublish> <!-- 不要排除引用程序集,确保Mvc能找到预编译视图的依赖 --> <MvcRazorExcludeRefAssembliesFromPublish>false</MvcRazorExcludeRefAssembliesFromPublish> </PropertyGroup>
如果之前配置过<EmbeddedResource>把视图嵌入程序集,发布时可以暂时注释掉,因为预编译视图会优先生效。
4. 验证预编译结果
发布后可以用ILSpy之类的反编译工具查看你的程序集,确认是否存在类似Views.Email.Welcome这样的类——这说明视图已经成功预编译了。
按这几步调整后,发布后的应用就能正确找到并渲染预编译视图了。
内容的提问来源于stack exchange,提问作者Liero
相关产品推荐
相关产品推荐

