What is the point of the MVC implementation of IValidatableObject if it can't be used to perform full validation of the object?
请有人帮帮我,因为我一口气验证控制器动作中绑定的对象确实很麻烦。
我认为
这使我想知道,如何对对象执行完整的复杂验证并返回完整的验证错误集?没有人想要在网络表单上修复所有报告的错误,然后提交以将更多错误返回给他们。
我以为我也许可以在
所以我不能仅使用一种方法执行所有验证:
- 原因
- 无法执行高级验证,例如基于模型中其他值的条件验证
- 除了单独的字段验证之外,它还不执行其他任何操作
- 原因
- 没有逃脱或"关闭"常规模型验证,以使其静默失败,因此我可以对对象执行完全验证
- 如果常规模型验证以任何方式失败(例如绑定失败),IValidatebleObject并不总是会触发
无论绑定是否成功,如何一次性验证对象?
无论绑定成功如何,
您似乎遇到的问题是,由于不同的原因,验证在框架的不同部分进行。
首先,进行客户端验证。如果您的所有字段都具有不干扰的客户端验证,则所有验证将立即在客户端上进行。
第二个是模型绑定。如果尝试将项目绑定到其模型条目时发生错误,则这些项目将首先失败。例如,如果您尝试将字符串" xxx"绑定到DateTime,它将抛出验证错误,因为它无法将" xxx"转换为DateTime。而且,由于DateTime是不可为空的,因此不能简单地在其中放置null。
第三项是您实际的服务器端数据属性验证。如果您只有部分客户端验证(意味着并非所有字段都具有客户端验证),那么您可能会遇到奇怪的情况,即它会为客户端的某些项目抛出验证错误,然后在用户解决这些问题并提交之后,服务器端验证发现错误,您将抛出更多错误。
最后,调用IValidatableObject。不幸的是,IValidatableObject没有客户端验证,因此您将不得不为这些字段创建客户端验证,或者完全禁用客户端验证才能一次完成所有服务器端验证。
IValidatableObject是一个相当通用的接口,并且在不仅仅是MVC的更多地方使用。 MVC之所以使用它,是因为它是一个方便的现有接口。并且,在将客户端验证添加到MVC之前就已经存在。更好的方法是创建一个实现客户端验证的ValidationAttribute派生属性,然后提供适当的javascript插件以进行不干扰验证。
如果在任何步骤中验证均失败,则不会继续进行下一步。即,如果客户端验证失败,则不会调用服务器端。如果数据属性失败,则不会调用IValidatableObject。
解决此问题的一种方法:
如何强制MVC验证IValidatableObject
想到了几种不同的选择。如果您需要在客户端上进行复杂的验证,则使用Angular或Knockout之类的javascript框架将是有益的,否则,如果添加jQuery验证插件,则可能会失败:
http://jqueryvalidation.org/
也许还值得回顾一下ModelStateDictonary方法,看看这些方法是否有帮助-例如在控制器中为复杂的验证方案手动调用ModelState.AddModelError。
http://msdn.microsoft.com/zh-cn/library/system.web.mvc.modelstatedictionary_methods(v = vs.118).aspx
示例:
1 2 3 4 5 6 7 8 9 | bool valid = true; if (string.IsNullOrEmpty(model.JobNumber)) { ModelState.AddModelError("jobNumber","Please enter job number"); valid = false; } return View(model); |