[英]How do I find/render precompiled Razor View
Scenario: 场景:
It works fine but when publish the app with precompiled views, the FindView from the link above methods returns null. 它工作正常,但是当使用预编译视图发布应用程序时,上述方法链接中的FindView返回null。
Steps to reproduce: 重现步骤:
How do I find and render precompiled view at runtime? 如何在运行时查找并渲染预编译视图?
The easiest fix would be disabling of precompiled views during the publish. 最简单的解决方法是在发布期间禁用预编译视图。 If it is an option, then just set
MvcRazorCompileOnPublish
to false
in csproj file 如果它是一个选项,然后只设置
MvcRazorCompileOnPublish
以false
的文件的csproj
<PropertyGroup>
<TargetFrameworks>netcoreapp2.0;net461</TargetFrameworks>
<MvcRazorCompileOnPublish>false</MvcRazorCompileOnPublish>
</PropertyGroup>
If however you want to use precompiled views, then you need to make several fixes in ConfigureDefaultServices
method. 但是,如果要使用预编译的视图,则需要在
ConfigureDefaultServices
方法中进行一些修复。
First of all, move services.Configure<RazorViewEngineOptions>
call after AddMvc()
. 首先,将
services.Configure<RazorViewEngineOptions>
调用AddMvc()
。 Otherwise you override RazorViewEngineOptions
configuration setup added by AddMvc()
and it will not be filled with required data (the job performed by RazorViewEngineOptionsSetup ). 否则,您将覆盖由
AddMvc()
添加的RazorViewEngineOptions
配置设置,并且不会用所需的数据填充该设置(该工作由RazorViewEngineOptionsSetup执行)。
After this fix basic rendering will work however partial views and layout will not be located by Razor Engine. 在此修复之后,基本渲染将起作用,但是Razor Engine无法定位局部视图和布局。 To fix this, you need to add location format without controller name (
/Views/{0}.cshtml
) to RazorViewEngineOptions.ViewLocationFormats
collection. 要解决此问题,您需要将不带控制器名称的位置格式(
/Views/{0}.cshtml
)添加到RazorViewEngineOptions.ViewLocationFormats
集合。
After described fixes rendering based on precompiled views works fine for me. 在描述了修复程序之后,基于预编译视图的渲染对我来说很好。 Here is corrected
ConfigureDefaultServices
method: 这里是更正的
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();
}
I could not understand why, but in the console application, AddMvc()
skips one configuration step - it does not add a provider that retrieves precompiled views from assembly. 我不明白为什么,但是在控制台应用程序中,
AddMvc()
跳过了一个配置步骤-它没有添加提供程序以从程序AddMvc()
检索预编译的视图。
In my case I use console app (net472) and Razor class library and put RazorViewToStringRenderer
in this library. 就我而言,我使用控制台应用程序(net472)和Razor类库,并将
RazorViewToStringRenderer
放在该库中。
To add the provider, we need to do the following 要添加提供者,我们需要执行以下操作
var viewAssembly = Assembly.Load(typeof(RazorViewToStringRenderer).Assembly.GetName().Name + ".Views");
var viewAssemblyPart = new CompiledRazorAssemblyPart(viewAssembly);
services.AddMvc().PartManager.ApplicationParts.Add(viewAssemblyPart);
After this steps RazorViewToStringRenderer
works perfect. 在此步骤之后,
RazorViewToStringRenderer
可以完美工作。
I'm using the same code in a web project and I had to add the complete directory info to the GetView attempt. 我在Web项目中使用了相同的代码,因此必须将完整的目录信息添加到GetView尝试中。 The FindView method works (without precompilation) with the View or CSHTML extension.
FindView方法可与View或CSHTML扩展一起使用(无需预编译)。 But the GetView needs both and always works (with and without precompilation of views)
但是GetView既需要又可以同时工作(使用和不使用视图的预编译)
var getViewResult = _viewEngine
.GetView(
executingFilePath: null,
viewPath: $"/Views/{viewName}.cshtml",
isMainPage: true);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.