Saya hanya memperhatikan bahwa Html.CheckBox("foo")menghasilkan 2 input, bukan satu, ada yang tahu mengapa demikian?
<input id="foo" name="foo" type="checkbox" value="true" />
<input name="foo" type="hidden" value="false" />
Saya hanya memperhatikan bahwa Html.CheckBox("foo")menghasilkan 2 input, bukan satu, ada yang tahu mengapa demikian?
<input id="foo" name="foo" type="checkbox" value="true" />
<input name="foo" type="hidden" value="false" />
Jawaban:
Jika kotak centang tidak dipilih, bidang formulir tidak dikirimkan. Itulah sebabnya selalu ada nilai salah di bidang tersembunyi. Jika Anda meninggalkan kotak centang tidak dicentang, formulir akan tetap memiliki nilai dari bidang tersembunyi. Begitulah cara ASP.NET MVC menangani nilai kotak centang.
Jika Anda ingin mengonfirmasi hal itu, letakkan kotak centang pada formulir bukan dengan Html. Tersembunyi, tetapi dengan <input type="checkbox" name="MyTestCheckboxValue"></input>. Biarkan kotak centang tidak dicentang, kirim formulir dan lihat nilai permintaan yang diposting di sisi server. Anda akan melihat bahwa tidak ada nilai kotak centang. Jika Anda memiliki bidang tersembunyi, ini akan berisi MyTestCheckboxValueentri dengan falsenilai.
IsActive, yang diinisiasi truedalam konstruktor. Pengguna membatalkan centang, tetapi karena nilai tidak dikirim ke server, pengikat model tidak mengambilnya, dan nilai properti tidak berubah. Pengikat model tidak boleh berasumsi, bahwa jika nilai tidak dikirim, itu disetel ke false, karena itu bisa jadi keputusan Anda untuk tidak mengirim nilai ini.
falsenilai bahkan jika mereka diperiksa, dan itu membingungkan. Kotak centang yang dinonaktifkan tidak boleh mengirim nilai apa pun, jika ASP.NET ingin kompatibel dengan perilaku HTTP default.
Anda dapat menulis helper untuk mencegah penambahan input tersembunyi:
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);
}
}
Gunakan:
@Html.CheckBoxSimple("foo", new {value = bar.Id})
@using Your.Name.Spacedi bagian atas file .cshtml razor view Anda.
System.Web.Mvc.Htmlagar dapat diakses di semua tampilan
Pendekatan manual adalah ini:
bool IsDefault = (Request.Form["IsDefault"] != "false");
Ini adalah versi yang sangat diketik dari solusi 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);
}
}
Input tersembunyi menyebabkan masalah dengan kotak centang gaya. Jadi saya membuat Ekstensi Helper Html untuk menempatkan input tersembunyi di luar div yang berisi Kotak Centang.
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());
}
Hasil
<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">
Anda dapat mencoba menginisialisasi konstruktor Model Anda seperti itu:
public MemberFormModel() {
foo = true;
}
dan menurut Anda:
@html.Checkbox(...)
@html.Hidden(...)
Saya menemukan ini benar-benar menyebabkan masalah ketika saya memiliki WebGrid. Tautan pengurutan pada WebGrid akan berubah oleh querystring yang digandakan atau x = true & x = false ke x = true, false dan menyebabkan kesalahan parse pada kotak centang untuk.
Saya akhirnya menggunakan jQuery untuk menghapus bidang tersembunyi di sisi klien:
<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>