記一次Razor Pages無法編譯問題及解決

来源:https://www.cnblogs.com/hxyes/p/18440717
-Advertisement-
Play Games

Redis Stream簡介 Redis Stream是隨著5.0版本發佈的一種新的Redis數據類型: 高效消費者組:允許多個消費者組從同一數據流的不同部分消費數據,每個消費者組都能獨立地處理消息,這樣可以並行處理和提高效率。 阻塞操作:消費者可以設置阻塞操作,這樣它們會在流中有新數據添加時被喚醒 ...


解決方案寫在前面:更新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 發現確實有新版本,發現版本號差的並不是很大,所以一開始並沒有報太大希望,但更新後再編譯,一切問題都消失了……

困擾我這麼久的問題,竟然一次更新就解決了,完全就沒有幻想中力輓狂瀾的澎湃啊啊啊啊啊~~~


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 人工智慧artificial intelligence 是電腦互聯網信息技術多年積累和不同互聯網公司共同構造的產物。人工智慧和大數據領域聯繫很大。每個軟體公司都有公司的業務數據和目標客戶。中央倉庫和私有倉庫保存著公有數據和私有數據。Java應用開發中的Maven是對實體本地jar包的一種互聯網分佈 ...
  • 正文 忽然想起,昨天有一個財政局的工作人員,過來轉款。那時候已經快下班了。我們給他辦完之後,他說他沒想到這麼快。看來還得回去,明明都打算不回去了來著。 我有些疑惑。照理來說,財政局應該挺好玩。我這麼問他。他苦笑了一下,說要是好玩就回去上班了,天天都不想去單位。然後開始感慨我們的銀行工作好。 我實在沒 ...
  • 大家好,我是風箏 個人博客:【古時的風箏】。 本文目的為個人學習記錄及知識分享。如果有什麼不正確、不嚴謹的地方請及時指正,不勝感激。 每一個贊都是我前進的動力。 公眾號:「古時的風箏」 前幾天順手改的一個安卓啟動器,開源沒幾天,沒想到GitHub上已經獲得了40多顆星,要知道我前段時間花 ...
  • 部署SpringBoot項目(通關版) 一、概述 使用 java -jar 命令直接部署項目的JAR包和使用Docker製作鏡像進行部署是兩種常見的部署方式。以下是對這兩種方式的概述和簡要的優劣勢分析: 1.1、使用 java -jar 命令直接部署項目的JAR包 概述: 通過 java -jar ...
  • 在 Python 中,字元串格式化是將變數插入到字元串中的一種方式,Python 提供了多種字元串格式化的方法,包括舊式的 % 格式化、新式的 str.format 方法以及 f-string(格式化字元串字面量)。 ...
  • 一:背景 1. 講故事 前些天在看 AOT的時候關註了下 源生成器,挺有意思的一個東西,今天寫一篇文章簡單的分享下。 二:源生成器探究之旅 1. 源生成器是什麼 簡單來說,源生成器是Roslyn編譯器給程式員開的一道口子,在這個口子里可以塞入一些自定義的cs代碼,讓Roslyn編譯器在編譯代碼的時候 ...
  • 一、依賴註入相關知識 1.1、依賴註入的原理和優點 依賴註入(DI),是IOC控制反轉思想 的實現。由一個DI容器,去統一管理所有的服務生命周期,服務的創建、銷毀、獲取,都是由DI容器去處理的。 依賴註入,很大程度解耦了服務之間的依賴關係,服務之間依賴的是抽象(依賴的是 服務/服務介面 的 “類型” ...
  • 在Linux centos環境下安裝部署sql server資料庫,並結合cpolar內網穿透工具,創建安全隧道將其映射到公網上,獲取公網地址,實現在外異地遠程連接家裡/公司的sqlserver資料庫,而無需公網IP,無需設置路由器,亦無需雲伺服器。 1.安裝sql server 下載 SQL Se ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...