Quantcast
Channel: 黑暗執行緒
Viewing all articles
Browse latest Browse all 2311

【茶包射手日記】ASP.NET 2.0 Web Site 升 3.5 怪異問題一則

$
0
0

分享在同事專案發現的有趣茶包。

同事接手超古老的 ASP.NET 2.0 WebSite 專案,第一步先升級成 3.5,從青銅器時代推演到鐵器時代。依過去經驗,3.5 也基於 2.0,除了要將 AJAX 擴充功能轉成內建,幾乎是無痛升級。(事實上,2.0 就算升 4.0/4.5 也很少遇到麻煩)

但這回遇上怪事。未升 3.5 前 Build Web Site 成功,升級後出現缺少 ASP.NET AJAX Toolkit版本問題, 排除過程冒出一個編譯錯誤,某個共用類別存取了外部程式庫元件的 internal屬性。程式寫法挺妙的,舉例來說,元件 CommLib.Data.DataHelper 有個內部屬性 connString,Web Site 裡的共用類別為了要存取它,故意把自己的 namespace 也改成 CommLib.Data,假裝跟程式庫成為一家人,彷彿這樣就可以存取到 internal 屬性! 依我所知,internal 限制同一組件內存取,要開放限制需由 internal 一方主動宣告(參考:【笨問題】紅杏出牆的internal類別),將 namespace 取一樣就想變自己人,跟改姓就能繼承遺產一樣天真。

但事實擺在眼前,原本 2.0 Build Web Site 是成功的,改成 3.5 才出錯,莫非 2.0 跟 3.5 行為不同? 3.5 底層仍是 2.0,不夠有此差異。取來專案,逐步剔除無關程式反覆測試,當搞清楚是怎麼一回事,我差點笑了出來~

首先,跨組件存取 internal 成員這事兒從頭到尾都是不可行的,不管在 2.0 還是 3.5 都是編譯錯誤。那 Build Web Site 可以成功又是怎麼一回事?後來我才注意到,這顆亂來的共用類別被誤放在網站專案的根目錄下,依據 Web Site 規則,不屬於任何 ASPX、ASCX 的共用程式應放在 App_Code 才能被編譯及引用,換言之,這個問題共用類別根本是一段沒用到的有錯廢 Code。推測還有一種可能,該 internal 屬性更早前曾被宣告為 public,但在 Web Site 根目錄放共用程式純屬白忙一場(幹這種傻事還會被 Visual Studio 警告,如下圖),編譯不到也用不了,至於為什麼專案會留著這段廢 Code 則是謎。

雖然 Build Web Site 會忽略放在根目錄下的共用類別,但如果在 Visual Studio 開啟它,Error List 倒是會忠實指出錯誤。所以,先前的怪現象是這麼來的 - .NET 2.0 時 Build Web Site 成功時沒開啟問題類別,升 3.5 後於修正過程在 IDE 開啟此一存取 internal 屬性類別,Error List 報錯,而我們誤判這是升 3.5 導致的問題(其實問題一直都在,只是先用沒用 VS2017 開啟它就眼不見為淨)。搞清楚這點,先前無法解釋「升 3.5 出錯後再降回 2.0 錯誤也不會消失」現象也有了合理解釋 - 有沒有錯誤要看你有沒有在 VS 開啟它,跟 2.0/3.5 無關。

用一段展示重演狀況,我故意在 Web Site 根目錄下放了一個 BadClass.cs,裡面有一段無厘頭程式碼 BadClass Bad Bad Bad;,確保此類別絕對無法被編譯。而如操作所示,一開始 Build Web Site 成功,Error List 無錯誤,開啟 BadClass.cs 後,Error List 出現三項錯誤,Solution Explorer 跟 BadClass.cs 冒出紅蚯蚓,但 Build Web Site 依舊是成功的!

真相大白,學到 Web Site 編譯行為的冷知識,收工~


Viewing all articles
Browse latest Browse all 2311

Trending Articles