【问题标题】:ASP.NET MVC cannot POST view model with binding to checkboxASP.NET MVC 无法发布绑定到复选框的视图模型
【发布时间】:2015-12-22 00:36:15
【问题描述】:

这是我的视图模型:

public class UserViewModel
{
    public User GroupUser { get; set; }
    public bool Checked { get; set; }
}

public class GroupUserViewModel
{
    public Guid GroupId { get; set; }
    public string GroupName { get; set; }
    public IList<UserViewModel> Users;        
}

我的看法:

@model GroupUserViewModel

@{
    ViewBag.Title = "Users";
    Layout = "~/Views/Shared/_Layout.cshtml";
}

<h2>@Model.GroupName</h2>

@using (Html.BeginForm("AddUserToGroup", "Group", FormMethod.Post))
{
    for (var userIter = 0; userIter < Model.Users.Count(); userIter++)
    {
        <div class="form-group">
            @Html.DisplayFor(model => model.Users[userIter].GroupUser.UserName)
            @Html.CheckBoxFor(model => model.Users[userIter].Checked)

            @Html.HiddenFor(model => model.GroupId)
            @Html.HiddenFor(model => model.GroupName)
        </div>        
    }

    <input type="submit" class="btn btn-success" value="Save"/>
}

我的控制器:

[HttpPost]
public ActionResult AddUserToGroup(GroupUserViewModel groupUsers)
{
    //do things    
}

我检查了 POST 数据,结果是:

Users[0].Checked=true
Users[0].Checked=false
Users[1].Checked=false

对于我勾选的框,有 2 个条目,一个 true 和一个 false。这正常吗?

同样在控制器中,我得到的是:

groupUsers.GroupId = {00000000-0000-0000-0000-000000000000}
groupUsers.GroupName = null
groupUsers.Users = null

显然,由于表单实际上并未将我想要的视图模型发布回控制器,因此会发生这种情况。由于我需要GroupIdGroupName,有什么方法可以将所需的视图模型传递回控制器?

编辑:

经过一些更新并添加了GroupIdGroupName 的隐藏字段,现在POST 数据为:

Users[0].Checked=true
Users[0].Checked=false
Id=015f5aef-eb6c-449e-9f08-9d42110c5347
GroupName=MyName
MyObjects[1].Checked=false
Id=015f5aef-eb6c-449e-9f08-9d42110c5347
GroupName=MyName

GroupIdGroupName 现在正在正确传递,但列表仍然是 null

【问题讨论】:

  • 是的,这很正常。如果您检查 html,您将看到带有 value="true" 的复选框和带有 value="false" 的关联隐藏输入。这可以确保发布一个值,因为未选中的复选框不会回发一个值。 DefaultModelBinder 将绑定第一个并忽略同名的第二个。
  • 您显示的视图代码不包括IdName 的表单控件,因此它们将是默认值。该集合将根据您显示的代码绑定(应该是@Html.CheckBoxFor(m=&gt; m.MyObjects[i].Selected),但假设这是一个错字)
  • @StephenMuecke 感谢您提供信息。好的,IdName 现在正在通过,但对象列表仍然为空。
  • 应该是。你确定那是真正的代码吗?
  • public IList&lt;UserViewModel&gt; Users; 是一个字段,而不是一个属性,因此 DefaultModelBinder 不能设置该值 - 添加 { get; set; }

标签: c# asp.net-mvc checkbox viewmodel model-binding


【解决方案1】:

GroupUserViewModel 中的IList&lt;UserViewModel&gt; Users 是字段,而不是属性,因此DefaultModelBinder 无法设置其值。改成

public class GroupUserViewModel
{
    ....
    public IList<UserViewModel> Users { get; set; } // make it a property   
}

【讨论】:

    【解决方案2】:

    是的,这很正常。原因是因为未选中的复选框不会发布值,因此 ASP.NET 为每个复选框呈现一个隐藏字段,该字段与复选​​框控件之后的复选框具有相同的 ID,并将其值设置为 false。如果有多个同名的表单字段,ASP.NET DefaultModelBinder 将采用第一个值。如果未选中复选框,这将导致从隐藏字段发布一个 false 值,以及两个值,一个 false 用于隐藏字段,一个 true 用于选中复选框。因为隐藏字段位于复选框之后,如果复选框发布值,它将覆盖隐藏字段。 但是,这并不能回答您关于模型为什么不具有约束力的问题..

    【讨论】:

    • 可能你没有回答他的问题。评论(如斯蒂芬的)会更好。
    • +1 for ASP.NET DefaultModelBinder 将,如果有多个同名的表单字段,取第一个值
    猜你喜欢
    • 2018-11-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-02
    • 2018-12-10
    • 1970-01-01
    • 1970-01-01
    • 2013-03-06
    相关资源
    最近更新 更多