透過js賦值給唯讀的TextBox,PostBack後會被重置為預設值(Net2.0以上環境)
手邊有個 Web Application 專案,要從 1.1 升版到 3.5,一切都順利完成,好像沒有問題,但是,事情不是憨人想的那麼簡單,就在程式交付後,客戶回報某個日期欄位不是他送出表單時填寫的值,造成資料面異常。趕快回來檢查程式,發現該欄位是一個唯讀的 TextBox 控制項,並掛上 jQuery 小日曆,使用者可以操作小日曆選日期,然後以 js 給 TextBox 值,接著 PostBack 後取值並做相關處理。這個作業在 .Net1.1 都很正常,但是升版到 .Net3.5,PostBack 後,TextBox.Text 會是欄位預設值。
先講結論,這個是 .Net 2.0 後,因為安全性強化所導致的情況:
MSDN:system.web.ui.webcontrols.textbox.readonly
摘要重點:The Text value of a TextBox control with the ReadOnly property set to true is sent to the server when a postback occurs, but the server does no processing for a read-only text box. The value of the Text property is preserved in the view state between postbacks unless modified by server-side code.
處理方式,我們是選擇改用 jQeuery 在 Document.Ready 時,設定該欄位「唯讀」,而不要透過 TextBox 的 ReadOnly 屬性來設定。當然,根據 MSDN 的說法,其實 ReadOnly 的 TextBox,其 Text 屬性值還是會送回 Server 端,只是 Server 端不會處理它,換言之,用 Request.Form(“控制項ID”),應該也可以取到透過 js 異動過的值。
以下是測試程式:
Default.aspx
<%@ Page Language="vb" AutoEventWireup="false" CodeBehind="Default.aspx.vb" Inherits="TextBoxReadOnlyTest._Default" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title>TextBox Readonly 測試</title>
<script src="Scripts/jquery-1.7.1.min.js" type="text/javascript"></script>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:TextBox runat="server" ID="txtProperty" ReadOnly="True" Text="Property"></asp:TextBox><br />
<asp:TextBox runat="server" ID="txtjQuery" Text="jQuery"></asp:TextBox><br />
<input id="btnSetValue" type="button" value="從Client設定TextBox的值" />
<asp:Button ID="btnGo" runat="server" Text="Postback~~" /><br />
Property readonly:
<asp:Label runat="server" ID="lblProperty"></asp:Label><br />
jQuery readonly:
<asp:Label runat="server" ID="lbljQuery"></asp:Label>
</div>
<script language="javascript" type="text/javascript">
$(function () {
$("#txtjQuery").attr("ReadOnly", true);
$("#btnSetValue").click(setTxtValue);
});
function setTxtValue() {
$(":text").val("Hello World.");
}
</script>
</form>
</body>
</html>
Default.aspx.vb
Public Class _Default
Inherits System.Web.UI.Page
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
End Sub
Private Sub btnGo_Click(sender As Object, e As EventArgs) Handles btnGo.Click
lblProperty.Text = txtProperty.Text
lbljQuery.Text = txtjQuery.Text
End Sub
End Class
頁面顯示,PostBack 前:
按了【從Client設定TextBox的值】鈕,兩個 TextBox 的值都被改變了:
按【Postback~】鈕,進入監看式看看,果不其然,txtProperty.Text 是預設值,但是 Request.Form(“txtProperty”) 可以取到 js 修改過的值:
最後回到頁面的結果:
--------
沒什麼特別的~
不過是一些筆記而已