【发布时间】:2015-11-06 13:53:18
【问题描述】:
我正在尝试以这样一种方式构建我的控制器和视图,即我的所有视图都是强类型的,并且我不使用 ViewBag。我有一个从中继承的基本视图模型,为每个视图创建一个“容器”视图模型,以及为每个表单创建一个视图模型。
对于这个例子,让我们关注一个可以由一组国家组成的区域实体(可能用于计算运费、增值税等):
public class BaseViewModel
{
public string Title { get; set; }
public string MetaDescription { get; set; }
public string CanonicalUrl { get; set; }
public Website Website { get; set; } // class that contains properties like site name, base url, use ssl, etc
}
public class ZoneCreateForm
{
[Key]
public int Id { get; set; }
[Required]
public string Name { get; set; }
[DataType(DataType.MultiLineText)]
public string Description { get; set; }
public int[] CountryIds { get; set; } // Selected country ids
}
public class ZoneCreateViewModel : BaseViewModel
{
public IEnumerable<Country> Countries { get; set; } // All countries. Used to create a dropdown list to select from
public ZoneCreateForm CreateForm { get; set; }
}
我试图将我的“表单模型”限制为仅发布到表单的字段。这有助于通过消除基础模型中的属性以及帖子上控制器操作中的 AutoMapper 来搭建脚手架。
但是,在本例中,我需要访问父模型的 Countries 属性才能创建所有国家/地区的下拉列表。
在我看来,我有一些选择:
- 输入国家/地区并将其填充到 ViewBag 中,以便可以从 CreateForm 部分视图访问它们。
- 使国家/地区成为
ZoneCreateForm视图模型的一部分,并在控制器操作上使用 [Bind(Exclude="Countries")] 以避免过度发布 - 还有什么我没有想到的?
有没有一种“标准”的方式来处理这个问题?我在网上看到的大多数示例都使用域模型,而不是具有任何继承和子模型的视图特定模型。每当他们需要额外的数据时,他们就将其塞入 ViewBag,这对我来说似乎很脏。
【问题讨论】:
-
为什么你不能在控制器中填充属于 ZoneCreateViewModel 的 Counties 属性,并在需要的视图上呈现一个下拉列表,而在不需要的视图上将其保留为 null?
-
需要国家/地区的表单部分视图基于不包括国家/地区列表的
ZoneCreateForm。我想我最终要做的是将IEnumerable<SelectListItem> Countries和IEnumerable<SelectListItem> States添加到ZoneCreateForm模型并使用public ActionResult Create([Bind(Exclude="Countries,States")]ZoneCreateForm form)作为操作方法。
标签: c# asp.net asp.net-mvc viewmodel