如何在 ASP.NET Core 2.0 中预编译视图?

Posted

技术标签:

【中文标题】如何在 ASP.NET Core 2.0 中预编译视图?【英文标题】:How to precompile views in ASP.NET Core 2.0? 【发布时间】:2018-09-09 19:29:48 【问题描述】:

我根据article 设置了我的解决方案。我省略了一些内容,因为根据this,ASP.NET Core 2.0 默认预编译视图。最后,我将它发布到一个文件夹中,该文件夹成功结束,但是我的 precompiledviews.dll 丢失了。我尝试在 .csproj 中明确设置它,但没有运气。

编辑:解决方案中的两个项目都只是默认的 MVC 模板。

【问题讨论】:

你的TargetFramework 是什么?您是否尝试过将 MvcRazorCompileOnPublish 隐式设置为 true? @Set ,它是 Core 2.0,是的,我确实尝试将 MvcRazorCompileOnPublish 设置为 true。 【参考方案1】:

我打赌你使用Self-contained deployment,即使用类似命令发布

dotnet publish --configuration Release --runtime win-x64

这会生成包含所有依赖项的可执行文件,包括 .NET Core 二进制文件。

Razor view compilation and precompilation 文章包含以下警告:

Razor 视图预编译当前在执行 ASP.NET Core 2.0 中的自包含部署 (SCD)。该功能将 2.1 版本时可用于 SCD。

所以如果你想使用预编译的 Razor 视图,你应该使用Framework-dependent deployment,即使用以下命令发布:

dotnet publish --configuration 发布

在这种情况下,Razor 视图是预编译的(默认情况下),您会在其他应用程序二进制文件中找到 YourAppName.PrecompiledViews.dll

更新(用于库项目中的预编译视图)

我的原始答案与通常的 ASP.NET Core MVC 应用程序有关,但问题是特定于包含预编译视图(即自包含 UI)的项目库。

默认情况下,ASP.NET Core 在发布期间预编译视图,但是对于存储在库项目中的视图,情况并非如此。有一个github issue 专门解决这个问题。该讨论很长,但是ends up 得出的结论是,目前我们仍然需要使用带有自定义目标的解决方案来进行 Razor Views 预编译。它与问题引用的article中描述的方法基本相同。

我已经使用ChildApplication 和主要MvcApplication 设置了测试解决方案,并使预编译视图同时适用于构建和发布。

这里是 ChildApplication 的 csproj(跳过默认 ASP.NET Core MVC 项目的部分):

<PropertyGroup>
    <TargetFramework>netcoreapp2.0</TargetFramework>
    <MvcRazorCompileOnPublish>true</MvcRazorCompileOnPublish>
</PropertyGroup>

<!-- ... -->

<Target Name="SetMvcRazorOutputPath">
    <PropertyGroup>
        <MvcRazorOutputPath>$(OutputPath)</MvcRazorOutputPath>
    </PropertyGroup>
</Target>
<Target Name="_MvcRazorPrecompileOnBuild" DependsOnTargets="SetMvcRazorOutputPath;MvcRazorPrecompile" AfterTargets="Build" Condition=" '$(IsCrossTargetingBuild)' != 'true' " />
<Target Name="IncludePrecompiledViewsInPublishOutput" DependsOnTargets="_MvcRazorPrecompileOnBuild" BeforeTargets="PrepareForPublish" Condition=" '$(IsCrossTargetingBuild)' != 'true' ">
    <ItemGroup>
        <_PrecompiledViewsOutput Include="$(MvcRazorOutputPath)$(MSBuildProjectName).PrecompiledViews.dll" />
        <_PrecompiledViewsOutput Include="$(MvcRazorOutputPath)$(MSBuildProjectName).PrecompiledViews.pdb" />
        <ContentWithTargetPath Include="@(_PrecompiledViewsOutput->'%(FullPath)')" RelativePath="%(_PrecompiledViewsOutput.Identity)" TargetPath="%(_PrecompiledViewsOutput.Filename)%(_PrecompiledViewsOutput.Extension)" CopyToPublishDirectory="PreserveNewest" />
    </ItemGroup>
