ASP.Net在回传时复选框的值错误?

26

我们有一个初始状态为禁用且选中的复选框。然后在客户端通过JavaScript启用它。如果用户取消选中该复选框并按下按钮以调用回发,则复选框的状态在服务器端仍然保持选中状态。这显然是不希望发生的行为。以下是示例。

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="testcb.aspx.cs" Inherits="ESC.testcb" %>

<!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></title>
</head>
<body>
    <form id="form1" runat="server">
    <script type="text/javascript">
        function buttonClick() {
            var cb = document.getElementById('<%= CheckBox1.ClientID %>');
            cb.disabled = false;
            cb.parentNode.disabled = false;
        }


    </script>

    <div>
        <asp:CheckBox ID="CheckBox1" runat="server" Checked="true" Enabled="false" />
        <asp:Button ID="Button1" runat="server" Text="Button" OnClientClick="buttonClick(); return false;" />
        <asp:Button ID="Button2" runat="server" Text="Button2" OnClick="button2Click" />
    </div>
    </form>
</body>
</html>

还有服务端代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

namespace ESC
{
    public partial class testcb : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
        }

        protected void button2Click(object sender, EventArgs e)
        {
            string h = "";
        }
    }
}

所以我们在“string h”行处中断,检查CheckBox1.Checked的值。它是true,即使在表单上未选中。


这是因为当您从代码后台设置控件属性时,页面的视图状态没有得到更新。 - S M Kamran
使用HTML控件代替服务器控件,我相信你的问题会得到解决。 - S M Kamran
1
@Kamran,Viewstate不是问题。 - Muhammad Akhtar
1
切换到HTML输入框并不能解决问题。 - Anthony
6个回答

36

这是ASP.NET已知的问题 - 如果在页面加载期间将复选框禁用且未在回发期间选中,则ASP.NET无法更新复选框。但我不确定具体原因 - 如果默认未选择该复选框并选择它,则服务器上的值会正确更改。

解决方法是在页面中添加一个表示复选框状态的隐藏字段,每当单击复选框时将其更新为"ON"或"OFF"等值。

然后在服务器上检查隐藏字段的值而非复选框本身,因为隐藏字段始终会被提交。


2
嗨,Sam,你能否提供有关“已知问题”的更多信息?KB或链接?我有一个复选框缺少“取消选中”功能; enabled == True,在OnInit中checked = false; enabled == True,在Page_load中checked = true; 但是在浏览器中未被选中,并且如果在此之前发生了另一个异步回发,则它将按预期工作。 - Dennis C
谢谢,我遇到了同样的问题。在经过许多调查后偶然发现了这篇帖子,最终得知这是 ASP.NET 中已知的问题 :) 解决方案对我有效。 - Nirman

18

我曾经遇到过类似的问题,CheckBox对象的Checked属性没有被正确地更新。要获取实际发布的值,您可以检查:

Request.Form[CheckBox1.UniqueID]

如果复选框被勾选,它的值将是'on',否则为null。


2
(六年后...)很奇怪。我的ASP.Net应用程序“有时候”会报告错误的ASP.Net复选框Checked值,而有时候这个建议确实有效...其他时候它会抛出异常,因为该控件的值在Request.Form值中找不到... - Mike Gledhill
这对我来说是最有效的解决方法,当其他方法都无法解决时!该值为“on”,但选中属性为“false”。 - Jamie M.

1

既然您已经在浏览器中使用JavaScript来操作控件状态,我建议您在页面加载事件中禁用复选框。这样,您的后台提交将正常工作...

<head>

  <script type="text/javascript">
    function buttonClick() {
      var cb = document.getElementById('<%= CheckBox1.ClientID %>');
      cb.disabled = false;
      cb.parentNode.disabled = false;
    }    
  </script>

</head>
<body onload="document.getElementById('<%= CheckBox1.ClientID %>').disabled = true;">
  <form id="form1" runat="server">
  <div>
    <asp:checkbox id="CheckBox1" runat="server" checked="true" />
    <asp:button id="Button1" runat="server" text="Button" onclientclick="buttonClick(); return false;" />
    <asp:button id="Button2" runat="server" text="Button2" onclick="button2Click" />
  </div>
  </form>
</body>

在我的项目中,我做过类似的事情。但是从安全性考虑来说并不是很好。如果用户禁用了Javascript,那么他基本上可以勾选该框并按保存按钮而没有任何阻碍。 - Simon Dufour

1

我可能没有正确理解问题,但是你不能只使用请求中的表单来检索CheckBox的值吗?所以在代码后台文件中的button2Click()中,您可以这样做:

Request.Form[CheckBox1.UniqueID]

2
不,浏览器无需提交禁用表单元素的值。 - user52898

0
你可以使用类似这样的代码。
if ((Request.Params["Checkbox1"] ?? "").ToString() == "on")

如果它没有被选中,它首先就不会通过,但这应该考虑到这一点。


0
这是一种替代解决方案,如果你需要避免重新编译源代码。 它只需在提交表单之前瞬间启用复选框即可。 1:向提交按钮添加以下参数:OnClientClick="EnableCheckbox()" 2:在页面上的某个位置添加此简单函数以启用它。
<script> 
       function EnableCheckbox() {
            document.getElementById("<%=chkMyCheckbox.clientID  %>").disabled = false;
        } 
</script>

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接