记一次Razor Pages无法编译问题及解决

news/2024/9/30 12:16:31

解决方案写在前面:更新Visual Studio及相关组件,本人版本自17.8.0更新至17.11.4

缘起于公司的一个业务接口,在有一些信息需要在应用内嵌的webview中展示,信息不少,涉及的前端技术不复杂,但是拼字符串太罗嗦,所以想到了添加一个Razor页面,所以,常规逻辑,在服务上注册'''AddRazorPages''',构建后使用映射方法'''MapRazorPages''',然后调试。这次调试没有问题,页面也能正常显示。因为是微信的小程序,并且是在手机上演示,网站地址要在配置的业务域名上,所以基本写完了页面,第一时间就把应用部署到了iis的测试端口上。然后问题就发生了————配置的首页返回404,访问业务所在的url也返回404。

因为几乎是第一次正式用Razor,所以尝试了检查url,补全index甚至补全.cshtml,都是一样的404。再后来检查了应用的日志,发现除了页面访问的w3cLog记录,没有任何其他的记录,但页面使用了Ef core 对SQl Server 的查询,而查询的日志项并没有在日志过滤规则之外,所以基本确定了页面并没有被执行。

本地调试可以执行,部署后不能执行,第一时间就是想到的环境不一致,Development和Production,对应开发环境和生产环境。在Visual Studio使用调试时ASPNETCORE_ENVIRONMENT这个变量要被设置成"Development"的,但直接执行,该环境变量没有定义,应用默认的状态是Production。

在Debug文件夹运行可执行文件,结果发现依然404。注意到Pages 文件夹没有,第一时间考虑有两种可能:一、项目设置错误,没有在生成时把文件复制到文件夹;二、考虑cshtml文件被编译到dll中了(实际上就是这样的,但当时的我并不能确认)。

先考虑第一种可能,这个实操不难,只需要在项目配置中添加

    <Content Update="Pages\*.cshtml"><CopyToOutputDirectory>Always</CopyToOutputDirectory></Content>

