在ASP.NET MVC中进行开发时,我使用1:1 ViewModel设置,其中viewmodel仅包含视图所需的数据。我也在使用数据注释来验证viewmodel。
我担心的是,这不遵循DRY原则,因为我发现自己必须在我的网站中复制验证。我希望在一个地方(我的域模型)进行验证,但因为我从未将域模型发送到视图模型,所以这是不可能的。
我想知道是否有其他人遇到过这个问题并找到了解决问题的合适方法或者有更好的解决方案?
答案 0 :(得分:6)
当我们采用1:1 ViewModel方法时,我们遇到了类似的问题。我们发现1)复制比第一次出现的要少,2)应用程序的整体可维护性和功能得到了足够的改善,任何非DRY成本都是物有所值。
我们最终考虑从不同角度(关注点分离)验证ViewModel和域模型。在域级别模型上实施验证时,我们正在寻找全面的安全措施来防止攻击。我们还检测到严重的“合同”违规行为,表明上层存在漏洞。在视图模型中实现验证时,我们严格关注可用性。
如果从这些不同的角度看待模型,那么你可能会想到的重叠程度就会减少。出于可用性原因,域层可能允许您在ViewModel中限制某些操作。或者ViewModel可能会假设只发布渲染视图的输入,依靠域模型进行全面的安全验证,以防止攻击。
1:1 ViewModels也极大地简化了可测试性。 ViewModel的测试可以独立于域层编写,这使得单元测试更轻,更易维护,并且通常更有用。同样,您可以测试域模型,而不会对输入如何通过用户界面进行精确扭曲。这也坚持“纵深防御”的安全原则。
我们还注意到视图比域层更频繁地更改。知道您的域模型上有非常好的安全单元测试覆盖率,并且当您实现新的View时,您只需要担心从可用性角度进行验证。
最后,如果您预计会有一个Web服务层,您会发现域和视图模型的分离会带来好处。没有它,域模型不可避免地被编写以支持UI。当您在服务接口上进行分层时,您会发现阻抗不匹配。
如果确实存在重大重复,您始终可以单独考虑验证。根据我们的经验,由于上述所有原因,这一点并不值得。