ASP.NET 為防止惡意竄改,伺服器端渲染時若 ReadOnly="true",Postback 時會忽略客戶端修改的值,直接使用 ViewState 中的原始值(通常為空)。這是安全機制,非 Bug。
<asp:TextBox ID="TextBox1" runat="server" onfocus="this.blur();" />
<asp:TextBox ID="TextBox1" runat="server" ReadOnly="true" />
// 後台
string value = Request.Form[TextBox1.UniqueID]; // 建議用 UniqueID 而非 ID
// 或
string value = Request.Form["TextBox1"]; // 若無 MasterPage/命名容器
LoadPostData,直接讀取原始 HTTP 表單資料TextChanged 事件、驗證器可能失效protected void Page_Load(object sender, EventArgs e) {
if (!IsPostBack) {
TextBox1.Attributes["readonly"] = "readonly"; // 小寫 readonly
}
}
ReadOnly 屬性為 false,正常處理 Postback;瀏覽器端渲染出 readonly="readonly" 防止使用者編輯!IsPostBack 中執行,否則每次 Postback 重複添加屬性| 方案 | 後台取值 | 前台唯讀 | TextChanged | 驗證器 | 無障礙 | 推薦指數 |
|---|---|---|---|---|---|---|
| onfocus=blur | ✅ | 視覺上 | ✅ | ✅ | ❌ | ⭐⭐ |
| Request.Form | ✅ (手動) | ✅ | ❌ | ❌ | ✅ | ⭐⭐⭐ |
| Attributes添加 | ✅ (自動) | ✅ | ✅ | ✅ | ✅ | ⭐⭐⭐⭐⭐ |
// RowDataBound 中動態設置
protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e) {
if (e.Row.RowType == DataControlRowType.DataRow) {
var txt = (TextBox)e.Row.FindControl("TextBox1");
txt.Attributes["readonly"] = "readonly";
}
}
同理適用於所有輸入類控件。