你在哪里做验证?模型,控制器或视图

时间:2008-09-25 16:35:01

标签: asp.net-mvc validation design-patterns

您将用户输入验证放在Web表单应用程序中的哪个位置?

  1. 查看:JavaScript客户端
  2. 控制器:服务器端语言(C#...)
  3. 模型:数据库(存储过程或依赖项)
  4. 我认为每个级别都需要验证:

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

10 个答案:

答案 0 :(得分:7)

我检查所有层级,但我想注意我使用的验证技巧。

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

这是一种似乎在大多数网络程序员身上丢失的艺术。

答案 1 :(得分:5)

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

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

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

答案 2 :(得分:4)

验证可以在所有层进行。

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

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

答案 3 :(得分:3)

这很有趣。我在模型中执行所有验证的时间最长,正好在我考虑的DAL(数据访问层)之上。我的模型通常在使用提供抽象和低级API的DAL的表数据网关之后进行模式化。

在TDG的一侧,我将实现业务逻辑和验证,例如:

  1. 用户名为空
  2. 是用户名> 30个字符
  3. 如果记录不存在,则返回错误
  4. 随着我的应用程序越来越复杂,我开始意识到可以在客户端使用JavaScript完成大部分验证。所以我将大部分验证逻辑重构为JS并清理了我的模型。

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

    当我再次意识到,在验证逻辑中,INPUT验证/断言与业务规则/逻辑之间可能存在明显差异。

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

    如果您没有'验证用户名的长度,那么最后是什么阻止人们创建单个字符用户名?

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

    在我的情况控制器往往更加以应用为中心,而模型,如果精心设计的,我可以经常在“其他”项目中重用不仅仅是内部,所以我宁愿保持模型重量轻和控制器上较重的一边。

    在任何一个方向上推动你的力量都是个人意见,要求,经验等......

    有趣的主题:)

答案 4 :(得分:3)

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

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

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

答案 5 :(得分:2)

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

答案 6 :(得分:0)

我只在View和Controller中执行,数据库通过您的数据类型和诸如此类的东西强制执行某些操作,但是如果没有我捕获错误,我宁愿它不会那么远。

你几乎已经回答了自己的问题,重要的是要知道你永远不能相信这个观点,尽管这是向用户提供反馈的最简单的途径,所以你需要至少在一个级别上进行消毒。

答案 7 :(得分:0)

嗯,不确定。我会说控制器,直到我读到这篇文章:瘦小的控制器,胖模型

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

答案 8 :(得分:0)

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

客户端验证是次要验证,仅用于构建轻量级输入验证,但服务器端验证始终需要。你永远不能信任用户输入;)

.NET 拥有很好的控件来构建验证,但业务层总是需要一种更好的方法来验证数据,而这些控制还不足以完成该任务。< / p>

答案 9 :(得分:-1)

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

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