为什么ASP.NET MVC Html.CheckBox输出两个具有相同名称的INPUT?

时间:2009-07-14 19:04:01

标签: asp.net-mvc

为什么世界会这样做:

<%= Html.CheckBox("ForSale", Model.Product.ForSale)%> For Sale

产生以下HTML:

<input id="ForSale" name="ForSale" type="checkbox" value="true" />
<input name="ForSale" type="hidden" value="false" />
For Sale

现在每当我选中此框并访问Request.Form["ForSale"]时,我都会得到"true,false"的荒谬答案。我应该解析那个吗?

这个隐藏字段不会出现在其他HtmlHelper控件中,为什么它会用于CheckBox?

如何关闭这个愚蠢的“功能”?或者HtmlHelper刚刚超出其实用性?

更新

从下面的答案中可以看出,这背后有一些逻辑。我准备了一个小扩展方法,所以我不必考虑它(感谢@ eu-ge-ne):

    public static bool GetCheckBoxValue(this System.Web.HttpRequestBase req, 
                                        string name) {
        return Convert.ToBoolean(req.Form.GetValues(name).First());
    }

7 个答案:

答案 0 :(得分:38)

如果未选中该字段,则会强制包含该字段。如果取消选中复选框,它将不会作为页面的一部分发送 - 只有在选中它们时才会发送它们,然后它们的值为true。如果取消选中复选框,隐藏字段将确保将发送false,因为始终会发送隐藏字段。

答案 1 :(得分:5)

我采取了不同的方法:

不要使用Html.CheckBoxFor或Html.CheckBox帮助器方法来渲染复选框,而是使用普通的html渲染它:

<input id="ShowOther" name="ShowOther" value="<%=Model.ShowOther %>" type="checkbox" <% if (Model.ShowOther)  { %>checked="checked"<% } %> />

我添加了一个jQuery脚本,用于在选中/取消选中复选框时设置值。

<script type="text/javascript">
    $(function() {
        $('#ShowOther').click(function() {
            var checked = $(this).attr('checked');
            if (checked != undefined)
                $(this).val(true);
            else
                $(this).val(false);
        });
    });
</script>

就我可以测试一下,似乎总是将正确的发送到Controller,并且“true,false”不再存在问题。< / p>

答案 2 :(得分:3)

以下是我在其中一个应用中完成此操作的方法。令人沮丧,但似乎有效。

public virtual ActionResult Edit(int id, FormCollection values)
{
    SomeObject dbData = _repository.GetSomeObject(id);

    try
    {
        UpdateModel(dbData);
        if (values.GetValues("CheckBoxId").Contains("true")) 
            dbData.SomeBooleanProperty = true;
        else 
            dbData.SomeBooleanProperty = false;

        _repository.Save();

        Session["Success"] = "Successfully edited the part.";
        return RedirectToAction("Index");
    }
    catch
    {
        // Handle validation errors here
        return View(new SomeObjectFormViewModel(dbData));
    }
}

希望这会有所帮助。如果您有任何后续问题,请发表评论,我会相应地更新我的答案。

答案 3 :(得分:2)

如果未选中CheckBox,则表单将不会包含在表单提交中。所以这个“功能”为每个CheckBox提供了一个结果。未经检查的那些将只是“假”。

我已经实现了自己的CheckBox帮助函数,它们的工作方式不同。大多数时候我不想要真或假,而只是复选框值的集合。通过用于执行操作的id选择某些项目非常棒。即使在列表中,我也不想要未经检查的项目。

您可以查看html扩展的源代码,并使用类似的结构来创建自己的CheckBox方法。

http://aspnet.codeplex.com/sourcecontrol/changeset/view/23011?projectName=aspnet#288010

我会发布我的,但我没有使用标准的HtmlHelper类,所以它可能会更令人困惑。我确实在我的CheckBox函数中添加了一个值参数,这样我就可以使用特定的id值而不是“true”或“false”。

答案 4 :(得分:2)

  

现在每当我勾选方框并访问Request.Form [“ForSale”]时,我都会得到“真,假”的荒谬回答。我应该解析那个吗?

试试这个:

var ForSale = Convert.ToBoolean(Request.Form.GetValues("ForSale").First());

<强>更新:

  

如果在下一个MVC构建中它将以反转顺序“false,true”返回值,该怎么办? ...... - Mastermind

var ForSale = Request.Form.GetValues("ForSale")
    .Select(x => x.ToUpperInvariant()).Contains("TRUE");

// or

// FormatException can be thrown from Convert.ToBoolean()
var ForSale = Request.Form.GetValues("ForSale")
    .Select(x => Convert.ToBoolean(x)).Contains(true);

答案 5 :(得分:0)

尝试

request.form["chkBoxes"].replace("false","").split(new char[] {','}, stringsplitoptions.removeemptyentries);

答案 6 :(得分:0)

我认为最干净的解决方案是:

(bool)formCollection["key"].ConvertTo(typeof(bool))