MVC在视图模型中使用域模型

以下可以做吗? 我知道域模型永远不应该在视图中使用,但是在视图模型中使用域模型是否可以? 对于一些非常小的模型,为它们创建和管理视图模型似乎不值得。

例如

public class LoginDomainModel { public string Email { get; set; } public string Password { get; set; } public string DisplayName { get; set; } public long UserTypeID { get; set; } public virtual UserType UserType { get; set; } } public class UserTypeDomainModel { public UserType() { this.Logins = new List(); } public long UserTypeID { get; set; } public string UserType { get; set; } public string Description { get; set; } public virtual ICollection Logins { get; set; } } public class LoginViewModel { public string Email { get; set; } public long UserTypeID {get; set;} //Right here public List UserTypesSelectList {get; set;} } 

我个人在视图中使用域模型, 如果它们自然是完全合适的话 。 这很可能只发生在CRUD本质上的简单项目上(以直接的方式编辑域实体)。 为了纯洁,我发现创建域实体的精确副本是浪费时间。

永远不会修改域模型以满足视图的需要。 在95%以上的项目中,这就是我自己所处的环境。当你为了视图而污染域名时,就会引入可维护性问题。

这取决于你所说的“领域模型”。 你的意思是EF实体吗? 或者你的意思是业务层对象?

将EF实体传递给视图永远不是一个好主意,特别是如果您使用默认模型绑定。 如果您不小心,这可能会产生安全问题。 虽然如果您对传递给视图的业务对象不小心,可能会出现同样的问题。

视图模型的一个巨大优势是您可以更好地控制数据映射,因此您可以更轻松地validation只发生正确的映射。

这一切都归结为你的应用程序。 如果它是一个简单的应用程序,那么进行更复杂的映射可能不值得。 如果它是一个复杂的应用程序,它必须存在很长时间,并可能会更新很多..那么你一定要投入精力。

由于单独的视图模型和域模型导致的重复感觉,我很长时间都在努力。 我断言,因为它们是出于不同的目的而不是真的重复,但是声明这么多相似的属性仍然感觉“错误”。

在非常小的项目中(特别是那些具有高度可信赖的经过身份validation的用户组)我可能只是直接绑定到域模型并完成它。 或者,如果视图模型需要不同的结构,我可以混合搭配(如@Eric J.所述)。

但是 :ModelBinder将尝试将请求中的值与模型上的属性进行匹配。 这意味着您的域模型上的任何属性都可能被(流氓)请求填充。 有一些方法可以防止这种情况发生,但对我来说,心灵的安心超过了创建单独视图模型的额外努力。

我没有看到绝对需要为只读的未绑定值创建单独的视图模型(可能是您的情况下的用户类型列表,尽管public virtual ICollection Logins可能会否定这一点)。

或者,您可能希望将域模型投影到面向UI的抽象(例如IEnumerable )。 您可以将SelectListItems用于各种输入机制,因此您不会将自己与特定的UI行为联系起来。

即使使用抽象,您仍可能需要validation请求是否包含非法值。 例如,也许只有超级管理员可以分配某些UserTypeDomainModel ID。 无论抽象如何,您仍需要validation这一点。

TLDR:抽象领域模型尽可能实用,找到合适的抽象(新的视图模型并不总是正确的答案),并且(稍微偏执)关于输入validation。