将DataAnnotation属性应用于Model中的ViewModel

时间:2010-11-24 21:36:46

标签: asp.net-mvc data-annotations validation mvvm

我们将所有DataAnnotations放在Model类Customer上。然后,我们将Customer实例作为属性暴露在我们关联的ViewModel上,同时将一些查找列表显示在Country等中,并在View中显示。到目前为止一切都很好。

然后我们阅读SO和其他来源,我们不应该将整个Customer模型对象传递给View,原因是只提供View所需的最小值,更重要的是(对我们而言)以防止可能当ModelBinding潜在的恶意回发添加额外信息以更改我们在视图中无法使用的模型属性时出现问题。

我们如何从模型对象和可能减少的ViewModel属性中获取所有这些DataAnnotation属性,而不会在悬崖上抛出DRY原则?

另外,我们是否认为我们不应该对我们从数据库中提取的实体使用TryUpdateModel?我想我们的选择是要么使用TryUpdateModel并传递一个排除的属性列表,这对我来说似乎并不特别优雅,因为列表只是一个字符串类型的参数。或者我们应该取消使用TryUpdateModel并使用更安全的AutoMapper等工具?

感谢您对这些问题的任何想法。

2 个答案:

答案 0 :(得分:1)

  

我们如何从模型对象和可能减少的ViewModel属性中获取所有这些DataAnnotation属性,而不会在悬崖上抛出DRY原则?

你做不到。这是付出的代价,但我认为它相当便宜,因为实际上在这个精简版本中,验证属性可能不同,根据视图的要求,您可能有不同的验证属性。我们举个例子:NewEdit查看。在Edit视图中,将需要实体的Id,而在New视图中则不需要,因为它将由数据存储分配(实际上在您的新模型中)甚至可能不是Id属性)。

此外,通常我只将验证属性放在视图模型上,但这可能不是最好的方法,就好像你想在不同的应用程序中重用模型一样,它们上面没有任何验证逻辑。

  

另外,我们是否正确认为我们不应该对我们从数据库中提取的实体使用TryUpdateModel?

我个人从不使用TryUpdateModel。我更喜欢将视图模型作为控制器操作参数传递,并让默认模型绑定器完成工作。在这种情况下,您当然不需要任何包含或排除属性列表,因为此视图模型完全适合给定视图。

就AutoMapper而言,它是必须具备的工具,用于在模型类(显示在存储库方法签名中)和传递给视图和从视图传递的视图模型之间进行转换。

答案 1 :(得分:0)

我发现只在ViewModel上放置验证属性并保持模型对象是最好的方法。

当用户发布任何数据时验证视图模型,如果数据有效,业务层将负责使用用户发送的数据在数据库中创建对象模型。

在服务/业务层类中,更新或添加的函数只接受对象模型(字符串,整数等)的必要值,但从不接受整个对象。服务类负责创建对象。

通过在视图模型上放置验证,可以确保传递到业务逻辑层的所有数据都有效,并且您可以安全地提交更改。