Sadece bir Html.CheckBox("foo")
yerine 2 giriş oluşturduğunu fark ettim , herkes bunun neden böyle olduğunu biliyor mu?
<input id="foo" name="foo" type="checkbox" value="true" />
<input name="foo" type="hidden" value="false" />
Sadece bir Html.CheckBox("foo")
yerine 2 giriş oluşturduğunu fark ettim , herkes bunun neden böyle olduğunu biliyor mu?
<input id="foo" name="foo" type="checkbox" value="true" />
<input name="foo" type="hidden" value="false" />
Yanıtlar:
Onay kutusu seçilmezse form alanı gönderilmez. Bu yüzden gizli alanda her zaman yanlış değer vardır. Onay kutusunu işaretlemezseniz formun gizli alandan değeri yine de olur. ASP.NET MVC onay kutusu değerlerini bu şekilde işler.
Bunu onaylamak istiyorsanız, Html.Hidden ile değil, ile forma bir onay kutusu yerleştirin <input type="checkbox" name="MyTestCheckboxValue"></input>
. Onay kutusunu işaretlemeyin, formu gönderin ve sunucu tarafında yayınlanan istek değerlerine bakın. Onay kutusu değeri olmadığını göreceksiniz. Gizli alanınız olsaydı MyTestCheckboxValue
, false
değer içeren bir girdi içerirdi.
IsActive
başlatılan bir özelliğe sahip olduğunu varsayalım true
. Kullanıcı onay kutusunun seçimini kaldırır, ancak değer sunucuya gönderilmediğinden, model bağlayıcı onu almaz ve özellik değeri değişmez. Model bağlayıcı, değer gönderilmezse yanlış olarak ayarlandığını varsaymamalıdır, çünkü bu değeri göndermemeye karar verebilirsiniz.
false
bile değer gönderirler ve bu kafa karıştırıcıdır. ASP.NET varsayılan HTTP davranışı ile uyumlu olmak istiyorsa, devre dışı bırakılmış onay kutuları hiçbir değer göndermemelidir.
Gizli girdinin eklenmesini önlemek için bir yardımcı yazabilirsiniz:
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);
}
}
kullanın:
@Html.CheckBoxSimple("foo", new {value = bar.Id})
@using Your.Name.Space
.cshtml tıraş bıçağı görünüm dosyanızın üstüne eklemeyi unutmayın .
System.Web.Mvc.Html
tüm görünümlerde erişilebilir olması için ad alanına koyun
Manuel yaklaşım şudur:
bool IsDefault = (Request.Form["IsDefault"] != "false");
Bu, Alexander Trofimov'un çözümünün güçlü bir şekilde yazılmış versiyonudur:
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);
}
}
Gizli girdi, stil onay kutuları ile sorunlara neden oluyordu. Bu yüzden gizli girişi CheckBox içeren div dışında yerleştirmek için bir Html Yardımcı Uzantısı oluşturdum.
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());
}
Sonuç
<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">
Modelinizin yapıcısını şu şekilde başlatmayı deneyebilirsiniz:
public MemberFormModel() {
foo = true;
}
ve sizin görüşünüze göre:
@html.Checkbox(...)
@html.Hidden(...)
Bir WebGrid vardı bu gerçekten sorunlara neden bulundu. WebGrid'deki sıralama bağlantıları iki kat yukarı sorgu dizesi veya x = true & x = false değerinin x = true, false değerine döneceğini ve onay kutusunda ayrıştırma hatasına neden olacağını belirtiyor.
İstemci tarafında gizli alanları silmek için jQuery kullanarak sona erdi:
<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>