asp.net-mvc asp.net mvc:为什么 Html.CheckBox 生成额外的隐藏输入

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2697299/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-08 00:16:37  来源:igfitidea点击:

asp.net mvc: why is Html.CheckBox generating an additional hidden input

asp.net-mvc

提问by Omu

I just noticed that Html.CheckBox("foo")generates 2 inputs instead of one, anybody knows why is this so ?

我只是注意到Html.CheckBox("foo")生成 2 个输入而不是一个,有人知道为什么会这样吗?

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

采纳答案by LukLed

If checkbox is not selected, form field is not submitted. That is why there is always false value in hidden field. If you leave checkbox unchecked, form will still have value from hidden field. That is how ASP.NET MVC handles checkbox values.

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

If you want to confirm that, place a checkbox on form not with Html.Hidden, but with <input type="checkbox" name="MyTestCheckboxValue"></input>. Leave checkbox unchecked, submit form and look at posted request values on server side. You'll see that there is no checkbox value. If you had hidden field, it would contain MyTestCheckboxValueentry with falsevalue.

如果您想确认这一点,请在表单上放置一个复选框,而不是使用 Html.Hidden,而是使用<input type="checkbox" name="MyTestCheckboxValue"></input>. 取消选中复选框,提交表单并查看服务器端发布的请求值。您会看到没有复选框值。如果您有隐藏字段,它将包含MyTestCheckboxValuefalse值的条目。

回答by Alexander Trofimov

You can write a helper to prevent adding the hidden input:

您可以编写一个帮助程序来防止添加隐藏输入:

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);
    }
}

use it:

用它:

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

回答by Desmond

when the check box is checked and submitted perform this

当复选框被选中并提交时,执行此操作

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

Refer

参考

回答by Valamas

The manual approach is this:

手动方法是这样的:

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

回答by Ciro Corvino

This is the strongly typed version of Alexander Trofimov's solution:

这是 Alexander 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);
    }
}

回答by Dave D

Use Contains, it will work with the two possible post values: "false" or "true,false".

使用包含,它将使用两个可能的帖子值:“false”或“true,false”。

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

回答by BlueKore

This is not a bug! It adds the possibility of having always a value, after posting the form to the server. If you want to deal with checkbox input fields with jQuery, use the prop method (pass the 'checked' property as the parameter). Example: $('#id').prop('checked')

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

回答by Sa?d Mezhoud

You can try to initialize the constructor of your Model like that :

您可以尝试像这样初始化模型的构造函数:

public MemberFormModel() {
    foo = true;
}

and in your view :

在你看来:

@html.Checkbox(...)
@html.Hidden(...)

回答by Matthew Lock

I found this really caused issues when I had a WebGrid. The sorting links on the WebGrid would turn by the doubled up querystring or x=true&x=false into x=true,false and cause a parse error in checkbox for.

我发现当我有一个 WebGrid 时,这确实引起了问题。WebGrid 上的排序链接将通过加倍的查询字符串或 x=true&x=false 转换为 x=true,false 并导致复选框中的解析错误。

I ended up using jQuery to delete the hidden fields on the client side:

我最终使用 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>

回答by VDWWD

The hidden input was causing problems with styled checkboxes. So I created a Html Helper Extension to place the hidden input outside the div containing the CheckBox.

隐藏的输入导致样式复选框出现问题。所以我创建了一个 Html Helper Extension 来将隐藏的输入放置在包含 CheckBox 的 div 之外。

using System;
using System.Linq.Expressions;
using System.Text;
using System.Web.Mvc;
using System.Web.Routing;

namespace YourNameSpace
{
    public static class HtmlHelperExtensions
    {
        public static MvcHtmlString CustomCheckBoxFor<TModel, TValue>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TValue>> expression, string labelText)
        {
            //get the data from the model binding
            var fieldName = ExpressionHelper.GetExpressionText(expression);
            var fullBindingName = htmlHelper.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldName(fieldName);
            var fieldId = TagBuilder.CreateSanitizedId(fullBindingName);
            var metaData = ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData);
            var modelValue = metaData.Model;

            //create the checkbox
            TagBuilder checkbox = new TagBuilder("input");
            checkbox.MergeAttribute("type", "checkbox");
            checkbox.MergeAttribute("value", "true"); //the visible checkbox must always have true
            checkbox.MergeAttribute("name", fullBindingName);
            checkbox.MergeAttribute("id", fieldId);

            //is the checkbox checked
            bool isChecked = false;
            if (modelValue != null)
            {
                bool.TryParse(modelValue.ToString(), out isChecked);
            }
            if (isChecked)
            {
                checkbox.MergeAttribute("checked", "checked");
            }

            //add the validation
            checkbox.MergeAttributes(htmlHelper.GetUnobtrusiveValidationAttributes(fieldId, metaData));

            //create the outer div
            var outerDiv = new TagBuilder("div");
            outerDiv.AddCssClass("checkbox-container");

            //create the label in the outer div
            var label = new TagBuilder("label");
            label.MergeAttribute("for", fieldId);
            label.AddCssClass("checkbox");

            //render the control
            StringBuilder sb = new StringBuilder();
            sb.AppendLine(outerDiv.ToString(TagRenderMode.StartTag));
            sb.AppendLine(checkbox.ToString(TagRenderMode.SelfClosing));
            sb.AppendLine(label.ToString(TagRenderMode.StartTag));
            sb.AppendLine(labelText); //the label
            sb.AppendLine("<svg width=\"10\" height=\"10\" class=\"icon-check\"><use xlink:href=\"/icons.svg#check\"></use></svg>"); //optional icon
            sb.AppendLine(label.ToString(TagRenderMode.EndTag));
            sb.AppendLine(outerDiv.ToString(TagRenderMode.EndTag));

            //create the extra hidden input needed by MVC outside the div
            TagBuilder hiddenCheckbox = new TagBuilder("input");
            hiddenCheckbox.MergeAttribute("type", HtmlHelper.GetInputTypeString(InputType.Hidden));
            hiddenCheckbox.MergeAttribute("name", fullBindingName);
            hiddenCheckbox.MergeAttribute("value", "false");
            sb.Append(hiddenCheckbox.ToString(TagRenderMode.SelfClosing));

            //return the custom checkbox
            return MvcHtmlString.Create(sb.ToString());
        }

Result

结果

<div class="checkbox-container">
    <input checked="checked" id="Model_myCheckBox" name="Model.myCheckBox" type="checkbox" value="true">
    <label class="checkbox" for="Model_myCheckBox">
        The checkbox label
        <svg width="10" height="10" class="icon-check"><use xlink:href="/icons.svg#check"></use></svg>
    </label>
</div>
<input name="Model.myCheckBox" type="hidden" value="false">