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
asp.net mvc: why is Html.CheckBox generating an additional hidden input
提问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 MyTestCheckboxValue
entry with false
value.
如果您想确认这一点,请在表单上放置一个复选框,而不是使用 Html.Hidden,而是使用<input type="checkbox" name="MyTestCheckboxValue"></input>
. 取消选中复选框,提交表单并查看服务器端发布的请求值。您会看到没有复选框值。如果您有隐藏字段,它将包含MyTestCheckboxValue
带false
值的条目。
回答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
回答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">