某個採用先行編譯(Pre-compilied)的網站,部署後爆出錯誤:

[NullReferenceException: Object reference not set to an instance of an object.] MyPage.btnSomeQuery_Click(Object sender, EventArgs e) +136

由於btnSomeQuery_Click的程式邏輯頗複雜,直覺是某個運算變數應有值卻傳回null引發,但檢查程式碼後又幾乎都排除出現null的可能,追查推敲很久卻無所獲。為了檢測錯誤,特別在部署機器換上原始碼版本的aspx、aspx.cs,發現問題因此消失了。耗了大半天,最後才發現問題出在部署時只更新DLL,aspx遺漏未更新,而舊版aspx少了一個本次才新增的DropDownList,aspx欠缺<asp:DropDownList>宣告,導致NullReferenceException!

身為資深射手,為史萊姆等級茶包耗掉一小時是不被允許的,著實令人汗顏。而回頭檢討,一開始偵錯陷入錯誤方向,始於一個錯誤認知:

我一直誤認"當ASPX缺少必要的WebControl宣告,出現的錯誤訊息應該是CS0103: The name 'myDropDownList' does not exist in the current context之類的訊息,而不是NullReferenceException!"

因此,早早排除WebControl變數是null的可能性,草草放走殺人犯,拼命對其他幾段清白程式碼嚴刑拷打,徒勞無功。(有個讀取DataTable的Method還差點屈打成招哩!)

基本上,在Web Site Project模式下,若在aspx.cs呼叫aspx中未宣告的WebControl,的確會出現CS0103編譯錯譯。但在先行編譯網站,因編譯階段使用的是正確的aspx,故編譯好的DLL中,Code-Behind程式已知並宣告了該WebControl。而實際執行階段,Code-Behind程式配上短少WebControl的aspx,便形成有宣告WebControl變數,卻無法對應到aspx中的實體,導致null的狀況。

花掉一小時的寶貴青春上完課,下次再遇類似問題,就不會再傻傻分不清楚了。


Comments

Be the first to post a comment

Post a comment