透過js賦值給唯讀的TextBox,PostBack後會被重置為預設值(Net2.0以上環境)

  • 6513
  • 0

透過js賦值給唯讀的TextBox,PostBack後會被重置為預設值(Net2.0以上環境)

DotBlogs Tags: , ,

手邊有個 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 前:

161828

按了【從Client設定TextBox的值】鈕,兩個 TextBox 的值都被改變了:

162429

按【Postback~】鈕,進入監看式看看,果不其然,txtProperty.Text 是預設值,但是 Request.Form(“txtProperty”) 可以取到 js 修改過的值:

155650

最後回到頁面的結果:

162552

--------
沒什麼特別的~
不過是一些筆記而已