为什么 Razor 视图在访问分配给局部变量的模型的索引器时"CS$<>8__locals1"输入名称添加前缀?



我正在构建一个简单的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

最新更新