[asp.net-mvc] asp.net mvc : Html.CheckBox가 추가 숨겨진 입력을 생성하는 이유

방금 Html.CheckBox("foo")하나 대신 2 개의 입력 을 생성 하는 것으로 나타났습니다 .

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



답변

확인란을 선택하지 않으면 양식 필드가 제출되지 않습니다. 숨겨진 필드에 항상 잘못된 값이있는 이유입니다. 확인란을 선택하지 않으면 양식에 여전히 숨겨진 필드의 값이 있습니다. 이것이 ASP.NET MVC가 확인란 값을 처리하는 방법입니다.

확인하려면 Html.Hidden이 아닌을 사용하여 확인란을 선택하십시오 <input type="checkbox" name="MyTestCheckboxValue"></input>. 확인란을 선택하지 않은 상태로두고 양식을 제출하고 서버 측에서 게시 된 요청 값을 확인하십시오. 확인란 값이 없다는 것을 알 수 있습니다. 숨겨진 필드가 있으면 값 이있는 MyTestCheckboxValue항목 이 포함 false됩니다.


답변

숨겨진 입력을 추가하지 않도록 도우미를 작성할 수 있습니다.

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


답변

확인란이 선택되어 제출되면

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

보내다


답변

수동 접근 방식은 다음과 같습니다.

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


답변

다음은 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);
    }
}


답변

포함을 사용하면 “false”또는 “true, false”의 두 가지 가능한 게시 값으로 작동합니다.

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


답변

숨겨진 입력은 스타일 체크 박스에 문제를 일으켰습니다. 그래서 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());
        }

결과

<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">