2010-04-23 44 views
167

我刚刚注意到Html.CheckBox("foo")生成2个输入,而不是一个,任何人都知道这是为什么?asp.net mvc:为什么Html.CheckBox生成一个额外的隐藏输入

<input id="foo" name="foo" type="checkbox" value="true" /> 
<input name="foo" type="hidden" value="false" /> 
+7

真的疯了)))[剃刀视图引擎HTML.Checkbox方法 – Andrei 2013-06-24 10:52:09

+2

可能重复创建一个隐藏的输入。为什么?](http://stackoverflow.com/questions/5462967/razor-viewengine-html-checkbox-method-creates-a-hidden-input-why) – Matt 2014-06-30 13:18:59

+1

[ericvg's answer](http:// stackoverflow。com/a/5463032/2615878)在可能的重复问题中也解释了当提交复选框和隐藏字段时,模型联编程序执行的操作。 – Theophilus 2015-01-23 21:32:24

回答

155

如果未选中复选框,则不会提交表单字段。这就是为什么隐藏领域总是存在虚假价值的原因。如果您不勾选复选框,表单仍会具有隐藏字段的值。这就是ASP.NET MVC处理复选框值的方式。

如果您想确认,请将表单上的复选框与Html.Hidden放在一起,但用<input type="checkbox" name="MyTestCheckboxValue"></input>。离开复选框,提交表单并查看服务器端发布的请求值。您会看到没有复选框值。如果您有隐藏字段,则会包含MyTestCheckboxValue条目和false值。

+43

如果您没有选中框,那么显然答案是错误的,不需要发回该项目。愚蠢的设计在我看来。 – 2013-09-18 23:24:36

+42

@ TheMuffinMan:这不是愚蠢的选择。假设你的视图模型有一个名为'IsActive'的属性,它在构造函数中被初始化为'true'。用户取消选中复选框,但由于值未发送到服务器,所以模型联编程序不会将其选中,并且属性值不会更改。模型联编程序不应该假设,如果值没有发送,它被设置为false,因为它可能是您决定不发送此值。 – LukLed 2014-07-28 09:12:07

+14

它从一个无害的复选框开始,然后在你知道它有视图状态之前,它演变成ASP.NET MVCForms。 – 2015-04-15 23:16:49

6

手动的方法是这样的:

bool IsDefault = (Request.Form["IsDefault"] != "false"); 
+1

这是保证让你的复选框类型的值,而不是隐藏的类型值? – 2012-03-13 19:21:53

+1

这是无关紧要的。当复选框没有被选中时,它不会发布。所以隐藏盒会有'假'。如果复选框被选中,则返回(true,true)的值(我认为),这不等于'false'。 – 2012-06-12 21:33:17

+14

不,当选中复选框时,由于复选框和隐藏字段都是要发回的有效控件,因此都会发布true和false两个选项。 Mvc binder然后检查给定的namve是否存在真值,如果是,则它优选真值。您可以通过查看发布的数据来查看。它将具有针对单个名称的真值和假值。 – ZafarYousafi 2013-03-23 14:47:15

9
当复选框被选中,并提交

执行此

if ($('[name="foo"]:checked').length > 0) 
    $('[name="foo"]:hidden').val(true); 

Refer

20

你可以写一个帮助防止加入隐藏的输入:

using System.Web.Mvc; 
using System.Web.Mvc.Html; 

public static class HelperUI 
{ 
    public static MvcHtmlString CheckBoxSimple(this HtmlHelper htmlHelper, string name, object htmlAttributes) 
    { 
     string checkBoxWithHidden = htmlHelper.CheckBox(name, htmlAttributes).ToHtmlString().Trim(); 
     string pureCheckBox = checkBoxWithHidden.Substring(0, checkBoxWithHidden.IndexOf("<input", 1)); 
     return new MvcHtmlString(pureCheckBox); 
    } 
} 

使用它:

@Html.CheckBoxSimple("foo", new {value = bar.Id}) 
+3

这让我绊倒了一分钟,以防万一......如果你的助手在命名空间中,不要忘记添加'@using Your.Name。空间'在你的.cshtml剃刀视图文件的顶部。 – ooXei1sh 2015-07-24 16:00:00

+3

@ ooXei1sh或者,或者把你的帮手放在命名空间'System.Web.Mvc.Html'中,以便在所有视图上都可以访问 – Luke 2016-07-07 16:33:30

0

这不是一个错误!它增加了将表单发布到服务器后始终具有价值的可能性。 如果你想用jQuery处理复选框输入字段,请使用prop方法(传递'checked'属性作为参数)。 例子:$('#id').prop('checked')

0

您可以尝试初始化模式一样,构造函数:

public MemberFormModel() { 
    foo = true; 
} 

,并在您的视图:

@html.Checkbox(...) 
@html.Hidden(...) 
-1

我发现这真的引起的问题时,我有一个的WebGrid。 WebGrid上的排序链接会将加倍的查询字符串或x = true变为x = false变为x = true,并在复选框中导致解析错误。

我结束了使用jQuery删除客户端的隐藏字段:

<script type="text/javascript"> 
    $(function() { 
     // delete extra hidden fields created by checkboxes as the grid links mess this up by doubling the querystring parameters 
     $("input[type='hidden'][name='x']").remove(); 
    }); 
    </script> 
+0

如果我删除了隐藏的输入,页面就不能工作 – Max 2017-07-18 11:04:45

0

使用包含,将与两个可能的值后的工作:“假”或“真,假”。

bool isChecked = Request.Form["foo"].Contains("true"); 
2

这是亚历山大Trofimov的解决方案强类型版本:

using System.Web.Mvc; 
using System.Web.Mvc.Html; 

public static class HelperUI 
{ 
    public static MvcHtmlString CheckBoxSimpleFor<TModel>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, bool>> expression, object htmlAttributes) 
    { 
     string checkBoxWithHidden = htmlHelper.CheckBoxFor(expression, htmlAttributes).ToHtmlString().Trim(); 
     string pureCheckBox = checkBoxWithHidden.Substring(0, checkBoxWithHidden.IndexOf("<input", 1)); 
     return new MvcHtmlString(pureCheckBox); 
    } 
} 
相关问题