ASP.NET MVC - 查看模型模式

时间:2011-05-20 21:50:54

标签: asp.net-mvc asp.net-mvc-3 razor standards view-model-pattern

我现在只使用MVC框架(ASP.NET MVC2 / 3 / Razor)几个月了,我真的非常喜欢它,但是我很难找到View Models的标准。在我的项目中,我有一个Models文件夹(包含我的数据模型 - Linq DBML,Repository [ies],扩展方法)和Models / ViewModels文件夹。我的视图模型通常是可重用的类,通常只包含LINQ对象的简单get / set属性或我需要为特定视图访问的对象集合。

现在我遇到的问题是弄清楚何时创建一个视图模型。我的目标是尽可能经常使用LINQ对象作为视图模型,尤其是当它是Edit操作时。我的问题是,如果我有其他数据,我可能只想用于显示目的?我不喜欢使用ViewData / ViewBag集合,因为访问这些集合的成员需要了解集合项的密钥(设计人员/前端人员不容易“猜测”)。我也不喜欢为每个View创建一个ViewModel的想法,因为它似乎是不必要的混乱代码。

例如,假设我有一个Employee的数据模型,我想显示一些与该员工无关的信息 - 例如,站点统计信息,动态菜单以及您可能想到的可能来自数据库的任何其他信息。我应该通过什么模型/ Employee / Edit操作? Employee对象有一堆ViewData []用于其余部分,还是自定义EmployeeView?

有金标准吗?我错过了什么?你在做什么不同我应该研究一下?提前谢谢!

3 个答案:

答案 0 :(得分:3)

我从不直接将我的实体类用作视图模型。我总是为包含该视图数据的每个视图创建一个特定于视图的模型。我已经开始使用AutoMapper在视图模型和实体模型之间进行映射。我通过ModelMapper类来调解这个问题,该类具有用于处理标准映射的ToViewModel<TEntity,TViewModel>()方法(仅调用automapper)和用于自定义映射的专用映射方法,尤其是支持从视图模型创建和更新实体。

答案 1 :(得分:2)

你在这里列举了三件事:

  • 网站统计信息
  • 动态菜单
  • 其他[...] 可能来自数据库

第三点是陷阱;只是因为某些内容存在于您的数据库中,并不意味着它属于您的域模型。

导航可能基于数据库。它也可能位于站点地图中或硬编码到应用程序中。它实际上不是应用程序数据,而是应用程序配置。如果你将它存储在应用程序数据库中,那就没关系(好吧,不是真的),但是不是模型本身的一部分。

同样,站点统计信息通常存储在数据库中,但它们存储在不同的数据库中,特别是分析数据库(很多人只是将其“外包”给Google)。同样,它们是数据,但它们不是您的模型。

如果您希望自己的应用程序有意义,则需要在概念层面上区分这些问题。导航在您的母版页/布局中完成,包括使其工作所需的任何动态代码。它是视图逻辑 - 不要让它泄漏到您的模型中。它完全没问题,通常最好使用ViewData / ViewBag来解决当前正在使用的实际功能的辅助问题。

现在,假设还有其他类型的视图数据实际应用程序数据:原则 原则视图应该直接连接到模型 - 这是毕竟“MVC”意味着什么 - 但在实践中,它只是重新实现了错误构思的“规范数据模型”的想法。域和表示是一个单独的问题,因此,意味着不同的上下文模型 - 在后一种情况下,这是一个视图模型。

当我第一次开始做MVC工作时,我也不愿意使用视图模型。但是在我对这个想法变得更加习惯之后,我意识到它确实是唯一成功的解决方案 - 特别是当你的“模型”大部分都是数据库本身的薄包装时。观点和数据以不同的方式和不同的速率发生变化;如果您不想担心不断出现的错误和回归,那么您需要两者之间的隔离。构建一个映射层并将其称为一天。

此时我已经为每个视图创建了一个不同的视图模型,无论我认为我是否需要它。一开始,它可能只是模型类的副本,但它意味着我可以随时以任何方式调整它而不必使用底层模型 - 反之亦然。 As tv says,初始视图模型很容易使用AutoMapper生成,并且可能占用大约30秒的时间。

只需使用视图模型,并希望最终这些工具支持视图模型自动生成。

答案 2 :(得分:0)

如果您创建了用于编辑员工的页面,但您还显示了您提到的内容(站点统计信息/菜单),为什么不将它们放在部分视图或布局文件中?