我有两个班级:
public class Exercise
{
public Guid Id {get;set;}
public string Name {get;set;}
public List<ExerciseItem> Items {get;set;}
}
public class ExerciseItem
{
public Guid Id {get;set;}
public string Name {get;set;}
public string Content {get;set;}
}
我也有创建一个Exercise对象的观点。该视图上有一个名为“添加练习项”的按钮,其中我动态调用ajax方法返回ExerciseItem对象的局部视图。视图正确返回。该观点如下:
@model Elang.Models.ExerciseItem
<div>
<input type="hidden" name="Items.Index" value="@Model.Id" />
<input type="hidden" id="Items@(Model.Id)__Id" name="Items[@Model.Id].Id" value="@Model.Id" />
<input type="text" id="Items@(Model.Id)__Content" name="Items[@Model.Id].Content" class="inputText"/>
</div>
问题在于,当我提交表单并调用我的“Create”方法时:
[HttpPost]
public ActionResult Create(Exercise exercise)
{
//add exercise to db
//HOWEVER!!
//exercise.Items is empty
}
我的项目为空。我究竟做错了什么?有人可以给我一些建议,我该怎么办才能解决这个问题?
答案 0 :(得分:6)
我真的不确定为什么这么多人坚持不使用辅助方法,并希望自己完成所有表单字段。帮助者将确保您的格式正确,只要您正确使用它们。
但是,这里的真正问题是ActionMethod所需的练习模型与PartialView使用的ExerciseItem
模型之间的阻抗不匹配。您使用Partial作为EditorTemplate,这会导致问题。
相反,使用EditorTemplate,并使用辅助方法,一切都会正常运行。
在视图路径(本地文件夹或共享视图)中创建名为EditorTemplates的文件夹,并添加名为ExerciseItem.cshtml
的文件。在该文件中,使用以下代码:
@model Elang.Models.ExerciseItem
<div>
@Html.Hidden(m => m.Id)
@Html.TextBoxFor(m => m.Content)
</div>
然后,在父视图中,只需使用以下内容,它将自动遍历所有集合并生成正确命名的字段:
@Html.EditorFor(m => m.Items)
如果你仍然想使用Ajax来检索项目,那么将EditorFor放在局部视图中,让部分视图采用练习模型。
简单地说,在渲染集合时,使用USE编辑器/显示模板。它将使您的生活变得更加轻松,并防止以正确的格式使模板字段命名约定令人头疼。
我认为至少有50%的问题出现在“我的模型”的SO上!如果他们正确使用EditorTemplates,就不会发生变化