为什么 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
迭代集合,则模型绑定不起作用,因此使用 for
和 m.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
}
我有两个模型类;技能和技能等级。每个技能可以有很多技能级别:-
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
迭代集合,则模型绑定不起作用,因此使用 for
和 m.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
}