asp.net mvc: почему Html.CheckBox создает дополнительный скрытый ввод - PullRequest
198 голосов
/ 23 апреля 2010

Я только что заметил, что Html.CheckBox("foo") генерирует 2 входа вместо одного, кто-нибудь знает, почему это так?

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

Ответы [ 10 ]

183 голосов
/ 23 апреля 2010

Если флажок не установлен, поле формы не отправляется.Вот почему всегда есть ложное значение в скрытом поле.Если вы оставите флажок не установленным, форма все равно будет иметь значение из скрытого поля.Именно так ASP.NET MVC обрабатывает значения флажков.

Если вы хотите подтвердить это, установите флажок в форме не с Html.Hidden, а с <input type="checkbox" name="MyTestCheckboxValue"></input>.Оставьте флажок снятым, отправьте форму и посмотрите значения отправленных запросов на стороне сервера.Вы увидите, что значение флажка отсутствует.Если у вас есть скрытое поле, оно будет содержать MyTestCheckboxValue запись со значением false.

30 голосов
/ 21 июня 2014

Вы можете написать помощника для предотвращения добавления скрытого ввода:

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})
11 голосов
/ 01 ноября 2012

когда флажок установлен и отправлен, выполните это

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

См.

7 голосов
/ 10 октября 2011

Ручной подход таков:

bool IsDefault = (Request.Form["IsDefault"] != "false");
5 голосов
/ 20 июня 2017

Это строго типизированная версия решения Александра Трофимова:

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);
    }
}
1 голос
/ 31 мая 2017

Использование Содержит, он будет работать с двумя возможными значениями публикации: "ложь" или "правда, ложь".

bool isChecked = Request.Form["foo"].Contains("true");
0 голосов
/ 22 мая 2019

Скрытый ввод вызывал проблемы со стилизованными флажками. Поэтому я создал Html Helper Extension для размещения скрытого ввода вне div, содержащего CheckBox.

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

Результат

<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">
0 голосов
/ 29 марта 2017

Я обнаружил, что это действительно вызывало проблемы, когда у меня была WebGrid.Сортировка ссылок в WebGrid превратится на удвоенную строку запроса или x = true & x = false в x = true, false и вызовет ошибку разбора в флажке для.

В итоге я использовал 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 голосов
/ 19 октября 2015

Вы можете попытаться инициализировать конструктор вашей Модели так:

public MemberFormModel() {
    foo = true;
}

и по вашему мнению:

@html.Checkbox(...)
@html.Hidden(...)
0 голосов
/ 09 июня 2015

Это не ошибка!Это добавляет возможность иметь всегда значение после отправки формы на сервер.Если вы хотите иметь дело с полями ввода флажков с помощью jQuery, используйте метод prop (передайте свойство 'checked' в качестве параметра).Пример: $('#id').prop('checked')

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...