在 Web 表单应用程序中,您将用户输入验证放在哪里?

  1. 看法:JavaScript 客户端
  2. 控制器:服务器端语言(C#...)
  3. 模型:数据库(存储过程或依赖项)

我认为每个级别都需要验证:

  1. 用户是否输入了合理的值
    • 日期是实际日期,数字是实际数字...
  2. 执行 1 中的所有检查。再次加上检查恶意攻击(IE XSS 或 SQL 注入)
    • 1中完成的检查。主要是为了避免用户出错时服务器往返。
    • 由于它们是在客户端用 JavaScript 完成的,因此您不能相信它们已经运行。再次验证这些值将阻止一些恶意攻击。
  3. 是否满足依赖关系(即用户是否对有效问题添加了评论)
    • 良好的界面使得这些很难被违反。如果这里有什么东西被抓到,那就说明出了什么问题。

[灵感来自 这个回应]

有帮助吗?

解决方案

我检查了所有层,但我想指出我使用的验证技巧。

我在数据库层进行验证,对模型的适当约束将提供自动数据完整性验证。

对于大多数网络程序员来说,这似乎是一门艺术。

其他提示

模型中的验证,可选的 UI 中的自动化例程,从模型中获取提示并改善用户体验。

通过自动化例程,我的意思是用户界面中不应该有任何针对每个模型的验证代码。如果您有一个验证方法库,例如 RoR 的(具有 validates_presence_of :username 之类的方法),控制器或视图应该能够读取这些方法并应用等效的 javascript(或任何方便的)方法。

这意味着您必须在用户界面中复制完整的验证库,或者如果您使用预先存在的验证库,则至少提供一个映射。但是一旦完成,您就不必在模型外部编写任何验证逻辑。

验证可以在所有层进行。

验证来自 Web 表单的输入(所有字符串、转换为正确的类型等)与验证来自 Web 服务或 XML 文件等的输入不同。每个都有其自己的特殊情况。当然,您可以创建一个 Validator 辅助类,从而外部化 Validation 并允许它被视图共享。

然后进行 DAO 层验证 - 模型中是否有足够的数据可以持久保存(以满足非空约束等)等等。您甚至可以在数据库中检查约束(状态为('N','A','S','D')等)。

这很有趣。在最长的时间里,我在模型中执行了所有验证,就在我认为的 DAL(数据访问层)之上。我的模型通常按照表数据网关进行模式化,并使用提供抽象和低级 API 的 DAL。

在 TDG 内部,我将实现业务逻辑和验证,例如:

  1. 用户名是否为空
  2. 用户名 > 30 个字符
  3. 如果记录不存在,则返回错误

随着我的应用程序变得越来越复杂,我开始意识到大部分验证可以使用 JavaScript 在客户端完成。所以我将大部分验证逻辑重构为 JS 并清理了我的模型。

然后我意识到服务器端验证(不是过滤/转义——我认为不同)也应该在服务器中完成,并且只在客户端完成,作为锦上添花。

因此,当我再次意识到输入验证/断言和业务规则/逻辑之间可能存在明显差异时,验证逻辑又回来了。

基本上,如果它可以在应用程序的客户端(使用 JS)完成,我认为这是输入验证...如果它必须由模型完成(此记录是否已经存在,等等?)那么我会认为商业逻辑。令人困惑的是它们都保护数据模型的完整性。

如果您不验证用户名的长度,那么如何阻止人们创建单字符用户名呢?

我还没有完全决定下一步将该逻辑放在哪里,我认为这实际上取决于您更喜欢什么,薄控制器,重型模型,反之亦然......

在我的例子中,控制器往往更加以应用程序为中心,而模型如果精心制作,我通常可以在“其他”项目中重用,而不仅仅是在内部,所以我更喜欢保持模型轻量级,而控制器则在较重的一侧。

推动你朝任一方向发展的力量实际上是个人观点、要求、经验等……

有趣的话题:)

验证 必须 在控制器中完成 - 这是确保安全和响应的唯一地方。

验证 应该 在视图中完成 - 它是联系点,将提供最佳的 UE 并节省服务器的额外工作。

验证 将要 在模型上完成 - 但仅限于特定核心级别的检查。数据库应该始终反映适当的约束,但让它代表真正的验证是低效的,而且数据库也不总是可以通过简单的约束来确定有效的输入。

所有验证都应该至少发生一次,并且应该在中间层进行,无论是在值对象中(在 DDD 意义上,不要与 DTO 混淆),还是通过实体本身的业务对象。可以进行客户端验证以增强用户体验。我倾向于不进行客户端验证,因为我可以立即暴露表单上的所有错误,但这只是我个人的偏好。数据库验证可以确保数据完整性,以防您搞砸了逻辑中间层或后端的东西。

我只在视图和控制器中执行此操作,数据库通过您的数据类型等强制执行其中的一些操作,但我希望在没有捕获错误的情况下不要走那么远。

不过,您几乎回答了自己的问题,重要的是要知道,您永远不能信任该视图,尽管这是向用户提供反馈的最简单途径,因此您需要至少在一个层面上进行清理。

嗯嗯,不确定。在我阅读这篇文章之前,我会说控制器:瘦控制器,胖模型

http://blog.astrumfutura.com/archives/373-The-M-in-MVC-Why-Models-are-Misunderstood-and-Unappreciated.html

由于大多数验证取决于 商业规则, ,我对 业务层 作为第三方工具类。还有其他类型的验证,例如用户输入,虽然需要在控制器中进行,但您也可以将这些验证规则封装在第三方类中。实际上,这取决于要验证的内容。

客户端验证是次要的,只是为了构建一个轻量级的 输入验证, ,但是服务器端验证是 总是需要. 。你永远不能相信用户输入;)

。网 有很好的控制来构建验证,但是 业务层 总是需要更好的方法来验证数据,而这些控制不足以完成该任务。

视图中的简单输入验证。模型中的全面验证。原因?如果您更改视图技术,并且验证位于视图/控制器中,则必须为新视图重写验证。这可能会引入错误。将其放入模型中,所有视图都会重用......

但是,正如我所说,在视图中进行简单验证可以提高速度和简便性。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top