今天接獲回報,先前寫的控件(繼承自TextBox的數字輸入欄位WebControl)在ASP.NET 2.0下有問題,當控件ReadOnly設為True時,在前端用Javascript修改控件<INPUT>的Value,用Fiddler看,新值明明PostBack回後端了,但是在Server-Side查到的是前端修改前的舊值。

有點懷疑這是ASP.NET 2.0的Behavior改變,用TextBox測試,果然如此!

我的測試是先在Server-Side設定TextBox1屬性
TextBox1.Text=”OldValue”;
TextBox1.ReadOnly=true;
接著前端用document.all(“TextBox1”).value=”NewValue”;改變數值,PostBack後,Server-Side用TextBox1.Text取得的是”OldValue”,同樣的程式在1.1上執行結果為”NewValue”。

Google了一下,印證了這是ASP.NET 2.0的改變,主要是為了安全的考量,因為這樣可以防止前端利用Javascript或其他技巧去篡改已設為ReadOnly的欄位,提高安全性。不過呢,過去有不少專案將加總值等等設成ReadOnly,由JavaScript計算填入再傳入後端。我想若以最高安全標準來看,應該要在後端再重算一次,以免將有心人篡改過的數字寫入資料庫。只是同樣的邏輯要寫兩次(還一次用Javascript、一次用C#/VB.NET),成本有點高。若該欄位存的是連狗都沒興趣的數字,則便宜行事是可以被接受的(又不是在報特支費發票),如果你想要找回從前"前端對User設唯讀,但JavaScript修改值可以傳回"的模式,可以試試以下兩種做法:
1.用Request["TextBox1"]的方式取值
2.TextBox1.Attributes.Add("ReadOnly","ReadOnly");

雖然還是有解決方案,但比較煩的是,過去的一些ASP.NET 1.1專案,不少的TextBox.ReadOnly只用來擋使用者輸入,還是接受由JavaScript自動算值後填入;專案轉到2.0,表面上順利無誤,執行的結果可不太妙,全部掃一次Code的功夫看來是少不了,要做1.1->2.0移轉的朋友們要特別留意。


Comments

# by goal

黑大,想請教一下,我畫面上的texbox都是設定readonly的,這些textbox會接上資料庫,畫面上有按鈕可以選擇上一筆或下一筆,這個情況,我改成Request去取值,只需要傳key回去資料庫做選取就好,一個Request的情況下可能對效率影響不大,但如果我是在編輯模式,使用者按下儲存後,我想把textbox改成readonly避免在postback時使用者可以改變textbox當中的值,那這種情況下,使用大量的Request,是否會有什麼影響? ex: string a = TextBox.Text 和 string a = Request["TextBox"]

# by Jeffrey

to goal, 不知你所指的影響是在效能面還是安全面? 使用Request[".."]並不會影響效能,不管是否取用,欄位內容都已Post回Server端。差別在於TextBox.Text的內容來自ViewState(一個又臭又長的Hidden欄位)編碼解析而得、而Request["..."]取的是回傳內容裡TextBox=...&TextBox2=...所裝載的資料。ViewState的內容經過編碼,不易(非不能)被篡改、而前端可透過JavaScript可輕易修改Request["..."]的內容,這是主要的差別。希望有回答你的疑惑。

Post a comment