【问题标题】:MVC 5 Checkbox returns “False,false” or “false”MVC 5 复选框返回“假,假”或“假”
【发布时间】:2015-12-01 15:53:07
【问题描述】:

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

【问题讨论】:

  • 只需从 @Html.CheckBoxFor 助手中删除 @value = Model.IsActive 即可正常工作
  • 对不起,我应该指定的,我也试过不传入@value,没有任何区别。我正在考虑创建一个标准的 HTML 复选框,然后将值作为单独的参数传递。
  • Alex 是对的,从 CheckBoxFor 中删除 htmlAttributes。在它们中设置 @value 会破坏 CheckBoxFor 已经提供的绑定,因为你给它提供了 lambda 'model => model.IsActive'。
  • 仅供参考,我完全按照您的描述重新创建了您的问题,然后通过删除属性来修复它。所以我理解你的沮丧,这表明这里可能还有其他事情发生。您是否在视图中的其他任何地方引用了 model.IsActive?
  • 好吧,我觉得非常愚蠢,model.IsActive 在这段代码的页面底部被引用了 我把它放在那里是因为复选框之前没有正确呈现原始值(可能是因为 HtmlAttributes),但是 JS 覆盖了复选框的值。现在工作正常...

标签: c# asp.net-mvc checkbox


【解决方案1】:

您无需更改复选框的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);
        }

【讨论】:

  • 你是对的,但问题是当复选框被创建时初始值为 false(model.IsActive 作为 false 传入)并且我选中复选框以将值更改为 true仍然在帖子中作为假传回。复选框的值没有改变。
  • 您以及进一步的评论者是正确的,如果您好奇,我在上一篇文章中解释了我的问题的具体原因作为评论。我已接受您的帖子作为正确答案。
猜你喜欢
  • 2023-03-03
  • 2014-09-07
  • 1970-01-01
  • 1970-01-01
  • 2014-02-03
  • 2014-05-10
  • 2016-09-01
  • 2017-10-14
  • 1970-01-01
相关资源
最近更新 更多