asp.net - Asp.Net MVC 3 应用程序中复杂子对象的集合?

标签 asp.net entity-framework collections asp.net-mvc-3 entity

我希望能够在同一 View 中更新模型及其所有子对象集合。我已经引用过这些例子:http://haacked.com/archive/2008/10/23/model-binding-to-a-list.aspxhttp://blog.stevensanderson.com/2010/01/28/editing-a-variable-length-list-aspnet-mvc-2-style/ .

例如,我有一个对象顾问,它有一个“工作经验”的集合。所有这些都在 Entity Framework 模型中。在 View 中,Consultant 对象的简单属性没有问题,但我无法获取要显示的文本框的集合。我尝试按照上面链接中的示例进行操作,但它不起作用。问题是,在这些示例中,模型只是一个列表(而不是具有子列表属性的对象)。而且,该模型又是 EF 模型。由于某种原因,这似乎并不像这些示例中那样起作用。

为了简单起见,我尝试按照 Phil Haacks 示例做一些事情,然后让 View 显示文本框:

@for (int i = 0; i < Model.WorkExperiences.Count; i++)
{
    Html.TextBoxFor(m => m.WorkExperiences[i].Name);
}

我尝试在 ViewModel 的 Controller 中创建一个新的 WorkExperience 对象:

    public ActionResult Create(int id)
    {
        Consultant consultant = _repository.GetConsultant(id);
        DetailsViewModel vm = new DetailsViewModel();
        vm.WorkExperiences = consultant.WorkExperiences.ToList();
        vm.WorkExperiences.Add(new WorkExperience());           
        return View(vm);
    }

但是 View 不显示 WorkExperience Name 属性的任何空文本框。另一方面,如果我创建一个单独的 View 只是为了添加一个新的 WorkExperience 对象,传递一个新的空 WorkExperience 对象作为模型,那么效果很好:

@Html.EditorFor(model => model.Name)

这给了我一个空文本框,我可以保存新对象。但是为什么我不能在与 Consultant 对象相同的 View 中执行此操作,并根据上面链接中的示例进行集合?

顺便说一句,这是前一个问题的后续问题,它向我指出了上面的链接,但我从未找到最终的解决方案。如果需要更多信息,请参阅该问题:Create Views for object properties in model in MVC 3 application?

更新:

根据下面的答案和评论,这是 View 和 EditorTemplate 的更新:

View :

@model Consultants.ViewModels.DetailsViewModel

@{
    ViewBag.Title = "Index";
}

<h2>Index</h2>

<p>
    @Html.ActionLink("Add work experience", "CreateWorkExperience", new { id = ViewBag.Consultant.Id })
</p>
<table>
    <tr>
        <th></th>
        <th>
            Name
        </th>

    </tr>

@foreach (var item in Model.WorkExperiences) {
    <tr>
        <td>
            @Html.ActionLink("Edit", "Edit", new { id = item.Id }) |
            @Html.ActionLink("Details", "Details", new { id = item.Id }) |
            @Html.ActionLink("Delete", "Delete", new { id = item.Id })
        </td>
        <td>
            @item.Name
        </td>

    </tr>

}

</table>

@for (int i = 0; i < Model. WorkExperiences.Count; i++)
{
    Html.EditorFor(m => m. WorkExperiences[i]);
}

(请注意,这一切并不是我最终的设计方式,我现在要做的就是让 WorkExperience 对象显示为一个空文本框来填写,并且能够添加和删​​除此类文本框,如 Phil Haack 和 Steven Sanderson 的示例中所示。)

编辑器模板:

@model Consultants.Models.WorkExperience


@Html.TextBoxFor(m => m.Name);

这个带有 EditorTemplate 的东西在 Phil Haack 的示例项目中工作得很好,我下载了这个示例项目来尝试,但是在这里,对于 EF 模型或任何问题,我根本没有得到任何文本框。 View 中的表只是作为测试,因为在表中我确实获取了 WorkExperiences 的行,无论我添加空的 WorkExperience 对象还是填写其属性并不重要,每个对象都会显示行。但同样,没有文本框...

最佳答案

For example, I have an object Consultant, that has a collection of "WorkExperiences". All this is in an Entity Framework model.

这是您应该改进的第一件事:引入 View 模型,并且不要在 View 中使用域模型。

话虽如此,让我们继续讨论模板。因此您可以完全消除在 View 中编写循环的需要。

您的 View 可能如下所示:

@model Consultants.ViewModels.DetailsViewModel

@{
    ViewBag.Title = "Index";
}

<h2>Index</h2>

<p>
    @Html.ActionLink("Add work experience", "CreateWorkExperience", new { id = ViewBag.Consultant.Id })
</p>
<table>
    <tr>
        <th></th>
        <th>
            Name
        </th>
    </tr>
    @Html.DisplayFor(x => x.WorkExperiences)
</table>

@Html.EditorFor(x.WorkExperiences)

因此,我们正在使用显示模板和编辑器模板。现在让我们定义它们。

显示模板 (~/Views/Shared/DisplayTemplates/WorkExperience.cshtml):

@model AppName.Models.WorkExperience
<tr>
    <td>
        @Html.ActionLink("Edit", "Edit", new { id = Model.Id }) |
        @Html.ActionLink("Details", "Details", new { id = Model.Id }) |
        @Html.ActionLink("Delete", "Delete", new { id = Model.Id })
    </td>
    <td>
        @Model.Name
    </td>
</tr>

编辑器模板(~/Views/Shared/EditorTemplates/WorkExperience.cshtml):

@model AppName.Models.WorkExperience
@Html.TextBoxFor(x => x.SomePropertyOfTheWorkExperienceModelYouWantToEdit)
...

这里重要的是命名约定。模板的名称应该是集合中项目的类型名称。例如,如果在您的 View 模型中您有一个属性

public IEnumerable<Foo> { get; set; }

相应的模板应名为Foo.cshtml,并且应位于~/Views/Shared/DisplayTemplates~/Views/Shared/EditorTemplates 取决于其角色。

如您所见,我们已经摆脱了令人讨厌的循环。现在,不仅 View 看起来干净,而且您还获得了输入字段的正确名称,以便您可以将值绑定(bind)回后操作中。

关于asp.net - Asp.Net MVC 3 应用程序中复杂子对象的集合?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5060817/

相关文章:

.net - Memcached 是否可以与 ASP.NET 状态服务器互换?

c# - 使用 Parameters.AddWithValue 将两个 gridviews 中的值插入到一个 sql 列中

asp.net - 在本地主机上的 Web 应用程序之间阻止来自 "spilling"的表单例份验证

c# - 使用 EF Core 编写动态 LINQ 查询以进行排序和投影

entity-framework - Entity Framework 5 复杂类型

java - 如何通过构造初始化HashSet值?

javascript - 提交至 Eloqua 表单,无需 Eloqua 处理页面

c# - 与连接(桥接)表的一对多关系

performance - 为什么 Seq 模块中的某些功能得到了优化,而其他功能却没有在 F# 中进行优化?

javascript - BackboneJS 在集合中重新排列模型同时为每个模型维护 0 索引序数属性的最佳方法