ASP.NET MVC 视图模型模式
Posted
技术标签:
【中文标题】ASP.NET MVC 视图模型模式【英文标题】:ASP.NET MVC ViewModel Pattern 【发布时间】:2010-11-24 13:39:37 【问题描述】:编辑:我做了一些更好的东西来使用 ViewModels 从视图中填充和读取数据,称为 ValueInjecter。 http://valueinjecter.codeplex.com/
http://prodinner.codeplex.com 使用它 - 一个 ASP.net MVC 示例应用程序
您可以在 prodinner 中看到使用 ViewModels 的最佳方式
使用 ViewModel 存储映射逻辑并不是一个好主意,因为存在重复和 SRP 违规,但现在使用 ValueInjecter,我有干净的 ViewModel 和干映射代码
那是旧东西,不要使用它:我制作了一个 ViewModel 模式,用于在 asp.net mvc 中编辑东西 当您必须制作用于编辑实体的表单并且必须在表单上放置一些下拉菜单以供用户选择一些值时,此模式很有用
public class OrganisationBadViewModel
//paramterless constructor required, cuz we are gonna get an OrganisationViewModel object from the form in the post save method
public OrganisationViewModel() : this(new Organisation())
public OrganisationViewModel(Organisation o)
Organisation = o;
Country = new SelectList(LookupFacade.Country.GetAll(), "ID", "Description", CountryKey);
//that's the Type for whom i create the viewmodel
public Organisation Organisation get; set;
...
【问题讨论】:
【参考方案1】:这看起来与 Wrox Professional ASP.NET MVC 书中推荐的做法非常相似,其第一章可从上述 URL 免费获得。
从第 100 页开始,他们有一个关于 ViewData 和 ViewModels 的部分。
当控制器类决定将 html 响应呈现回客户端时,它负责将呈现响应所需的所有数据显式传递给视图模板。视图模板不应该执行任何数据检索或应用程序逻辑 - 而是应该将自己限制为仅具有由控制器传递给它的模型/数据驱动的渲染代码。
[...]
当使用 [“ViewModel”] 模式时,我们会创建针对特定视图场景进行优化的强类型类,并公开视图模板所需的动态值/内容的属性。然后,我们的控制器类可以填充这些视图优化类并将其传递给我们的视图模板以供使用。这可以在视图模板中实现类型安全、编译时检查和编辑器智能感知。
取自 Rob Connery 等人编写的由 Wrox 出版的 Professional ASP.NET MVC 1.0 的“第 1 章“书呆子晚餐””。原件可在http://tinyurl.com/aspnetmvc
获得【讨论】:
【参考方案2】:有几件事困扰着我。
术语。 ViewModel 在这种情况下是一个简单的视图数据,由控制器填充并稍后使用。 View 对控制器一无所知,因为 ASP.NET MVC 基础结构负责选择控制器和适当的操作。控制器处理用户交互。我认为它看起来更像被动视图而不是 ViewModel(我假设 ViewModel 是指 Model-View-ViewModel 模式)。
详细信息。填充视图数据的控制器不应该知道视图是如何实现的细节。然而 OrganisationViewModel.Country 披露了不必要的细节(SelectListItem 是纯视图实现细节)。从而使控制器依赖于视图实现细节。我认为应该改变它以避免它。考虑使用一些对象来保存一个国家的数据。
希望这会有所帮助。
【讨论】:
【参考方案3】:总的来说,我认为它看起来不错,并且为您的域对象创建视图模型通常是个好主意。
我没有查看每一行代码,但引起我注意的一件事是 OrganisationViewModel 的构造函数。我会使用以下方法重写它:
public OrganisationViewModel() : this(new Organisation())
public OrganisationViewModel(Organisation o)
Organisation = o;
InitCollections();
这会删除一些重复的代码,因为您不必在两个构造函数中调用 InitCollections()
。当然,这只是一个小细节,与大意无关。
【讨论】:
【参考方案4】:我们开始这样做了,但是我们的控制器开始变得很可怕(因为我们的 ViewModel 不一定 1:1 映射到我们的数据库)。为了缓解这种情况,我们创建了 Mapper 类来创建 ViewModel,然后映射回绑定到数据库的数据。然后控制器只调用 Mapper 类方法。看起来效果不错。
【讨论】:
看看这个valueinjecter.codeplex.com/documentation,这就像一个通用的映射器,也许你可以用它来做你的映射以上是关于ASP.NET MVC 视图模型模式的主要内容,如果未能解决你的问题,请参考以下文章
使用 ASP.NET MVC 数据绑定视图模型显示 JQuery 对话框的最佳方式
ASP .Net MVC 模型 - ViewModel - 视图