web-dev-qa-db-fra.com

Comment précompiler des vues dans ASP.NET Core 2.0?

J'ai mis en place ma solution en fonction de cela article . J'ai omis certaines choses car selon this , ASP.NET Core 2.0 précompile les vues par défaut. À la fin, je le publie dans un dossier, qui se termine avec succès, mais mon precompiledviews.dll est manquant. J'ai essayé de le définir explicitement dans .csproj, mais pas de chance.

Modifier: les deux projets à l'intérieur de la solution ne sont que des modèles MVC par défaut.

10
Orvel

Je parie que vous utilisez déploiement autonome , c'est-à-dire publier avec une commande comme

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

qui résulte en un fichier exécutable avec toutes les dépendances, y compris les binaires .NET Core.

Razor view compilation and precompilation l'article contient l'avertissement suivant:

La précompilation de la vue Razor n'est actuellement pas disponible lors de l'exécution d'un déploiement autonome (SCD) dans ASP.NET Core 2.0. La fonctionnalité sera disponible pour les SCD lors de la sortie de la version 2.1.

Donc, si vous souhaitez utiliser des vues Razor précompilées, vous devez utiliser déploiement dépendant du framework , c'est-à-dire publier avec la commande suivante:

dotnet publish --configuration Release

Dans ce cas, les vues Razor sont précompilées (par défaut) et vous trouverez YourAppName.PrecompiledViews.dll parmi d'autres fichiers binaires d'application.

[~ # ~] mise à jour [~ # ~] (pour les vues précompilées dans le projet Library)

Ma réponse d'origine se rapporte à l'application habituelle ASP.NET Core MVC, mais la question est spécifique à la bibliothèque de projet contenant des vues précompilées aka UI autonome.

ASP.NET Core précompile les vues par défaut lors de la publication, mais ce n'est pas le cas pour les vues stockées dans le projet de bibliothèque. Il y a un problème github consacré à ce problème. Cette discussion est assez longue, mais elle finit avec la conclusion que pour le moment nous devons encore utiliser une solution avec des cibles personnalisées pour la précompilation de Razor Views. Il s'agit essentiellement de la même approche que celle décrite dans le article référencé par la question.

J'ai installé une solution de test avec ChildApplication et main MvcApplication et créé des vues précompilées fonctionnant à la fois pour la génération et la publication.

Voici csproj pour ChildApplication (en ignorant les sections du projet MVC ASP.NET Core par défaut):

<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>

Voici csproj pour le parent MvcApplication:

<!-- ... -->

<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>

Dean North dans son article d'origine ajoute une référence directe à l'Assemblée avec des vues précompilées.

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

Une telle approche n'est pas parfaite car elle utilise Assembly construit avec une configuration spécifique (Debug ici). Dans mon fichier de projet ci-dessus, j'utilise des cibles distinctes qui copient ChildApplication.PrecompiledViews.dll pendant la génération et la publication.

Voici ( Exemple de solution sur GitHub avec les projets parents et enfants.

10
CodeFuller

Je les ajoute généralement au .csproj. Pas besoin de copier des fichiers ou tout ce désordre.

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

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