MVC 5复选框返回“False,false”或“false”

时间:2015-09-05 17:27:17

标签: c# asp.net-mvc checkbox

乍一看这篇文章可能看似重复,但事实并非如此。相信我,我看了遍布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,到底发生了什么?!

1 个答案:

答案 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);
        }