Aspnetcore: [Discussion] Breaking changes to runtime compilation for Razor views and Razor Pages

Created on 16 Feb 2019  路  25Comments  路  Source: dotnet/aspnetcore

As a consequence of cleaning up the ASP.NET Core shared framework to not depend on Roslyn, support for runtime compilation of Razor views and Razor Pages is being moved to a separate package.
Applications that require runtime compilation or re-compilation of Razor files should

  • Add a reference to the Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation package
  • Update the application's ConfigureServices to include a call to AddMvcRazorRuntimeCompilation:

C# services.AddMvc() .AddMvcRazorRuntimeCompilation();

The following APIs previously available on Microsoft.AspNetCore.Mvc.Razor.RazorViewEngineOptions to support runtime compilation would now be available via
Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation.MvcRazorRuntimeCompilationOptions:

  • RazorViewEngineOptions.FileProviders -> MvcRazorRuntimeCompilationOptions.FileProviders
  • RazorViewEngineOptions.AdditionalCompilationReferences -> MvcRazorRuntimeCompilationOptions.AdditionalReferencePaths

In addition, Microsoft.AspNetCore.Mvc.Razor.RazorViewEngineOptions.AllowRecompilingViewsOnFileChange has been removed. Recompilation on file changes is enabled by default by referencing the Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation package.

Related issues: https://github.com/aspnet/Announcements/issues/312, https://github.com/aspnet/Announcements/issues/325

Most helpful comment

@pixeldm
Maybe you could make that package reference conditional.

In your csproj

<PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">
    <DefineConstants>UseRazorCompilation</DefineConstants>
</PropertyGroup>

Then in your startup, use pre processor directive

if UseRazorCompilation

.AddMvcRazorRuntimeCompilation();

endif

And also in your csproj add that condition to the package reference!

All 25 comments

(This definitely deserves to be in the migration docs for the 3.0 jump.)

Any word on when the package will be available via nuget?

_EDIT: I accidentally a word._

@mqudsi It'll be available as part of the 3.0.0-preview3 release.

Thanks, @pranavkm. Looking forward to it.

Is this only for env == "Production" scenarios? I assume this doesn't change the development loop (whereby Razor files are recompiled on the fly?)

No, this applies everywhere (both in my understanding and from what I'm seeing in the latest preview). I'm having to restart IISExpress after each change to get the CSHTML changes to reflect.

This has been resolved with the release of preview 3; however, I am getting the exception below (using the template for MVC in VS2019)

image

adding the nuget package Microsoft.AspNetCore.Hosting.Abstractions does nothing

After adding a reference to Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation I get a version mismatch on the Microsoft.CodeAnalysis.Common package. This is because Microsoft.VisualStudio.Web.CodeGeneration.Design is referencing an older version. I had to remove the reference to Microsoft.VisualStudio.Web.CodeGeneration.Design otherwise view recompilation was throwing an exception.

Is there any way to set AddMvcRazorRuntimeCompilation() for only the dev environment? Currently, the only way to get design time recompiling of a view is to turn this feature on. Otherwise, the project must be restarted to see any changes to a view. However, enabling this feature also involves adding the Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation package. This package adds a considerable amount of files to the publish folder when publishing. Furthermore, I don't really want runtime compilation of views for production. Currently, I can't find any way to limit this feature to just development. Any suggestions?

@pixeldm
Maybe you could make that package reference conditional.

In your csproj

<PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">
    <DefineConstants>UseRazorCompilation</DefineConstants>
</PropertyGroup>

Then in your startup, use pre processor directive

if UseRazorCompilation

.AddMvcRazorRuntimeCompilation();

endif

And also in your csproj add that condition to the package reference!

Maybe you could make that package reference conditional.

Thanks @dazinator ! This does indeed work as expected. Much appreciated for the help.

I'm just trying this out now, and it is working as described. Thanks!
Is there a way to watch for new .cshtml files to compile?

Will this be available for .net standard 2.0?

I currently have my razor view compilation in a .net standard 2.0 class library referenced in the web app and when trying to upgrade my web app to use .net core 3 it fails with the following error message:

MissingMethodException: Method not found: System.Collections.Generic.IList1<Microsoft.Extensions.FileProviders.IFileProvider> Microsoft.AspNetCore.Mvc.Razor.RazorViewEngineOptions.get_FileProviders()

I am unable to reference the Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation package in my class library as this package depends on netcoreapp 3.

The code I have working on .net 2,1 atm is based on https://github.com/mikebrind/RazorEngineViewOptionsFileProviders.

What is the best upgrade path to get this working again with net core 3.0 and still have my razor compilation code in a separate library using net standard 2.0?

@janleon https://github.com/aspnet/AspNetCore/issues/3757#issuecomment-434178759 has details on what library authors need to do to reference parts of AspNetCore. Referencing ASP.NET Core or it's libraries requires targeting netcoreapp3.0, so you have to cross-compile to your library.

services.AddMvc().AddRazorRuntimeCompilation();

that what worked for me.

  1. Install Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation
  2. Modify services.AddRazorPages() to services.AddRazorPages().AddRazorRuntimeCompilation();

From the OP and announcement:

Recompilation on file changes is enabled by default by referencing the Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation package

Yet the docs and other posts here indicate you also need to set:

services.AddRazorRuntimeCompilation() - would be worth updating the announcement and OP here if this is indeed needed.

Any chance the dev team can undo whatever they did that broke this? I've added the package reference and I too have concerns with the sheer number of additional files required to implement this fix as well as the speed difference when making a change and simply refreshing vs 2.2's speed and ability to recompile the view.

I'm pretty sure the time to discuss not going this route that has long since sailed. These comments go out to everyone that's subscribed to the thread, so please try to avoid tangential discussions. If you feel strongly about it, you should probably open a new issue.

anyone come up with a good pattern to not have the package in release builds? best i could come up with is conditioning the package reference and #IF blocking the the code (and using's).

@pranavkm - I think you were working on something here...

Hello,

I'm trying to diagnose an issue I'm experiencing on OrchardCore, the runtime compilation is taking a very long time to compile seemingly simple view files. Is there any way I can get additional diagnostics or logging from the RuntimeViewCompiler? At the moment it's only giving me total compile time for each view?

For example this page is taking just over 6.5s to compile:

@using OrchardCore.ContentManagement;
@using OrchardCore.Mvc.Utilities;
@{
    ContentItem contentItem = Model.ContentItem;
    //Html.AddPageClassNames("detail-" + contentItem.ContentType.HtmlClassify());
}
@await DisplayAsync(Model)

Tagging @sebastienros for the OrchardCore reference.

@marlon-tucker I saw the other comment you added in OrchardCore, but I think it was unrelated to the issue you commented on.
Can you file an issue with repro steps in OC (how you compile, where is your source code, what version of tools you are using)? Nobody else has reported this issue so far.

@sebastienros yep ok, I'll submit an issue tomorrow morning UK time. Sounds likely it's environmental which means it's going to be difficult to diagnose.

Was this page helpful?
0 / 5 - 0 ratings