我正在构建一个简单的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
循环中注释的,其余的输入是正确命名的。通过进一步的反复试验,我发现它真正触发了它使用变量访问角色索引器的原因。例如。如果我删除循环并执行此操作,它将为所有输入产生错误的名称:
@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]
,则不会生成错误的名称。因此,要尝试将其完全拼写出来,当使用索引参数变量访问本地变量后代的索引时,它似乎会发生。
我在当时(当时)发现了这一点或类似的东西,但我不明白问题。如果实际上是一个错误,我仍然有些惊讶。尽管很难描述,但这似乎并不是一个罕见的情况。有人可以解释发生了什么并希望提供解决方案吗?表格提交时,我只想将EdituServM发布到我的操作中。
@for (int x = 0; x<userVM.Roles.Count; x++){
可以在页面顶部声明变量x的解决方法。
来源:https://github.com/aspnet/mvc/issues/2890