天天看点

基于.NetCore开发博客项目 StarBlog - (12) Razor页面动态编译

系列文章

  • 基于.NetCore开发博客项目 StarBlog - (1) 为什么需要自己写一个博客?
  • 基于.NetCore开发博客项目 StarBlog - (2) 环境准备和创建项目
  • 基于.NetCore开发博客项目 StarBlog - (3) 模型设计
  • 基于.NetCore开发博客项目 StarBlog - (4) markdown博客批量导入
  • 基于.NetCore开发博客项目 StarBlog - (5) 开始搭建Web项目
  • 基于.NetCore开发博客项目 StarBlog - (6) 页面开发之博客文章列表
  • 基于.NetCore开发博客项目 StarBlog - (7) 页面开发之文章详情页面
  • 基于.NetCore开发博客项目 StarBlog - (8) 分类层级结构展示
  • 基于.NetCore开发博客项目 StarBlog - (9) 图片批量导入
  • 基于.NetCore开发博客项目 StarBlog - (10) 图片瀑布流
  • 基于.NetCore开发博客项目 StarBlog - (11) 实现访问统计
  • 基于.NetCore开发博客项目 StarBlog - (12) Razor页面动态编译
  • ...

前言

最近有段时间没更新博客开发笔记了,怠惰了啊 = =..

趁着周末,给博客项目完善了一些细节的功能,然后准备部署上线~

本来这篇文章是要记录几个功能(主题切换、项目监控、随机图片接口)的实现的,不过我在写页面的时候发现每次改完Razor都要重启好麻烦,所以踩坑了一番,便有了本文。

Razor页面动态编译

虽然.Net6开始支持部分代码热更新了,不过还是很鸡肋,经常修改Razor页面了但点Apply还是没效果~

我还是用回.NetCore3.1之前常用的动态编译比较好~

首先NuGet安装

Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation

,在

Program.cs

中配置一下

原本添加MVC服务是这样的

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

改成这样(开发模式才启用动态编译)

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

也可以不修改C#代码,通过环境变量的方式实现,修改

launchSettings.json

文件,添加一个环境变量

这样启动程序的时候会动态加载

RuntimeCompilation

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

另外,还有更彻底的方法,发布打包的时候不要编译cshtml文件,方便在发布后修改Razor页面。

在项目配置文件 (

xxx.csproj

) 中配置

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

这样在发布的时候,所有的 Razor 视图都不会被预编译了,并且所有的视图都会一同被发布,方便线上环境修改Razor页面。

不过要注意在发布的生产环境中,修改视图文件是不会立即生效的,需要重启程序(对于 IIS 宿主的运行环境需要重启站点)才会生效。

还可以配置条件编译,详情可以参考:https://www.cnblogs.com/thinksea/articles/14772837.html

这样修改完Razor页面,保存,就会自动重新编译,方便修改页面后实时查看效果。

配置动态编译后报错

我在这里遇到一个问题,之前.NetCore3.1的项目没遇到过

添加了动态编译后启动程序报错

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
           

经过搜索,找到一个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.

看了下我的dotnet SDK版本,是 6.0.101 ,看来是SDK的bug,更新一下版本应该就行~

(过了十分钟)更新好了,问题果然解决了!

参考资料

  • .Net Core 5.0 Razor 预编译,动态编译,混合编译:https://www.cnblogs.com/thinksea/articles/14772837.html
  • .NET Hot Reload support for ASP.NET Core:https://docs.microsoft.com/en-us/aspnet/core/test/hot-reload?view=aspnetcore-6.0
  • Razor file compilation in ASP.NET Core:https://docs.microsoft.com/en-us/aspnet/core/mvc/views/view-compilation?view=aspnetcore-6.0&tabs=visual-studio
  • Can't get RazorPageOptions from DI with version 6.0.3 of Mvc.Razor.RuntimeCompilation:https://github.com/dotnet/aspnetcore/issues/40609

微信公众号:「程序设计实验室」

专注于互联网热门新技术探索与团队敏捷开发实践,包括架构设计、机器学习与数据分析算法、移动端开发、Linux、Web前后端开发等,欢迎一起探讨技术,分享学习实践经验。

继续阅读