我在ASP.NET MVC 2中广泛使用数据注释验证。这个新功能已经是一个巨大的节省时间,因为我现在可以在一个地方定义客户端验证和服务器端验证。然而,虽然我做一些详细的测试,我意识到,如果我依靠数据注释验证,有人绕过服务器端验证是很容易的。例如,如果我通过使用[必需]属性注释属性来定义必填字段,并在表单中为该必填字段放置了一个文本框,用户可以简单地从DOM中删除文本框(这可以通过Firebug轻松完成)现在,在Controller内部的ModelBinding过程中,将不会在该属性上触发数据注释验证。为了确保触发“必需”验证,我可以在ModelBinding发生后重复验证,但是我将重复验证逻辑。
每个人对验证的建议是什么?数据注释验证足够吗?还是需要重复验证以确保验证在所有情况下都被触发?
后续评论:
基于下面的答案,似乎我不能依靠模型绑定器和数据注释验证。由于我们得出的结论是需要额外的服务器端验证,我的服务层是否有一种简单的方法来根据数据注释中定义的内容触发验证?看起来这将得到我们最好的两个词…我们不需要重复验证代码,但我们仍然会确保验证被执行,即使模型绑定器没有触发它。
我将此后续评论作为一个单独的问题,因为它提出了一个不同的问题,而不是原来的。
解决方法
我认为要保持警惕关于安全,你应该选择你使服务器验证的优先级,并确保这始终是你的后备。您的服务器验证应该在没有客户端验证的情况下工作。客户端验证更多的是对于UX和对于您的设计至关重要的,它是次要的安全性。考虑到这一点,你会发现自己重复验证。目标通常是尝试设计您的应用程序,以便服务器和客户端验证可以尽可能集成,以减少在服务器和客户端上验证所需的工作。但请放心,你必须做这两个。
如果绕过客户端验证(通过DOM操作)避免服务器验证(看起来您正在指示),则可能无法正确使用此实例的服务器验证。您应该在控制器操作或服务层中再次调用服务器验证。您描述的场景不应该是无效的服务器验证。
使用您描述的方案,DataAnnotation属性方法应该足够了。看来你只需要做一些代码更改,以确保在提交表单时也调用服务器验证。