为什么 Html.TextBox 带有数组索引前缀,无法读取构造为集合的模型数据

Why Html.TextBox with array index prefixes , can not read model data that are constructed as a Collection

我有两个模型类;技能和技能等级。每个技能可以有很多技能级别:-

public partial class Skill
    {
        public Skill()
        {
            this.SkillLevels = new HashSet<SkillLevel>();
            this.SkillLevelStaffs = new HashSet<SkillLevelStaff>();
            this.SkillVersionHistories = new HashSet<SkillVersionHistory>();
            this.Customers = new HashSet<Customer>();
            this.LinkToKBs = new HashSet<LinkToKB>();
        }

        public int SkillID { get; set; }
        public string Name { get; set; }
        public bool IsAllCustomer { get; set; }
        public string Description { get; set; }
       //code goes here



        public virtual ICollection<SkillLevel> SkillLevels { get; set; }

    }

public partial class SkillLevel
    {
        public int SkillID { get; set; }
        public int LevelID { get; set; }
        public string Description { get; set; }
        public string TestProcess { get; set; }

        public virtual Level Level { get; set; }
        public virtual Skill Skill { get; set; }
    }

现在在 Skill create/Edit 视图中,我显示了四对 SkillLevel 字段

@for (var i = 0; i < 4; i++)
       {

<div class="form-group">
@Html.Label("SkillLevels[" + i.ToString() + "].TestProcess", new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.TextArea("SkillLevels[" + i.ToString() + "].TestProcess",new { @class = "form-control", rows=10}) 
</div>

@Html.Label("SkillLevels[" + i.ToString() + "].Description", new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.TextArea("SkillLevels[" + i.ToString() + "].Description") 
@Html.ValidationMessage("SkillLevels[" + i.ToString() + "].Description",new { @class = "form-control", rows=10})
</div></div>
string v = (i + 1).ToString();
@Html.Hidden("SkillLevels[" + i.ToString() + "].SkillID",Model.SkillID)
@Html.Hidden("SkillLevels[" + i.ToString() + "].LevelID", v)
       }

这在创建视图中运行良好,其中将显示四对 Textprocess + Description 并作为 collection<SkillLevels> 回发,但如果我在编辑视图中有相同的代码,那么当我访问编辑视图时,四对 SkillLevel 将始终为空,似乎带有索引数组的 TextBox 无法读取 Collection<SkillLevels>??所以在编辑视图中我必须定义一个 foreach 来完成这项工作:-

@{
int i=0;
}
@foreach(var s in Model.SkillLevels)
{
  <div>
    @Html.Editor("SkillLevels[" + i.ToString() + "].TestProcess", new { @Value = s.TestProcess }) 

但我正在尝试对“编辑”+“创建”使用相同的视图。任何人都可以建议吗?

你不应该使用魔法字符串。我按照以下方式做同样的事情:

@for (var i = 0; i < Model.SkillLevels.Length; i++)
{
    <div class="form-group">
    @Html.LabelFor(m => m.SkillLevels[i].TestProcess, new { @class = "control-label col-md-2" })
    <div class="col-md-10">
    @Html.TextAreaFor(m => m.SkillLevels[i].TestProcess, new { @class = "form-control", rows=10}) 
    </div>
    ...
}

如果是新项目,您需要 "prefill" 包含 4 个空项目的集合...

如果您使用 foreach 迭代集合,则模型绑定不起作用,因此使用 form.SkillLevels[i]

如果您可以使用 for each 循环对 SkillLevels 集合进行迭代并希望使用相同的视图来继续创建 - 我的第一个想法是简单地将四个空元素添加到操作中的集合returns 创建视图模型的方法。

为此,您应该在模型中提供可为 null 的变量

public partial class SkillLevel
    {
        public int? SkillID { get; set; }
        public int? LevelID { get; set; }
        public string Description { get; set; }
        public string TestProcess { get; set; }

        public virtual Level Level { get; set; }
        public virtual Skill Skill { get; set; }
    }

最后两个我觉得无所谓。

然后在您的控制器中,它应该看起来或多或少像这样:

public ActionResult Create()
{
   var model = new SomeModel();
   model.SkillLevels = new List<SkillLevel>(4);
   for(int i=0;i<4;i++)
   {
      model.SkillLevels.Add(new SkillLevel());
   }
   return View("~/sth/Edit", model); //here should be path to your view
}