我们在哪里进行验证?模型,控制器或者视图

时间:2020-03-06 14:43:54  来源:igfitidea点击:

我们将用户输入验证放在Web表单应用程序中的什么位置?

  • 查看:JavaScript客户端
  • 控制器:服务器端语言(C#...)
  • 型号:数据库(存储过程或者依赖项)

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

  • 由于它们是在javascript中的客户端上完成的,因此我们不能相信它们已运行。再次验证这些值将阻止一些恶意攻击。

[受到此回应的启发]

解决方案

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

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

对于大多数Web程序员来说,这似乎是一种艺术。

验证可以在所有层进行。

验证来自Web表单的输入(所有字符串,转换为适当的类型等)不同于验证来自Web服务或者XML文件等的输入。每种情况都有其特殊的情况。我们当然可以创建Validator帮助器类,从而将Validation外部化并允许视图共享。

然后,我们具有DAO层验证,模型中是否有足够的数据可以保留(以满足非null约束等),依此类推。我们甚至可以在数据库中具有检查约束(状态为(" N"," A"," S"," D")等)。

我只在View and Controller中执行此操作,数据库通过数据类型执行其中的某些操作,但是我宁愿在没有发现错误的情况下做到这一点。

但是,我们几乎回答了自己的问题,要知道的重要一点是,我们永远无法信任视图,尽管这是向用户提供反馈的最简单方法,因此我们至少需要在另一个层次上进行消毒。

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

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

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

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

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

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

  • 用户名是否为空
  • 用户名是否大于30个字符
  • 如果记录不存在,则返回错误

随着我的应用程序变得越来越复杂,我开始意识到可以使用JavaScript在客户端进行很多验证。因此,我将大多数验证逻辑重构为JS并清理了我的模型。

然后,我意识到服务器端验证(而不是过滤/转义,我认为是不同的)也应该在服务器中进行验证,只有客户端才能锦上添花。

所以回到验证逻辑,当我再次意识到时,INPUT验证/声明与业务规则/逻辑之间可能存在明显的区别。

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

如果我们不验证用户名的长度,那么有什么方法可以阻止人们创建单个字符的用户名呢?

我仍然没有完全决定将逻辑放在何处,我认为这实际上取决于我们更喜欢什么,瘦控制器,重型模型或者反之亦然...

在我的案例中,控制器倾向于以应用程序为中心,而模型如果精心设计,我通常可以在"其他"项目中重用,而不仅是在内部,因此我宁愿保持模型轻便,而将控制器放在较重的一侧。

驱使我们朝任一方向前进的是真正的个人见解,要求,经验等。

有趣的主题:)

验证必须在控制器中进行,这是确保安全和响应的唯一位置。

验证应该在联系点上进行,它将提供最佳的UE,并节省服务器的额外工作。

验证将在模型上进行,但仅针对特定核心检查级别。数据库应该始终反映适当的约束,但是让它代表真正的验证是效率低下的,数据库也永远不可能通过简单的约束来确定有效的输入。

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

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

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

客户端验证是次要的验证,仅用于构建轻量级输入验证,但始终需要服务器端验证。我们永远无法相信用户的输入;)

.NET具有不错的控件来构建验证,但是业务层始终需要一种更好的方法来验证数据,而这些控件不足以完成该任务。

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

但是,正如我所说,从速度和简便性的角度来看,简单验证是可行的。