情景:
它工作正常但是在使用预编译视图发布应用程序时,上面方法链接中的FindView返回null。
重现的步骤:
如何在运行时查找和渲染预编译视图?
答案 0 :(得分:1)
最简单的解决方法是在发布期间禁用预编译视图。如果是一个选项,那么只需在csproj文件中将MvcRazorCompileOnPublish
设置为false
<PropertyGroup>
<TargetFrameworks>netcoreapp2.0;net461</TargetFrameworks>
<MvcRazorCompileOnPublish>false</MvcRazorCompileOnPublish>
</PropertyGroup>
如果您想使用预编译视图,则需要在ConfigureDefaultServices
方法中进行多次修复。
首先,在services.Configure<RazorViewEngineOptions>
之后移动AddMvc()
来电。否则,您将覆盖由RazorViewEngineOptions
添加的AddMvc()
配置设置,并且不会填充所需数据(RazorViewEngineOptionsSetup执行的作业)。
在此修复之后,基本渲染将起作用,但Razor Engine将无法找到部分视图和布局。要解决此问题,您需要将没有控制器名称(/Views/{0}.cshtml
)的位置格式添加到RazorViewEngineOptions.ViewLocationFormats
集合。
在描述修复后,基于预编译视图的渲染对我来说很好。这是更正的ConfigureDefaultServices
方法:
private static void ConfigureDefaultServices(IServiceCollection services, string customApplicationBasePath)
{
string applicationName;
IFileProvider fileProvider;
if (!string.IsNullOrEmpty(customApplicationBasePath))
{
applicationName = Path.GetFileName(customApplicationBasePath);
fileProvider = new PhysicalFileProvider(customApplicationBasePath);
}
else
{
applicationName = Assembly.GetEntryAssembly().GetName().Name;
fileProvider = new PhysicalFileProvider(Directory.GetCurrentDirectory());
}
services.AddSingleton<IHostingEnvironment>(new HostingEnvironment
{
ApplicationName = applicationName,
WebRootFileProvider = fileProvider,
});
var diagnosticSource = new DiagnosticListener("Microsoft.AspNetCore");
services.AddSingleton<ObjectPoolProvider, DefaultObjectPoolProvider>();
services.AddSingleton<DiagnosticSource>(diagnosticSource);
services.AddLogging();
services.AddTransient<RazorViewToStringRenderer>();
services.Configure<RazorViewEngineOptions>(options =>
{
options.ViewLocationFormats.Add("/Views/{0}.cshtml");
options.FileProviders.Clear();
options.FileProviders.Add(fileProvider);
});
services.AddMvc();
}
答案 1 :(得分:1)
我不明白为什么,但是在控制台应用程序中,AddMvc()
跳过了一个配置步骤-它没有添加提供程序来从程序集中检索预编译视图。
在我的情况下,我使用控制台应用程序(net472)和Razor类库,并将RazorViewToStringRenderer
放入该库中。
要添加提供者,我们需要执行以下操作
var viewAssembly = Assembly.Load(typeof(RazorViewToStringRenderer).Assembly.GetName().Name + ".Views");
var viewAssemblyPart = new CompiledRazorAssemblyPart(viewAssembly);
services.AddMvc().PartManager.ApplicationParts.Add(viewAssemblyPart);
完成此步骤后,RazorViewToStringRenderer
可以正常工作。
答案 2 :(得分:0)
我在Web项目中使用相同的代码,我不得不将完整的目录信息添加到GetView尝试中。 FindView方法使用View或CSHTML扩展(无需预编译)。但GetView需要并且始终有效(有和没有预编译视图)
var getViewResult = _viewEngine
.GetView(
executingFilePath: null,
viewPath: $"/Views/{viewName}.cshtml",
isMainPage: true);