我对使用 WPF/Silverlight 的 MVVM 相当满意,但这是我第一次尝试 MVC Web 应用程序……只是我的背景。
我创建了一个名为 TestSitesController 的控制器,它是从我的实体框架模型(生成读/写操作和视图的模板)中的“站点”模型类自动生成的。我唯一修改的是在 3 个地方,某些方法有一个默认参数 Guid id = null。我刚刚摆脱了“= null”,一切正常。这是我更改的示例
public ActionResult Delete(Guid id = null)
{
//....
}
这已更改为
public ActionResult Delete(Guid id)
{
//....
}
Site 模型没有什么特别的 SiteId、Abbreviation 和 DisplayName……试图让这个问题尽可能简单。好的,所以我运行该网站并转到 htpp://.../TestSites/ 并且一切正常。
我注意到我的所有视图(创建、删除、详细信息和编辑)都在使用 @model MVCWeb.MyEntities.Site,我现在完全可以使用它;但在 Index.cshtml 视图中,我注意到它使用的是
@model IEnumerable<MVCWeb.MyEntities.Site>
这适用于生成的模板,但我想使用“复合视图模型”,也许这是我试图混合我的 MVVM 知识的地方,但如果可能的话,我会坚持下去。在我看来,复合视图模型只是一个特定于由 1 个或多个实体模型以及 SelectedSiteId 等附加属性组成的视图的模型。
所以我创建了一个非常简单的 ViewModel,叫做 TestSitesViewModel
public class TestSitesViewModel
{
//Eventually this will be added to a base ViewModel to get rid
//of the ViewBag dependencies
[Display(Name = "Web Page Title")]
public string WebPageTitle;
public IEnumerable<MVCWeb.MyEntities.Site> Sites;
//Other Entities, IEnumberables, or properties go here
//Not important for this example
}
然后在我的控制器中,我添加了一个名为 IndexWithViewModel 的操作方法
public ActionResult IndexWithViewModel()
{
var vm = new TestSitesViewModel();
vm.WebPageTitle = "Sites With Composite View Model";
vm.Sites = db.Sites.ToList();
return View(vm);
}
然后,我制作了 Index.cshtml 的副本并将其命名为 IndexWithModel.cshtml 以匹配我的新 ActionResult 方法名称。我改变了顶行
@model IEnumerable<MVCWeb.MyEntities.Site>
至
@model MVCWeb.Models.TestSitesViewModel
我在表格部分之前添加了这个来测试 DisplayNameFor 和 DisplayFor
@Html.DisplayNameFor(model => model.WebPageTitle)
@Html.DisplayFor(model => model.WebPageTitle)
<br />
改变了
@foreach (var item in Model) {
至
@foreach (var item in Model.Sites) {
并暂时注释掉包含所有表头的 tr 部分。除了@Html.DisplayNameFor 显示“WebPageTitle”的变量名称而不是使用“Web Page Title”,如数据注释的 Display 属性中所示,一切都运行良好
[Display(Name = "Web Page Title")]
public string WebPageTitle;
此外,如果我在包含表头信息的 tr 部分中进行评论。我一生都无法弄清楚要放入什么我尝试过 model.Sites.Abbreviation、model.Sites[0].Abbreviation 和其他各种组合,但出现错误。
<tr>
<th>
@Html.DisplayNameFor(model => model.Abbreviation)
</th>
<th>
@Html.DisplayNameFor(model => model.DisplayName)
</th>
<th></th>
</tr>
那么我应该在那里使用什么?我不太确定为什么 model.Sites.Abbreviation 不起作用,因为 Sites 与原始 Index.cshtml 中的模型使用的类型完全相同