如何在不重复代码的情况下实现业务和视图验证?
如何避免需要在 ViewModel 和业务/域对象上重复验证规则?
例如,我可以在 ViewModel 上使用 DataAnnotation 属性,这将为我的 MVC Web 应用程序提供客户端和服务器端验证。但是这个 ViewModel 通常会被映射到业务/域对象,并提供给服务来执行一些业务逻辑,这意味着验证必须再次进行,通常使用相同或相似的规则。无论如何还有这个吗?
How do I avoid needing to repeat validation rules on both my ViewModels and business/domain objects?
For example I can use DataAnnotation attributes on my ViewModel, and this will give me client and server side validation in my MVC web app. But this ViewModel will then generally be mapped to a business/domain object and given to a service preform some business logic, meaning validation will have to happen again, often with the same or simular rules. Is there anyway round this?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我认为你所描述的情况是正常的,可以接受的。将您的 UI 和数据注释视为友好的 UI 验证,能够立即向用户显示输入数据的任何验证问题。
我认为您的业务/域对象的验证是完整的验证,不仅仅是验证值,而是执行业务规则(即 - 将商品添加到购物车 - >该商品有库存吗?)
然后总是有后端验证通常由数据库强制执行(即列中允许空值)。除非您的数据库允许所有字段都为空,否则您实际上不仅仅在您提到的两个地方执行验证,我认为这是一件好事。
我认为最重要的是,您可能希望业务/域对象强制执行所有验证,而客户端和后端验证仅强制执行最基本的验证。
希望有帮助。
I think what you're describing is normal and acceptable. Consider your UI and data annotation as the friendly UI validation that is capable of showing users immediately any validation problems with the data entered.
I would consider your Business/Domain object's validation to be the complete validation, not just validating values but enforcing business rules (i.e. - Add Item to Cart -->Is the Item in Stock?)
Then there is always back end validation that is often enforced by the database (i.e. Allowing Nulls in a column). Unless your database allows nulls in all fields, your actually performing validation in more than just the two places you mentioned, and this I think is a good thing.
I think the bottom line is that you probably want your Business/Domain objects to enforce all validation, and your client side and back end validation to simply enforce the most basic.
Hope that helps.
如果您想验证两个单独的对象并避免重复代码,那么我认为您可能会得到一个您不想听到的答案。
我能想到的唯一例外是采用返回的视图模型(未经验证)并填充您的模型,就像您要执行数据库操作一样,然后在那里进行验证检查。如果存在错误,请将其带回 ModelState 字典,并将包含错误的视图返回到浏览器。这种方法有一个很大的副作用,即您会失去客户端集成,或者充其量 - 它会涉及对服务器端的大量 AJAX 调用。
就我个人而言,我会接受失败并接受您将进行重复的工作,并确保尽可能多的代码是可重用的(例如,作为可以放置在视图模型和业务模型上的数据注释属性)
在您的业务模型中检查数据是否正确。例如
但是,对于业务逻辑,如果您担心数据可能会因替代接口(或您的健忘)的不一致检查而受到污染,那么请将某些方法复制到业务逻辑或模型元数据中。
If you want to validate two separate objects and avoid duplicating code, then I think you may be in for an answer you won't want to hear.
The only exception I can think of is to take the returned view model (unvalidated) and populate your models as you would if you were to perform the database action, then do the validation check there. If there are errors, bring those back to the ModelState dictionary and return the view to the browser with errors. This approach has the big side effect that you'd lose the client-side integration, or at best - it'd involve a lot of AJAX calls to the server side.
Personally, I'd accept defeat and accept that you're going to have duplication of effort and just ensure that as much of your code is re-usable (e.g. as Data Annotation attributes that can be placed on both your view models and business models.
Checks in your view models should ensure that the information provided is correct e.g:
Checks within your business models check to see that the data is correct. e.g.
However, with the business logic, if you're concerned that the data may get polluted by inconcistent checks by alternative interfaces (or your forgetfulness), then duplicate some of the methods into the business logic or into the model metadata too.