1

我有两节课:

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;}
}

我对创建一个练习对象也有我的看法。该视图上有一个名为“添加锻炼项目”的按钮,我在其中动态调用 ajax 方法以返回锻炼项目对象的部分视图。正确返回视图。这种观点如下:

@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>

问题是当我提交表单并调用我的“创建”方法时:

[HttpPost]
public ActionResult Create(Exercise exercise)
{
    //add exercise to db
    //HOWEVER!!
    //exercise.Items is empty
}

我的项目为空。我究竟做错了什么?有人可以给我一些建议,我应该怎么做才能解决这个问题?

4

1 回答 1

6

我真的不知道为什么这么多人坚持不使用辅助方法,并且想要自己完成所有表单字段。只要您正确使用它们,助手就会确保您的格式正确。

但是,您的真正问题是您的 ActionMethod 所需的运动模型与ExerciseItem您的 PartialView 使用的模型之间的阻抗不匹配。您将 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 放在局部视图中,并让局部视图采用练习模型。

简单地说,在渲染集合时,使用编辑器/显示模板。它将使您的生活变得如此轻松,并避免以模型绑定器期望的正确格式获取表单字段命名约定的麻烦。

我认为这里至少有 50% 的问题是关于“我的模型是空的!” 如果他们正确使用 EditorTemplates,就不会发生变化

于 2013-03-23T16:59:43.973 回答