2015-09-05 78 views
4

乍一看,这篇文章可能看起来像重复,但事实并非如此。相信我,我已经看遍了堆栈溢出无济于事。MVC 5复选框返回“False,false”或“false”

无论如何,我从Html.CheckBoxFor得到一些奇怪的行为。

我有这个下面定义的属性视图模型

[Display(Name = "User is active")] 
public bool IsActive { get; set; } 

它在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> 

认为

if (userInfo.isActive != null) 
{ 
    //Cast to bool because userInfo.isActive is Nullable<bool> 
    model.IsActive = (bool)userInfo.isActive; 
} 

ModelState.Clear(); 

return View(model); 

然后才初始化并返回到控制器

[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的值会返回作为虚假的,一切都是疯狂的。

当model.IsActive被初始化为false时,会发生该问题。我阅读了很多堆栈溢出帖子,解释如果复选框未被选中,则返回“false”,并且如果它被选中“true,false”被返回,但那不是我得到的行为。当复选框被初始化为false并且在视图中检查时,model.IsActive的值仍然会返回false,并且当我检查表单元素的值(请参阅控制器后期中的“var tmp”)时,它是“false,false” 。 “真,假”是预期的价值,不是吗?只有在试图将模型值从false更改为true时才会发生这种情况,不存在从true到false的问题。

So Stack Overflow,发生了什么?!

+1

只需从@ Html.CheckBoxFor帮手中删除'@value = Model.IsActive'并且它将正常工作 –

+0

对不起,我应该指定,我也尝试过不传入@值,没有什么区别。我正在考虑创建一个标准的HTML复选框,并将该值作为单独的参数传递。 – Francis

+0

亚历克斯是正确的,从CheckBoxFor中删除htmlAttributes。在他们内部设置@value正在搞乱CheckBoxFor已经提供给您的绑定,lambda'model => model.IsActive'。 – NigelK

回答

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输入的值属性仍然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); 
     } 
+0

你是正确的,但问题是,当复选框创建初始值为假(model.IsActive传入为false),我检查复选框将值更改为true它仍然在邮件中回传为假。复选框的值不会更改。 – Francis

+0

您以及更多评论者都是正确的,如果您好奇,我会在最后一篇文章中将我的问题的具体原因作为评论加以解释。我已经接受你的帖子作为正确答案。 – Francis