再生成一次,第一遍不配置ASPNETCORE_ENVIRONMENT变量,结果是相关页面依旧404,第二遍,配置ASPNETCORE_ENVIRONMENT为Development,终于,页面正常展示了。但奇怪的是,进一步发布->运行时,依然需要将ASPNETCORE_ENVIRONMENT变量设置为Development??这不应该!(此时的我依然没觉得复制Pages/*.cshtml有什么问题,就是觉得配置被搞出问题了)设置为开发环境显然不合理,很多配置都是针对开发环境的,SwaggerUI也会展示,总不能在发布到服务器前再改一次代码吧?

不过,由于第二天要演示,而且由于微信小程序的各种**门槛,不得不部署,这时候IIS又闹情绪,照网上的办法,又是配置,又是配置的,运行起来的服务始终是生产环境,总不能改系统的环境变量,毕竟上面的陈年老项目认到这个变量指不定激动的抽过去了也不一定。不过,办法总比困难多,Environment.SetEnvironmentVariable方法解决这个问题,其实也是一开始就想到它了,但为了不动现有的代码,一直没舍得用,遵循下老祖宗的开闭原则嘛。但第二天的演示更要紧,不得不做一个违背老祖宗的决定~

演示结束,立马回到这个问题,首先想到的就是新建一个项目。这下可不得了了,不论改环境变量还是复制文件,都成了404了。明明就是默认的Razor Pages模板,去MSDN上给的代码也都一样,但就是跑不起来。无头苍蝇一样搜了各种办法,但都没有针对我的问题,寻找文心一言和chatGPT的解答,也都是不合我意。

不过,最终在各种关键词搜索中,找到了杨中科老师在百家号上的一篇回答《如何让asp.net core mvc发布时候不编译cshtml视图》,虽然和我的想法相反,但这总算是相关的了。文章中介绍了让cshtml文件在运行时编译的方法,感觉能找到点苗头,于是按他说的一试,页面不再是404了。

或许到这,也就该结束了,毕竟用这方法不在考虑修改环境变量,也不用修改其他代码,问题算是圆满的解决了。。。吗?当然可以不再进一步探索,但是这篇反方向的解决方案让我有了一个新的灵感————:

文章满篇都在提要在运行时编译要做的额外配置,那要是不做呢?默认情况下它到底以何种方式运行。杨中科老师的文章中提到的两个属性标签已经让答案呼之欲出了:MvcRazorCompileOnPublish被置为了false,RazorCompileOnBuild同样被置为了false,也就是说,默认情况下,生成时和发布时Razor文件可能是被编译的。至于编译的形式,有可能就是jsp那样!(至于为什么先知道的jsp,学校给教的,大概在2020~2021年,哈哈:),现在估计依然在教。也是完成作业的过程中偶尔接触到的jsp文件编译后的反编译代码)

要探究编译后的文件,自然是少不了ILSpy,以往用它来分析过线上代码的问题,所以想到反编译就想到了它。对发布后的dll(没有使用运行时编译配置)进行分析,发现相关的命名空间下只有Model文件的编译,页面内容相关的代码一点没有。

但现在,在当前的环境下,我也是穷途末路了,新项目都这样,就算又有配置问题,找出来也不异于大海捞针,况且如此的绝望,在第一天下班后的尝试中就已经发生在了自己的电脑上。只有用本办法了————虚拟机。在一台Windows10环境的虚拟机上,我又重新搭建了一套Visual Studio,创建了新的Razor模板,运行。但这次,成功了,用了各种姿势都是。我不知道该说是意料之中还是意料之外。但总算是有成功的样本给我研究了。

拿到虚拟机上发布后的dll,丢到ILSpy中,这次能清楚的看到被编译到dll当中的页面内容,也不出意外,整体形式和jsp差不多。

但为什么?这一遭让我知道了cshtml在不特殊设置的情况下确实要被编译到dll中去的,相应的,把cshtml复制到构建文件夹并无必要。我一开始考虑的配置问题似乎就不存在……
剩下的就是对项目无尽的蹂躏了。当我在一次次的生成、调试或是发布时,我注意到一条警告:

CS9057 分析器程序集“C:\Program Files\dotnet\sdk\8.0.201\Sdks\Microsoft.NET.Sdk.Razor\source-generators\Microsoft.CodeAnalysis.Razor.Compiler.SourceGenerators.dll”引用了编译器的版本“4.9.0.0”,该版本高于当前正在运行的版本“4.8.0.0”

要放在平时,我根本不会在意,毕竟满屏的“属性未在构造器中赋值”中,它并不起眼,况且,就算偶然注意到它,也已经在多次偶然中与它相熟了。往常也没有奇怪的异常与它相关。但这次显眼Compiler和SourceGenerators让我无法再忽视它的存在。cshtml不就是在编译时没有生成成相应的代码嘛。

在前面蹂躏的过程中,也试了使用dotnet publish,结果是成功的,换了不同的sdk版本,都是成功。但自从注意到这条警告,我就试图在dotnet 的生成和发布中找到它,始终无果。
VS编译器版本不兼容了?怎么更新一下?vs编译用的不是我安装的sdk?

此时,自然就想到了更新Visual Studio,找到 vs installer 发现确实有新版本,发现版本号差的并不是很大,所以一开始并没有报太大希望,但更新后再编译,一切问题都消失了……

困扰我这么久的问题,竟然一次更新就解决了,完全就没有幻想中力挽狂澜的澎湃啊啊啊啊啊~~~

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.ryyt.cn/news/66466.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈,一经查实,立即删除!

相关文章

Svnlook使用浅谈(配置svn上传必须添加备注和删除权限)

在配置svn上传必须添加备注和删除权限前,我先隆重介绍下今天用到的svn命令svnlook。svnlook是检验Subversion版本库不同方面的命令行工具,不会对版本库有任何修改,只是查看,包括作者信息、文件内容、更改历史、文件大小、属性等。当然它有自己的独特语法 (1)语法格式:sv…

php: 查看opcache的使用情况

一,代码: opcache的各项参数设置效果怎么样?是否需要调整?我们需要了解一个opcache使用情况的统计,以供调整参数时处理 看php代码: <?php // 确保已经启用了Opcache if (extension_loaded(Zend OPcache) && function_exists(opcache_get_status)) {$status = …

adb命令输入中文字符

前言: adb 可以输入英文的文本,由于不支持unicode编码,所以无法输入中文,github上有个国外的大神写了个ADBKeyBoard输入法的apk,完美支持unicode编码,也能输入中文和其它字符及表情.解决方法: 1、https://zhangka.lanzouw.com/iKPQM2b7q9wd  密码:ah9d,下载并安装apk…

在 win10 2021 LTSC 上安装配置 wsl2 和 ubuntu

在 win10 2021 LTSC 上安装配置 wsl2 和 ubuntu 的过程: 参考官方文档:https://learn.microsoft.com/zh-cn/windows/wsl/install-manual(最后一步安装ubuntu发行版时,请自己解压, 然后拷贝到其他目录 再运行 ubuntu.exe, 否则默认放到了c盘 )win10系统启用wsl2:wsl --inst…

platformio创建工程过慢问题

在vscode安装platformio插件后,打开插件,等待platformio code安装完成后,关闭vscode打开任务管理器,结束进程platformio.exe和所有的Python.exe进程全部结束打开文件C:\用户名\你的用户名.platformio\penv\pip.conf,修改为如下配置[global] index-url = https://mirrors.h…

Guava Cache

1 Guava Cache 介绍 Guava 是 Google 提供的一套 JAVA 的工具包,而 Guava Cache 则是该工具包中提供的一套完善的 JVM 级别的高并发缓存框架。其实现机制类似 ConcurrentHashMap,但是进行了众多的封装与能力扩展。作为 JVM 级别的本地缓存框架,Guava Cache 具备缓存框架该有…

PART0-Oracle数据库介绍

1. Oracle数据库介绍 1.1. 关于关系型的数据库 每个组织都有必须存储和管理的信息,以满足其需求。例如,公司必须收集和维护员工的人力资源记录。这些信息必须对需要它的人可用。信息系统是一个用于存储和处理信息的正式系统。 信息系统可以是一组包含文件夹的纸箱,以及存储和…

六个核桃科技有限公司——团队展示

这个作业属于哪个课程 https://edu.cnblogs.com/campus/hniit/AI2022这个作业要求在哪里 https://edu.cnblogs.com/campus/hniit/AI2022/homework/13280团队名称 六个核桃科技有限公司这个作业的目标 让湖南信息学院人工智能专业成绩提高10%其他参考文献 kimi作业正文 智慧核桃…