我正在构建一个简单的ASP.NET MVC 5.2.3.0视图,该视图显示用户名和角色的复选框列表。您可以选中或取消选中复选框来控制用户所在的角色。这是我的ViewModel:
public class EditUserVM
{
public string Id { get; set; }
public string UserName { get; set; }
public List<UserRoleVM> Roles { get; set; }
}
public class UserRoleVM
{
public string RoleId { get; set; }
public string RoleName { get; set; }
public bool IsMember { get; set; }
}
它显示如下:
@model VMContainer<EditUserVM>
@* omitted for exmaple *@
var userVM = Model.ViewModel;
<div class="panel panel-primary">
<div class="panel-heading"><h4 style="display:inline">User: @userVM.UserName</h4></div>
<div class="panel-body">
@Html.ValidationSummary(false, "", new { @class = "text-danger" })
<h4>Users Roles</h4>
@using (Html.BeginForm())
{
@Html.AntiForgeryToken()
<div class="form-horizontal">
@Html.HiddenFor(m => userVM.Id)
@Html.HiddenFor(m => userVM.UserName)
<table class="table table-bordered table-striped">
<thead><tr><th></th><th>Role</th></tr></thead>
<tbody>
@for (int x = 0; x<userVM.Roles.Count; x++){
<tr>
<td>
@Html.HiddenFor(m => userVM.Roles[x].RoleId)
@Html.CheckBoxFor(m => userVM.Roles[x].IsMember)
</td>
<td>@Html.DisplayFor(m => userVM.Roles[x].RoleName)</td>
</tr>
}
</tbody>
</table>
<div>
<input type="submit" value="Save" class="btn btn-success" />
@Html.ActionLink("Cancel", "Users", null, new { @class = "btn btn-default" })
</div>
</div>
}
请注意,模型类型是VMContainer。这是我的视图使用的包装器,以便在生成内部T ViewModel时出错,它可以显示错误而不是普通视图内容。为了更容易访问EditUserVM,因为这是我需要提交的所有内容,而不是VMContainer包装器,我将其分配给本地变量var userVM = Model.ViewModel;
。我在之前的项目中经常使用这种模式。问题是当我在开发人员工具中检查页面时,我的所有输入都被命名为错误。它们都获得了生成类的前缀。例如,@Html.HiddenFor(m => userVM.Id)
呈现:
通过反复试验,如果删除for
循环,我将其缩小到不会发生。这是在for
循环注释掉的情况下,其余输入被正确命名。通过进一步的试验和错误,我发现真正触发它的是使用变量访问Roles索引器。例如。如果我删除循环并执行此操作,则会为所有输入生成错误的名称:
@Html.HiddenFor(m => userVM.Id)
@Html.HiddenFor(m => userVM.UserName)
@{ int x = 0; }
@Html.HiddenFor(m => userVM.Roles[x].RoleId);
如果我使用常量[0]
代替[x]
或 m.ViewModel.Roles[x]
而不是userVM.Roles[x]
,则不会生成错误的名称。因此,为了尝试完全拼写它,当使用索引参数的变量访问局部变量的后代的索引器时,似乎会发生这种情况。
我发现MVC 6(当时)已经发现了类似的东西,但我不明白这个问题。如果它实际上是一个bug,我仍然有点惊讶。虽然很难描述,但似乎并不是一个完全不常见的场景。有人可以解释发生了什么,并希望提供修复?我更喜欢在表单提交时仅将EditUserVM发布到我的操作。
答案 0 :(得分:0)
@for (int x = 0; x<userVM.Roles.Count; x++){
一种解决方法可能是在页面顶部声明变量x。