使用数据注释进行 MVC 验证 - 它不起作用的场景,替代方案?
因此,我一直在 MVC 项目中使用数据注释进行验证,它们似乎适用于大多数场景。
这是我当前项目中的两个示例,它们似乎不适合,并且我不确定放置验证的最佳位置。
1) 我有一个加入联盟页面,其中包含一个表单,登录用户在其中输入他们的团队名称并单击加入联盟。当他们提交表单时,我需要确保当前用户在联盟中还没有球队。因此,它基本上需要在数据库中查询该用户 ID 和联盟 ID,以确保该用户不存在任何球队。我的 ViewModel 不包含用户 ID,因为它与视图无关。
2)在同一页面上,我还需要确保团队名称是唯一的。如果您只是想查看它是否存在于表中,这很容易。您创建一个自定义验证属性,用于查询表中的字段值。但是我需要查看它是否存在于某个联赛 ID 的表中。 (他们正在加入的联盟。)
数据注释似乎不是除琐碎验证之外的任何其他事情的理想解决方案。我当前的解决方案是在后操作方法开始时查询数据库,然后手动将错误添加到 ModelState 中。 (是的,太糟糕了)
有什么想法吗?
So I have been using data annotations for my validation in an MVC project and they seem to work in most scenarios.
Here are two examples in my current project where they don't seem to fit and I am unsure of the best place to put the validation.
1) I have a Join League page that contains a form where the logged in user enters their team name and clicks to join the league. When they submit the form i need to make sure that the current user doesn't already have a team in the league. So it basically needs to query the db for that user id and league id to make sure no team exists for the user. My ViewModel does not contain user id, since it is not relevant to the view.
2) On this same page, I also need to make sure the team name is unique. This is easy if you are just looking to see if it exists in a table. You create a custom validation attribute that query's a table for the value of the field. However i need to see if it exists in a table for a certain league id. (the league they are joining.)
It doesn't seem like Data Annotations are an ideal solution for anything other then trivial validation. My current solution is to query the db at beginning of post action method, and add the error to the ModelState manually. (yes, terrible)
Any ideas?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我认为对输入验证和业务逻辑之间的差异进行一些思考可能会有所帮助。 Ayende 对此有一些想法 这里
类似“当他们提交表单时,我需要确保当前用户在联盟中还没有球队”之类的规则听起来像业务逻辑,而不是输入验证,您可能需要在另一种方式。例如,这个逻辑可以进入“User”类或类似的东西上的“CanSave”方法 - 关键是如果可以的话,将其与输入验证分开。
I think it may help to put some thought into the difference between Input Validation and Business Logic. Ayende has some thoughts on this here
Rules like 'When they submit the form I need to make sure that the current user doesn't already have a team in the league' sounds like Business Logic, not Input Validation, and you may want to handle it in a different way. This logic could, for instance, go into a 'CanSave' method on a 'User' class or something similar - the key thing is to separate this from Input Validation if you can.
尽管我同意 Steve 的观点,但 DataAnnotations 有一个基本的 ValidationAttribute,您可以在其中实现您想要的任何内容。说它只能做一些琐碎的事情是不准确的,事实上有了这个扩展点,你几乎可以做任何你想做的事情。
现在,通过在代码中包含数据库逻辑,服务位置遍布各处,存在一些问题,但有一些选项可以解决这个问题。 DataAnnotations 通过 ModelValidatorProvider 类应用,该类可以像 ControllerFactories 或 ViewEngines 一样轻松配置。
ModelValidatorProviders.Providers.Add(new YourCustomProvider());
现在,在这种情况下,您可以做的是让验证器提供程序将持久层代码提供到您的属性中。因此,代码保持干净,但您可以使用接触数据库的自定义数据注释属性。
Although I agree with Steve, DataAnnotations has a base ValidationAttribute in which you can implement anything you want. To say it can only do trivial things is not accurate in fact with this extensibility point you can do almost anything you want.
Now there are some issues with service location being all over the place by having database logic inside your code but there are options to clean this up. The DataAnnotations are applied via a ModelValidatorProvider class that can easily be configured just like you would do ControllerFactories or ViewEngines.
ModelValidatorProviders.Providers.Add(new YourCustomProvider());
Now what you can do in this case is have your validator provider provide the persistence layer code into your attribute. So the code stays clean yet you can use custom data annotation attributes that touch the db.