如何避免每个Model需要一个VIewModel

时间:2011-05-06 05:25:25

标签: asp.net-mvc

我正在使用ASP.NET 4和MVC3。

通常,我发现我需要一个ViewModel来显示我的模型的信息。例如,采用以下模型

class Profile
{
   public int UserID { get; set; }
   public string Name { get; set; }
   public DateTime DOB { get; set; }
}

需要隐藏UserID,但要显示UserName,所以通常时间与上面的模型类似,我必须提出一个ViewModel,只将UserID更改为UserName:

class ProfileViewModel
{
   public string UserName { get; set; }
   public string Name { get; set; }
   public DateTime DOB { get; set; }
}

有什么方法吗?

3 个答案:

答案 0 :(得分:2)

直到最近,我总是将我的模型传递给我的动作方法,因为我还认为创建具有相同属性名称的viewModel是重复的(不是)。这让我感到很痛苦。我现在已经重新接受教育,并且几乎总是在我的动作方法中专门使用viewModels(当然,总是存在将模型直接传递给action方法的情况。)

阅读this帖子,该帖子是将我转换为使用viewModels的帖子。这将告诉您以下内容:

  1. 模型和viewModels之间的区别
  2. 何时应该使用。
  3. 如何避免使用默认模型绑定器的某些安全问题。
  4. 除了链接帖子中的信息之外,您还应该考虑验证等内容。我有一个实现IValidateableObject接口的模型,以确保实体在保存到数据库之前处于有效状态。

    在我的ASP.NET应用程序中,我想创建一个允许用户在多个页面上输入信息的多步骤表单。我在这里遇到的问题是ASP.NET在模型绑定过程中也使用IValidatableObject接口。

    如果您只允许用户输入实体所需信息的子集,则模型绑定器将只能填写给定的信息。根据验证的复杂程度,这会导致ModelState被标记为无效,因为整个实体无效。

    我解决这个问题的方法是让一个viewModel代表每个步骤,每个步骤都有自己的验证。这样,您只需在每个步骤验证属性。一旦完成最后一步并且一切都有效,我将使用用户提供的信息创建一个合适的实体。该实体仅对其执行数据库级验证检查(字段长度等)

    我的建议不是要避免使用viewModel,而是要了解它们的使用原因并接受它们。

答案 1 :(得分:1)

不,没有,一旦会员公开,它就是公开的。现在,如果UserID属性是内部的,那么你就不会遇到这个问题。

然而,MVVM的目标之一是封装有关模型和视图交互的逻辑。即使您将视图模型和模型放在单独的程序集中并将UserID属性设置为内部,您仍应该有一个视图模型;如果需要更多功能而不仅仅是简单地绑定到模型的行,那么您就做好了准备。

直接访问模型总是不行。

此外,如果您真的想要,您可以随时使用T4模板为您自动生成代码(您可以在原始CS文件上使用Code DOM)为您输出视图模型。

答案 2 :(得分:1)

我通常每个模型都有多个ViewModel - 您需要做出的权衡归结为:

  1. 您是否愿意将业务逻辑(数据注释,显示信息等)与您的(持久性)模型相结合?
  2. 您是否愿意完全在视图中执行所有隐藏/显示业务逻辑而不使用Controller +脚手架为您做出这些决定?
  3. 创建所有ViewModel的缺点当然是子类爆炸,但考虑它的正确方法是我列出的问题恕我直言。