Tôi chỉ nhận thấy rằng Html.CheckBox("foo")
tạo ra 2 đầu vào thay vì một, có ai biết tại sao lại như vậy không?
<input id="foo" name="foo" type="checkbox" value="true" />
<input name="foo" type="hidden" value="false" />
Tôi chỉ nhận thấy rằng Html.CheckBox("foo")
tạo ra 2 đầu vào thay vì một, có ai biết tại sao lại như vậy không?
<input id="foo" name="foo" type="checkbox" value="true" />
<input name="foo" type="hidden" value="false" />
Câu trả lời:
Nếu hộp kiểm không được chọn, trường biểu mẫu sẽ không được gửi. Đó là lý do tại sao luôn có giá trị sai trong trường ẩn. Nếu bạn bỏ chọn hộp kiểm, biểu mẫu sẽ vẫn có giá trị từ trường ẩn. Đó là cách ASP.NET MVC xử lý các giá trị hộp kiểm.
Nếu bạn muốn xác nhận điều đó, hãy đặt một hộp kiểm vào biểu mẫu không phải bằng Html.Hidden, nhưng với <input type="checkbox" name="MyTestCheckboxValue"></input>
. Bỏ chọn hộp kiểm, gửi biểu mẫu và xem các giá trị yêu cầu được đăng ở phía máy chủ. Bạn sẽ thấy rằng không có giá trị hộp kiểm. Nếu bạn có trường ẩn, nó sẽ chứa MyTestCheckboxValue
mục có false
giá trị.
IsActive
, được khởi tạo true
trong hàm tạo. Người dùng bỏ chọn hộp kiểm, nhưng vì giá trị không được gửi đến máy chủ, nên chất kết dính mô hình không nhận nó và giá trị thuộc tính không thay đổi. Chất kết dính mô hình không nên cho rằng, nếu giá trị không được gửi, nó được đặt thành false, vì đó có thể là quyết định của bạn không gửi giá trị này.
false
giá trị ngay cả khi chúng được chọn và điều đó gây nhầm lẫn. Các hộp kiểm bị vô hiệu hóa hoàn toàn không nên gửi bất kỳ giá trị nào, nếu ASP.NET muốn tương thích với hành vi HTTP mặc định.
Bạn có thể viết một trình trợ giúp để ngăn chặn việc thêm đầu vào ẩn:
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);
}
}
sử dụng nó:
@Html.CheckBoxSimple("foo", new {value = bar.Id})
@using Your.Name.Space
vào đầu tệp xem dao cạo .cshtml của bạn.
System.Web.Mvc.Html
để có thể truy cập được trên tất cả các chế độ xem
Cách tiếp cận thủ công là thế này:
bool IsDefault = (Request.Form["IsDefault"] != "false");
Đây là phiên bản được đánh máy mạnh mẽ của giải pháp của 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);
}
}
Các đầu vào ẩn đã gây ra vấn đề với các hộp kiểm theo kiểu. Vì vậy, tôi đã tạo tiện ích mở rộng Trình trợ giúp Html để đặt đầu vào ẩn bên ngoài div có chứa 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());
}
Kết quả
<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">
Bạn có thể thử khởi tạo hàm tạo của Mô hình của mình như thế:
public MemberFormModel() {
foo = true;
}
và theo quan điểm của bạn:
@html.Checkbox(...)
@html.Hidden(...)
Tôi thấy điều này thực sự gây ra vấn đề khi tôi có một WebGrid. Các liên kết sắp xếp trên WebGrid sẽ biến chuỗi truy vấn tăng gấp đôi hoặc x = true & x = false thành x = true, false và gây ra lỗi phân tích cú pháp trong hộp kiểm cho.
Tôi đã kết thúc bằng cách sử dụng jQuery để xóa các trường ẩn ở phía máy khách:
<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>