我使用 ASP.NET MVC 3。
我遇到了至少 2 种在服务器端映射 Model->ViewModel 的方法:
- ViewModel 类构造函数内部
- 在 Controller 或指定的映射器类中
我最喜欢第一种方法,因为 ViewModel 属性声明及其映射在同一个地方,易于维护和单元测试。任何人都可以指定更多的利弊,或其他更好的做法吗?
我使用 ASP.NET MVC 3。
我遇到了至少 2 种在服务器端映射 Model->ViewModel 的方法:
我最喜欢第一种方法,因为 ViewModel 属性声明及其映射在同一个地方,易于维护和单元测试。任何人都可以指定更多的利弊,或其他更好的做法吗?
ViewModel 可以独立于任何源自数据库的模型类而存在。
我不建议将 ViewModel 填充代码放在控制器中,因为这不是控制器的责任(也是维护的噩梦)。
我的观点是从 ViewModel 映射到 DBModel(反之亦然)是 ViewModel 的责任,所以我所有的 ViewModel 类都实现了两个成员:
public static TViewModel FromDBModel(TDBModel dbModel);
public void ToDBModel(TDBModel dbModel);
第一个是Controller在返回View时调用的静态方法。静态方法构造 ViewModel 的一个实例并相应地设置其成员。
实例 ToDBModel 方法传递一个构造的 DBModel 实例(在检索或更新数据时由 Repository 构造,或在插入新数据时由控制器构造)。
HTH。
编辑:请注意,许多人对 AutoMapper 等库发誓(它使用反射和其他技巧来自动化 DBModel<->ViewModel 映射过程)。我不喜欢自动映射,因为它会从开发人员手中夺走控制权,而且当我必须了解映射器的工作原理以及如何让它映射非平凡的操作时,我认为它不会为我争取时间。YMMV。
我倾向于将实体和视图模型分开,以使它们彼此不知道。这是为了在测试控制器和映射本身时改进封装并最小化依赖关系。请参阅关注点分离。
相反,我会编写类来自己执行映射(如果它简单的话)或使用 AutoMapper 并在控制器中使用该方法。对于具有数十或数百个数据库实体和视图的大型系统,我倾向于使用 AutoMapper。自己编写映射会变得非常乏味且容易出错。你必须平衡你自己编写它的价值和这种实现给业务带来的价值。毕竟,如果我们想了解每个框架的一切,我们每个人都会编写自己的 .NET 框架版本。:)
也就是说,对某些系统使用视图模型可能没有什么好处,尤其是那些在视图中的“字段”和数据库实体之间存在一对一映射的系统 [又名典型的 CRUD]。当我看到这一点时,我通常会畏缩,但考虑到系统的时间框架和复杂性,它始终是一种选择。
然后有一种情况是你使用 ASP.NET MVC 来暴露一个 API。在这种情况下,实体的“application/json”和“text/xml”表示只是“视图”。视图模型通常用于从外部演示中过滤敏感和不必要的数据。在这种情况下,映射变得相当复杂,因为同一实体可能有多个表示(及其版本)。但是,这似乎在 OP 之外。