乍一看这篇文章可能看似重复,但事实并非如此。相信我,我看了遍布Stack Overflow无济于事。
无论如何,我从Html.CheckBoxFor获得了一些奇怪的行为。
我有一个具有以下定义属性的视图模型
[Display(Name = "User is active")]
public bool IsActive { get; set; }
它在视图之前初始化
if (userInfo.isActive != null)
{
//Cast to bool because userInfo.isActive is Nullable<bool>
model.IsActive = (bool)userInfo.isActive;
}
ModelState.Clear();
return View(model);
然后在Html.BeginForm中呈现为
<div class="form-group">
@Html.LabelFor(model => model.IsActive, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.CheckBoxFor(model => model.IsActive, htmlAttributes: new { @value = Model.IsActive /*Also tried @checked = Model.IsActive*/ })
@Html.ValidationMessageFor(model => model.IsActive)
</div>
</div>
并返回控制器
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult EditProfile(EditProfileViewModel model, string Roles, HttpPostedFileBase ProfileImage)
{
//There's a lot more up here, but it's not relevant to the problem
userInfo.isActive = model.IsActive;
var tmp = Request.Form["IsActive"]; //Added just to check the form value
try
{
db.Entry(userInfo).State = EntityState.Modified;
//Assign changed data to userInfo
db.SaveChanges();
}
}
当model.IsActive初始化为true且我没有取消选中复选框时,控制器帖子中model.IsActive的值为true,或者如果取消选中该复选框,则model.IsActive的值将返回false而且一切都很笨拙。
当model.IsActive初始化为false时,会出现问题。我阅读了很多Stack Overflow帖子,解释如果未选中该复选框,则返回“false”,如果选中,则返回“true,false”,但这不是我得到的行为。当复选框初始化为false并且我在视图中检查它时,model.IsActive的值仍然返回false,当我检查表单元素的值时(参见控制器帖子中的“var tmp”),它是“false,false” 。 “真,假”是预期值,不是吗?只有在尝试将模型值从false更改为true时才会发生这种情况,没有问题从true变为false。
所以Stack Overflow,到底发生了什么?!
答案 0 :(得分:2)
您无需更改复选框的value
属性。如果你使用没有它的助手,你会看到
@Html.CheckBoxFor(model => model.IsActive)
呈现为
<input data-val="true" data-val-required="The IsActive field is required." id="IsActive" name="IsActive" type="checkbox" value="true" class="valid">
您可以看到虽然Model.IsActive
设置为false,但输入的value属性仍为true
顺便说一下,如果你看一下CheckBox助手的源代码,你会看到value=true
在那里被硬编码(所以你不应该改变它):
private static MvcHtmlString CheckBoxHelper(HtmlHelper htmlHelper, ModelMetadata metadata, string name, bool? isChecked, IDictionary<string, object> htmlAttributes)
{
RouteValueDictionary attributes = ToRouteValueDictionary(htmlAttributes);
bool explicitValue = isChecked.HasValue;
if (explicitValue)
{
attributes.Remove("checked"); // Explicit value must override dictionary
}
return InputHelper(htmlHelper,
InputType.CheckBox,
metadata,
name,
value: "true",
useViewData: !explicitValue,
isChecked: isChecked ?? false,
setId: true,
isExplicitValue: false,
format: null,
htmlAttributes: attributes);
}