我刚注意到Html.CheckBox("foo")
生成2个输入而不是1个,有人知道为什么会这样吗?
<input id="foo" name="foo" type="checkbox" value="true" />
<input name="foo" type="hidden" value="false" />
答案 0 :(得分:181)
如果未选中复选框,则不提交表单字段。这就是隐藏领域总是存在虚假价值的原因。如果未选中复选框,则表单仍将具有隐藏字段的值。这就是ASP.NET MVC处理复选框值的方式。
如果您想确认这一点,请在表单上放置一个复选框,而不是使用Html.Hidden,但使用<input type="checkbox" name="MyTestCheckboxValue"></input>
。保持复选框未选中,提交表单并查看服务器端的已发布请求值。你会看到没有复选框值。如果您有隐藏字段,则会包含MyTestCheckboxValue
条目,其值为false
。
答案 1 :(得分:30)
您可以编写帮助以防止添加隐藏的输入:
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})
答案 2 :(得分:11)
答案 3 :(得分:7)
手动方法是:
bool IsDefault = (Request.Form["IsDefault"] != "false");
答案 4 :(得分:5)
这是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);
}
}
答案 5 :(得分:2)
从 ASP.NET (Core) 5 开始,将此添加到您的启动:
services.Configure<MvcViewOptions>(options =>
{
// Disable hidden checkboxes
options.HtmlHelperOptions.CheckBoxHiddenInputRenderMode = CheckBoxHiddenInputRenderMode.None;
});
以您的观点为例:
<input class="form-check-input" asp-for="@Model.YourBool" />
不再在您的表单中创建此属性的附加隐藏字段:
<input class="form-check-input" type="checkbox" data-val="true" data-val-required="The YourBool field is required." id="YourBool" name="YourBool" value="true" />
来源: https://github.com/dotnet/aspnetcore/pull/13014#issuecomment-674449674
答案 6 :(得分:1)
使用包含,它将使用两个可能的帖子值:“false”或“true,false”。
bool isChecked = Request.Form["foo"].Contains("true");
答案 7 :(得分:1)
截至2020/11和.NET 5处于预览阶段,有一个pull request应该可以控制此行为。谢谢你们!
无论如何,如果有人发现它有用,亚历山大·特罗菲莫夫的答案的.NET Core 3.0端口:
public static IHtmlContent CheckBoxSimple(this IHtmlHelper htmlHelper, string name)
{
TextWriter writer = new StringWriter();
IHtmlContent html = htmlHelper.CheckBox(name);
html.WriteTo(writer, HtmlEncoder.Default);
string checkBoxWithHidden = writer.ToString();
string pureCheckBox = checkBoxWithHidden.Substring(0, checkBoxWithHidden.IndexOf("<input", 1));
return new HtmlString(pureCheckBox);
}
答案 8 :(得分:0)
这不是错误!在将表单发布到服务器之后,它增加了始终具有值的可能性。
如果要使用jQuery处理复选框输入字段,请使用prop方法(将'checked'属性作为参数传递)。
示例:$('#id').prop('checked')
答案 9 :(得分:0)
您可以尝试初始化模型的构造函数:
public MemberFormModel() {
foo = true;
}
并在您看来:
@html.Checkbox(...)
@html.Hidden(...)
答案 10 :(得分:0)
隐藏的输入导致样式复选框出现问题。因此,我创建了一个HTML帮助程序扩展,以将隐藏的输入放置在包含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">
答案 11 :(得分:-1)
当我有一个WebGrid时,我发现这确实引起了问题。 WebGrid上的排序链接将通过加倍的查询字符串或x = true&amp; 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>