将 DataAnnotation 属性从模型应用到 ViewModel

发布于 2024-10-04 10:56:19 字数 553 浏览 8 评论 0原文

我们将所有 DataAnnotations 放在模型类 Customer 上。然后,我们将 Customer 的实例公开为关联 ViewModel 上的属性,以及国家/地区等的一些查找列表,并将其显示在我们的视图中。到目前为止一切都很好。

然后,我们在 SO 和其他来源上了解到,我们不应该将整个 Customer 模型对象传递给视图,因为只为视图提供所需的最低限度,更重要的是(对我们来说)防止 ModelBinding 时可能出现的问题潜在的恶意回发,添加额外的信息来更改我们的模型属性,否则这些属性在视图中不可用。

我们如何将所有这些 DataAnnotation 属性从模型对象中获取到可能被削减的 ViewModel 属性上,而不将 DRY 原则抛下悬崖?

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

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

We put all of our DataAnnotations on our Model class Customer. We then expose an instance of Customer as a property on our associated ViewModel along with some lookup lists for Countries etc and display this in our View. All's good so far.

We then read on SO and other sources that we shouldn't be passing our entire Customer model object to the View for the reasons of only providing the View with the bare minimum it needs and more importantly (for us) to prevent possible issues when ModelBinding potentially malicious postbacks that add additional information to change our models properties that otherwise were not available in the view.

How do we get all of those DataAnnotation attributes off the model object and onto the possibly cut down ViewModel properties without throwing the DRY principle over the cliff?

Also, are we correct in thinking that we shouldn't be using TryUpdateModel against an entity that we pull from the db? I guess our choice is to either use TryUpdateModel and pass an exclusion list of properties which doesn't seem particularly elegant to me given that the list is just a param of type string. Or perhaps we should do away with TryUpdateModel and use a tool such as AutoMapper which is more type safe?

Thanks for any thoughts on these issues.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

梦巷 2024-10-11 10:56:19

我们如何将所有这些 DataAnnotation 属性从模型对象中获取到可能被削减的 ViewModel 属性上,而不将 DRY 原则抛下悬崖?

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

另外,一般来说,我仅将验证属性放在视图模型上,但这可能不是最好的方法,因为如果您想在不同的应用程序中重用模型,它们上不会有任何验证逻辑。

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

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

就 AutoMapper 而言,它是在模型类(出现在存储库方法签名中)和传递到视图或从视图中传递的视图模型之间进行转换的必备工具。

How do we get all of those DataAnnotation attributes off the model object and onto the possibly cut down ViewModel properties without throwing the DRY principle over the cliff?

You can't. It's the price to pay, but I think it's pretty cheap because in fact in this stripped down version the validation attributes might be different and you might have different validation properties according to the requirements of the view. Let's take an example: New and Edit view. In the Edit view, the Id of the entity will be required, while in the New view not required as it will be assigned by the data store (in fact in your new model there might not even be an Id property).

Also, in general I place the validation attributes only on the view model but this might not be the best approach as if you wanted to reuse your models in different applications, there won't be any validation logic on them.

Also, are we correct in thinking that we shouldn't be using TryUpdateModel against an entity that we pull from the db?

Personally I never use TryUpdateModel. I prefer passing a view model as a controller action parameter and leave the default model binder do the job. In this case of course you don't need any inclusion or exclusion properties list because this view model is exactly tailored to the given view.

As far as AutoMapper is concerned it's a must have tool for converting between your model classes (which appear in your repository method signatures) and the view models which are passed to and from the view.

别把无礼当个性 2024-10-11 10:56:19

我发现仅将验证属性放在 ViewModel 上并单独保留模型对象是最好的方法。

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

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

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

I have found that placing validation attributes ONLY on the ViewModel and keeping the model object alone was the best approach.

The view models are validated when a user posts any data and if the data is valid, the business layer takes care of creating the object model in the database with the data the user sent in.

In the services/business layer classes, functions that update or add only accept the necessary values for a object model (strings, ints, etc.) but never an entire object. The service class is responsible for creating the object.

By placing the validation on the view model, you ensure that any and all data passed into your business logic layer is valid and you can safely commit changes.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文