3

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

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

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

有黄金标准吗?我错过了什么?你在做什么不同的事情,我应该调查一下?提前致谢!

4

3 回答 3

3

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

于 2011-05-20T21:55:43.907 回答
2

你在这里命名了三件事:

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

第三点是一个陷阱;仅仅因为某些东西在您的数据库中,并不意味着它是您的域模型的一部分。

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

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

如果您希望您的应用程序有意义,您需要在概念级别上分离这些关注点。导航在您的母版页/布局中完成,包括使其工作所需的任何动态代码。这是纯粹的视图逻辑——不要让它泄漏到你的模型中。对于当前使用的实际功能的辅助问题,使用 ViewData/ViewBag 是完全可以的,通常更可取。

现在,假设还有其他类型的视图数据实际上应用程序数据:原则上视图应该直接连接到模型是正确的——毕竟这就是“MVC”的意思——但实际上,它只是一个重新-实施构思不周的“规范数据模型”理念。领域和表示是不同的关注点,因此,意味着不同的上下文模型 - 在后一种情况下,这是一个视图模型。

当我第一次开始做 MVC 工作时,我也不愿意使用视图模型。但是在我更习惯了这个想法之后,我意识到它确实是唯一可行的解​​决方案——尤其是当你的“模型”主要是数据库本身的一个薄包装器时。视图和数据以不同的方式和速率发生变化;如果您不想担心源源不断的错误和回归,那么您需要在两者之间进行一些隔离。构建一个映射层并收工。

在这一点上,我已经开始为每个视图创建不同的视图模型,无论我是否需要它。一开始,它可能只是模型类的复本,但这意味着我可以随时以任何方式对其进行调整,而不必乱搞底层模型——反之亦然。 正如 tv 所说,使用AutoMapper生成初始视图模型非常容易,并且可能会占用您 30 秒的时间。

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

于 2011-05-20T22:14:36.890 回答
0

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

于 2011-05-20T22:03:47.813 回答