在开始使用ASP.NET MVC进行开发时,可能会问自己为什么需要使用视图模型(View Model)。使用领域模型(Domain Model)或实体模型(Entity Model)似乎也能很好地工作。确实如此,至少在一段时间内是这样的。但随着对模型的持续使用,会发现需要在视图中添加一些适应性改动。以下是使用Razor视图引擎的一个典型使用适应性示例:
Hello @model.UserName
Your age: @(model.Age != 0 ? model.Age.ToString() : "n/a")
看起来还不错,对吧?问题在于已经将逻辑引入到了视图中,这有两个不好的地方:
所有这些小的适应性改动最终会导致一个大的混乱。
视图模型的最大优势之一是消除安全风险。数据库对象或领域对象很可能包含用户不应该能够更改的属性。这些属性可能是名为IsAdmin或Reputation的属性。如果这些属性存在于模型中(并且被表单POST,如果知道HTML的话,这是很容易做到的),它们将自动被模型绑定器更改。简单地从视图模型中移除它们,它们就永远不会被更改。
通过使用领域模型或实体模型,正在增加较低层次和表示层之间的耦合,这通常不是好事。Google一下“解耦”以了解更多信息。
基本上,这意味着如果改变了领域/实体模型,就必须改变所有使用该模型的视图。如果使用视图模型,只需要改变映射实体/领域模型和视图模型之间的代码。
通常使用一个名为AutoMapper的框架来管理视图模型和其他模型之间的映射。AutoMapper及其替代品通常允许使用一行代码来完成映射。
例如,可以这样使用AutoMapper:
var viewModel = Mapper.Map<ViewModelType>(entityModel);