【问题标题】:ASP.NET MVC: Model binding half an objectASP.NET MVC:模型绑定半个对象
【发布时间】:2013-04-02 13:05:33
【问题描述】:

我有一个表单来添加一个带有几个用户角色复选框的新用户。我的操作中有一个名为 User 的模型,它具有以下属性:

public string Username { get; set; }
public string Password { get; set; }
public IEnumerable<UserRole> Roles { get; set; }

在 UserRole 类中我有两个属性:

public int Id { get; set; }
public string Name { get; set; }

在我的表单中,我可以通过输入名称“用户名”和“密码”成功地绑定到用户名和密码。当页面最初加载时,用户角色详细信息已加载,因此我只需要传入 Id,因为这是服务将用户与用户角色相关联所需的内容。

我认为我可以通过为每个复选框提供角色 ID 的值并将其传递给 Roles 来完成此操作,从而部分完成角色类并将角色对象的 Name 字段留空。一个示例复选框如下所示:

<input type="checkbox" id="addUserAdministrator" name="Roles.Id" value="@Model.Roles.Where(role => role.Name == "Administrator").Select(role => role.Id).First()" class="css-checkbox"/>

但是,这永远不会填充 Roles 集合,并且它始终为 null。有没有办法做到这一点,或者我需要做冗长的方式来传递整数列表并在动作中创建模型?

编辑:

我的动作是这样的:

public RedirectToRouteResult Add(User user)

【问题讨论】:

  • 您是否使用表单集合从复选框中检索值
  • 我已经更新了我的问题,我正在尝试绑定到那个对象
  • 该操作需要一个用户对象,但您似乎在传递一个角色,您可以发布整个表单代码吗?
  • 正如我在帖子中所说,其他表单项称为用户名和密码,它们直接绑定到用户对象上的这些属性。 Roles.Id 是有意义的,因为 Id 是 UserRole 类的属性

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


【解决方案1】:

您可以绑定原始类型的集合 - 在您的情况下为 int

 public IList<Int> Roles { get; set; } //role id's here

使用

<input type="checkbox" id="addUserAdministrator" name="Roles"

或者如果你想要角色集合,你应该明确地为你的集合指定一个索引。阅读this article。最好使用非顺序索引(例如使用 Guid.NewGuid()),以防表单列表中的选定项目之间存在间隙。

<input type="hidden" name="Roles.Index" value="@(GuidIndexForThisRow)" />
<input type="checkbox" name="Roles[@(GuidIndexForThisRow)].Id" value="1" />

【讨论】:

  • 我尝试了您的第二个建议,但是当我选择 2 个或更多复选框并提交这些复选框时,问题就出现了,只有一个(第一个)绑定到对象
  • 您是否为每对隐藏\复选框使用不同的 guid?它应该成对相同,但成对之间是唯一的。
  • 我什至无法通过您使用隐藏/复选框对的 guid 的方式将其绑定到角色。如果我将 name 明确设置为 Roles[0].Id ,它将绑定,否则它始终为 null
  • 你能用我的第二个建议显示你得到的 html 标记吗?链接到 screenshot\file 等。它应该可以工作。您没有设置 Roles[0].Id、Roles[1].Id。但是 [name=Roles.Index,value=Guid1][name=Roles[Guid1].Id,value1] | [name=Roles.Index,value=Guid2][name=Roles[Guid2].Id,value2] 等等......
  • 我决定采纳你的第一个建议,谢谢你的帮助
【解决方案2】:

当我将 Collections 与 Razor 一起使用时,我会这样解决:我使用 for 块来创建一个新的复选框、文本框或任何你想用集合索引显示的东西,因为当你调用控制器方法时,模型根据索引绑定您的集合值。

试试这个: 1. 在您的角色 ViewModel 中创建一个布尔字段,以了解何时选择了角色。

@Html.TextBoxFor(model => model.Username)
@Html.PasswordBoxFor(model => model.Password, new { value = Model.Password })

<ul id="roles">
@for (int I = 0; I < Model.Roles.Count(); ++I)
{
    <li>
        @Html.HiddenFor(model => Model.Roles[I].ID)
        @Html.CheckBoxFor(model => Model.Roles[I].RoleSelected)
        @Model.Roles[I].Name
    </li>
}
</ul>

试试这样的。

【讨论】:

  • 我不确定这是否适合我,因为我有一个用于最初加载数据的模型和一个用于将数据传递给操作的不同模型,因为它们具有不同的信息
  • 这种方式将根据角色集合绑定您的视图。无论您在初始化中输入值或更改此值,该循环都会显示您当前的内容。
猜你喜欢
  • 1970-01-01
  • 2015-03-28
  • 2011-11-22
  • 1970-01-01
  • 2014-01-25
  • 2017-07-16
  • 2011-05-22
  • 2020-03-14
相关资源
最近更新 更多