曦远 (DealiAxy)一份私人的文字刊物

StarBlog
返回文章列表折页手记阅读全文
StarBlog博客开发笔记

StarBlog Blog Development Notes (12): Razor Page Dynamic Compilation

Series articles Developing a blog project StarBlog based on .NetCore - (1) Why do you need to write your own blog? Developing a blog project StarBlog based on .NetCore - (2) Environment setup and creating the project Developing a blog project StarBlog based on .NetCore - (3) Model design Developing a blog project StarBlog based on .NetCore - (4) Batch import of markdown blogs Developing a blog project StarBl

曦远 (DealiAxy)约 16 分钟
目录5 个章节

Series Articles

Preface

I haven't updated the blog development notes for a while recently—got lazy = =..

Over the weekend, I polished some detailed features of the blog project and got ready to deploy it live~

This article was originally meant to document the implementation of a few features (theme switching, project monitoring, and a random image API), but while writing pages I found it annoying to have to restart every time I changed a Razor page, so I went through some pitfalls, and that's how this article came about.

Razor Page Dynamic Compilation

Although .Net6 started supporting partial code hot reload, it's still pretty half-baked—I often modify Razor pages but clicking Apply still has no effect~

I'd rather go back to the dynamic compilation that was commonly used before .NetCore3.1~

First, install Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation via NuGet, then configure it in Program.cs

Originally, adding MVC services looked like this

builder.Services.AddControllersWithViews(
    options => { options.Filters.Add<ResponseWrapperFilter>(); }
)

Change it to this (enable dynamic compilation only in development mode)

var mvcBuilder = builder.Services.AddControllersWithViews(
    options => { options.Filters.Add<ResponseWrapperFilter>(); }
);
if (builder.Environment.IsDevelopment()) {
    mvcBuilder.AddRazorRuntimeCompilation();
}

You can also do it without modifying C# code, via an environment variable. Edit the launchSettings.json file and add an environment variable

This way, RuntimeCompilation will be loaded dynamically when the program starts.

"environmentVariables": {
    "ASPNETCORE_ENVIRONMENT": "Development",
    "ASPNETCORE_HOSTINGSTARTUPASSEMBLIES": "Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation"
}

There's also a more thorough approach: don't compile cshtml files when publishing, so you can modify Razor pages after deployment.

Configure it in the project file (xxx.csproj)

<PropertyGroup>
    <RazorCompileOnBuild>false</RazorCompileOnBuild>
    <MvcRazorCompileOnPublish>false</MvcRazorCompileOnPublish>
</PropertyGroup>

This way, when publishing, all Razor views will not be precompiled, and all views will be published together, making it convenient to modify Razor pages in the production environment.

However, note that in a published production environment, modifying view files will not take effect immediately; you need to restart the application (for IIS-hosted environments, you need to restart the site) for the changes to take effect.

You can also configure conditional compilation. For details, see: https://www.cnblogs.com/thinksea/articles/14772837.html

This way, after you modify a Razor page and save, it will automatically recompile, making it convenient to see the effect in real time after changing the page.

Error After Configuring Dynamic Compilation

I ran into a problem here that I hadn't encountered in previous .NetCore3.1 projects

After adding dynamic compilation, the program threw an error on startup

Unhandled exception. System.ArgumentNullException: Value cannot be null. (Parameter 'source')
   at System.Linq.ThrowHelper.ThrowArgumentNullException(ExceptionArgument argument)
   at System.Linq.Enumerable.OfType[TResult](IEnumerable source)
   at Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.PageActionDescriptorProvider..ctor(IEnumerable`1 pageRouteModelProviders, IOptions`1 mvcOptionsAccessor, IOptions`1 pag
esOptionsAccessor)
   ...省略一大堆报错信息
   at Program.<Main>$(String[] args) in StarBlog\StarBlog.Web\Program.cs:line 96

After searching, I found a Github issues: https://github.com/dotnet/aspnetcore/issues/40609

Do you have the 6.0.201 SDK / 6.0.3 Microsoft.AspNetCore.App runtime installed? Patch builds of packages typically require a corresponding version of the runtime to be installed.

I checked my dotnet SDK version—it's 6.0.101. Looks like an SDK bug; updating the version should fix it~

(Ten minutes later) The update is done, and the problem is indeed solved!

References

_EOF_

StarBlog Blog Development Notes (12): Razor Page Dynamic Compilation

本文作者:
程序设计实验室
版权声明:
本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!

相关文章

讨论

共 0 条

良言一句三冬暖,恶语伤人六月寒。

加载评论中…