构建ViewModel的适当粒度是什么?

时间:2012-10-14 01:22:50

标签: asp.net-mvc viewmodel

我正在开发一个新项目,并且在看到之前项目的一些困难之后,这些项目没有提供足够的视图与模型分离(特别是使用MVC)模型和视图开始相互渗透我想用MVVM。

我理解基本概念,我很高兴开始使用它。然而,有一件事让我感到有些不同 - ViewModel中应该包含哪些数据?

例如,如果我创建的ViewModel将包含两个数据,以便可以在表单中进行编辑,我是否可以像这样捕获它:

public PersonAddressViewModel {
    public Person Person { get; set; }
    public Address Address { get; set; }
}

或者像这样:

public PersonAddressViewModel {
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string StreetName { get; set; }
    // ...etc
}

对我来说,第一个对我们正在尝试做的事情感觉更正确。如果我们做的更精细的谷物形式(也许我们捕获的是FirstName,LastName和StreetAddress),那么下降到那个级别可能更有意义。但是,我觉得第一个是正确的,因为我们正在捕获表单中的ALL Person数据和ALL Address数据。似乎将事情分开是没有意义的(以及许多额外的工作)。

欣赏任何见解。

4 个答案:

答案 0 :(得分:2)

如果您正在使用Person对象的所有字段,那么使用复杂视图模型没有任何问题。但是,如果您只是在这里或那里使用某个字段,那么使用您正在使用的那些值构建您的viewmodel要好得多。

您可以按照自己喜欢的方式制作视图模型,但是拥有它们的重点在于视图模型应该根据它所代表的视图进行自定义。

如果您使用AutoMapper之类的东西来映射到业务或域模型,那么使用第一种方法也会容易得多,因为对象应该有类似的定义。

答案 1 :(得分:0)

你没有使用MVVM。您正在定义ViewModel,仅用于查看目的的类,以避免破坏Model类。在这种情况下,您可以定义所需的属性以获得最佳利润。在示例中,我将采用第二种解决方案,但这取决于您。

我正在与许多开发者提供商合作开展一个大项目。在这种情况下,客户让我们定义我们希望保留模型(他们调用的业务实体)的ViewModel。因为我们是不同的组,所以没有人担心另一个ViewModel,所以你甚至可以为一个视图使用一个类,无论另一个视图与第一个视图有什么不同。这是ViewModels的优势之一,而不是纯粹的Model使用。

为了数据绑定,我更喜欢在客户端通过JSON对象定义ViewModel。有了这个,你可以通过knockoutjs,angularjs,backbonejs等真正使用MVVM ....

如果你想使用MVVM检查knockoutjs。使用起来非常简单和愉快

答案 2 :(得分:0)

如果您的Model类具有一些敏感属性(即User类中的IsAdmin),则直接使用Model类或将它们包装(如第1个示例中所示)在ViewModel类中可能是一个潜在的安全问题。

假设您的控制器操作采用PersonAddressViewModel输入参数:

public ViewResult someAction(PersonAddressViewModel personAddress)
{
  //save it
}

恶意用户基本上可以在PersonAddressViewModel复合对象中设置任何属性,即使您的UI不提供此类功能。 这可以通过MVC的默认绑定机制实现。 要避免这种情况,请不要包装敏感模型类或使用Bind attribute

更多相关内容:Pro ASP.NET MVC 3 Framework 3rd Edition By Steven Sanderson , Adam Freeman(第17章)

答案 3 :(得分:-1)

如果您正在使用该视图模型来呈现表单,我会投票支持第二种方法,因为您要组合表单所需的所有视图数据。