</Target>

这里是父 MvcApplication 的 csproj:

<!-- ... -->

<ItemGroup>
    <ProjectReference Include="..\ChildApplication\ChildApplication.csproj" />
</ItemGroup>

<Target Name="PostBuild" AfterTargets="PostBuildEvent">
    <Exec Command="xcopy &quot;$(ProjectDir)\..\ChildApplication\bin\$(ConfigurationName)\netcoreapp2.0\ChildApplication.PrecompiledViews.dll&quot; &quot;$(TargetDir)&quot; /Y /I" />
</Target>

<Target Name="AddPayloadsFolder" AfterTargets="Publish">
    <Exec Command="xcopy &quot;$(ProjectDir)\..\ChildApplication\bin\$(ConfigurationName)\netcoreapp2.0\ChildApplication.PrecompiledViews.dll&quot; &quot;$(PublishDir)&quot; /Y /I" />
</Target>

his original article 中的 Dean North 添加了对带有预编译视图的程序集的直接引用。

<ItemGroup>
    <Reference Include="DashboardExample.PrecompiledViews">
        <HintPath>..\DashboardExample\bin\Debug\netcoreapp1.1\DashboardExample.PrecompiledViews.dll</HintPath>
    </Reference>
</ItemGroup>

这种方法并不完美,因为它使用由特定配置构建的程序集(此处为Debug)。在上面的项目文件中,我使用了在构建和发布期间复制 ChildApplication.PrecompiledViews.dll 的单独目标。

这里是 Sample Solution on GitHub,包含父项目和子项目。

【讨论】:

实际上,我确实使用该命令发布了它。它确实成功结束了,但仍然没有预编译的视图。 哇,感谢您提供的示例解决方案。我下载了它,尝试发布它。而且我收到 ChildApplication.PrecompiledViews.dll 无法复制的错误消息,因为它不存在。是的,它不存在。我错过了什么吗? 您在MvcApplication 目录中运行dotnet publish -c Release 命令吗?它对我来说非常好。这是screenshot of publish execution,请与您的运行输出进行比较。 它工作正常,但奇怪的是 precompiledviews.dll 仍然无处可寻。它不应该在那里吗? 具有预编译视图的程序集将具有 ChildApplication.PrecompiledViews.dllMvcApplication.PrecompiledViews.dll 的名称。请重新检查,它们应该在那里。【参考方案2】:

我通常只是将这些添加到.csproj。无需复制文件或任何乱七八糟的东西。

    <PropertyGroup>
       <TargetFramework>netcoreapp2.2</...
       ...
       <MvcRazorCompileOnPublish>true</MvcRazorCompileOnPublish>
       <PreserveCompilationContext>true</PreserveCompilationContext>
    </PropertyGroup>

    <ItemGroup>
        ...
       <PackageReference Include="Microsoft.AspNetCore.Mvc.Razor.ViewCompilation" Version="2.2.0" />    
    </ItemGroup>

【讨论】:

我在下面的文章 docs.microsoft.com/en-us/aspnet/core/mvc/views/… 中看到,将此值设置为 true 会禁用 Razor SDK。如果我想迁移到 Razor SDK,是否会在不将 MvcRazorCompileOnPublish 指定为 true 的情况下立即预编译视图?

以上是关于如何在 ASP.NET Core 2.0 中预编译视图?的主要内容,如果未能解决你的问题,请参考以下文章

在 asp .net mvc 5 中预编译剃须刀视图

在 TFS 2010 构建服务器中预编译 asp.net MVC 网站

如何在 ASP.NET Core 2.0 中根据路由配置服务身份验证

如何在 ASP.NET Core 2.0 中设置多个身份验证方案?

如何在 ASP.NET Core 2.0 Razor 页面中填充下拉列表

如何在 Asp.Net Core 2.0“AddJwtBearer”中间件中设置多个受众?