以下可以做吗?我知道域模型永远不应该在视图中使用,但是在视图模型中使用域模型是否可以?对于一些非常小的模型,为它们创建和管理视图模型似乎不值得。
例如
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<Login>();
}
public long UserTypeID { get; set; }
public string UserType { get; set; }
public string Description { get; set; }
public virtual ICollection<Login> Logins { get; set; }
}
public class LoginViewModel
{
public string Email { get; set; }
public long UserTypeID {get; set;}
//Right here
public List<UserTypeDomainModel> UserTypesSelectList {get; set;}
}
我个人在视图中使用域模型 如果它们自然是完全合适的话。这很可能只发生在CRUD本质上的简单项目上(以直接的方式编辑域实体)。为了纯洁,我发现创建域实体的精确副本是浪费时间。
我会 决不 最简单地修改域模型以满足视图的需要。在95%以上的项目中,这就是我自己所处的环境。当你为了视图而污染域名时,就会引入可维护性问题。
这取决于你所说的“领域模型”。你的意思是EF实体吗?或者你的意思是业务层对象?
将EF实体传递给视图永远不是一个好主意,特别是如果您使用默认模型绑定。如果您不小心,这可能会产生安全问题。虽然如果您对传递给视图的业务对象不小心,可能会出现同样的问题。
视图模型的一个巨大优势是您可以更好地控制数据映射,因此您可以更轻松地验证只发生正确的映射。
这一切都归结为你的应用程序。如果它是一个简单的应用程序,那么进行更复杂的映射可能不值得。如果它是一个复杂的应用程序,它必须存在很长时间,并可能会更新很多..那么你一定要投入精力。
由于单独的视图模型和域模型导致的重复感觉,我很长时间都在努力。我断言,因为它们的目的不同,所以不是 真 重复,但声明这么多相似的属性仍然感觉“错误”。
在非常小的项目中(特别是那些具有高度可信赖的经过身份验证的用户组)我可能只是直接绑定到域模型并完成它。或者,如果视图模型需要不同的结构,我可以混合搭配(如@Eric J.所述)。
然而:ModelBinder将尝试将请求中的值与模型上的属性进行匹配。这意味着您的域模型上的任何属性都可能被(流氓)请求填充。有一些方法可以防止这种情况发生,但对我来说,心灵的安心超过了创建单独视图模型的额外努力。
我没有看到绝对需要为只读,未绑定的值创建单独的视图模型(可能是您的情况下的用户类型列表,尽管 public virtual ICollection<Login> Logins
可以否定这一点)。
或者,您可能希望将域模型投影到面向UI的抽象(例如, IEnumerable<SelectListItem>
)。您可以使用 SelectListItems
对于各种输入机制,因此您不会将自己与特定的UI行为联系起来。
即使使用抽象,您仍可能需要验证请求是否包含非法值。例如,也许只有超级管理员可以指定某些 UserTypeDomainModel
标识。无论抽象如何,您仍需要验证这一点。
TLDR: 抽象领域模型尽可能实用,找到适当的抽象(新的视图模型并不总是正确的答案),并且(稍微偏执)关于输入验证。