应该在每一层中进行哪些参数验证?

时间:2011-02-04 14:17:42

标签: c# asp.net parameters validation

我之前回答了一个关于这个话题的类似问题,得到了一些很好的反馈,但我仍然对如何继续有所怀疑。

这是场景......

应用允许用户发布和删除有关视频的评论。

当用户发布评论时,UI层传递注释字符串和userId(guid),并在删除时将commentId(int)和userId(guid)传递给BLL,然后BLL传递给DAL。

在UI层,我假设我需要进行完全验证,因此我使用客户端(如果适用)和服务器端验证确保以下内容:

  • userId实际上是一个guid
  • userId存在于用户数据库中(通过调用BLL方法)
  • userId是与commentId相关联的(用于删除)(通过调用BLL方法)
  • 评论不是空白
  • 评论不超过最大长度
  • commentId是> 0
  • commentId存在于数据库中(通过调用BLL方法)
  • videoId是> 0
  • videoId存在于数据库中(通过调用BLL方法)

在完成所有这些验证之后,我将把BLL方法称为

保存(字符串注释,int videoId,字符串userId) 要么 删除(int commentId,string userId)

由于BLL也可以用作web服务或其他页面/应用程序,我知道我也需要在BLL中进行验证。根据我所学到的,我认为我需要重做我在UI层中所做的所有相同的验证:

  • userId实际上是一个guid
  • userId存在于用户数据库中(通过调用BLL方法)
  • userId是与commentId相关联的(用于删除)(通过调用BLL方法)
  • 评论不是空白
  • 评论不超过最大长度
  • commentId是> 0
  • commentId存在于数据库中(通过调用BLL方法)
  • videoId是> 0
  • videoId存在于数据库中(通过调用BLL方法)

这是对的吗?除非必须,否则我讨厌进行额外的数据库调用!

现在我需要调用相关的DAL调用来实际更改数据库。我需要在DAL中再次执行以上哪些验证?

这个应用程序没有出售或任何东西,但我想了解处理验证的最佳方法,而不会通过我可能需要或可能不需要的额外数据库调用来消除性能。

4 个答案:

答案 0 :(得分:1)

在我看来,您应该在每个级别验证您有能力验证的每个项目。冷战时代的“信任但验证”声明适用于此。假设你有一个很好的分层方法,并且每个层都有可能在另一个项目的某个后期重用,假设未来的上层将以与原始层相同的方式验证是一个不好的假设。

显然,这有可能比业务逻辑添加更多的验证,甚至重复验证,但可能更安全。

如果您希望保存数据库调用,那么我会说在最低级别执行它们,但只是确保您在较高级别的错误处理足够强大,以处理冒泡的各种错误情况。

答案 1 :(得分:1)

我在UI层中进行验证仅针对可能是无辜的用户错误的事情。这里的验证纯粹是为了可用性。从您的列表中,这将是

  • 评论不是空白
  • 评论不超过最大长度

幸运的是,那些不需要数据库调用。

在后端,您需要验证列表中的所有内容。这是真正确保有效性,安全性,完整性等的唯一方法。

如果某些内容通过了UI图层验证但后端验证失败,则会发生非常非常错误的事件 - 恶意用户或代码中的错误。如果它是您的代码中的错误,向用户显示验证消息对他们来说并不是真正有用。如果它是恶意用户,则valdiation消息实际上是有害的,因为它们使得坏人更容易确定您执行的验证检查并找到漏洞。当验证在后端失败时,您的应用应该只向用户提供一般错误消息。

答案 2 :(得分:-1)

我不建议你对每个有自己数据库调用的chack做一堆额外的检查。如何创建存储过程并将所有数据库检查放入其中。然后你可以调用“Class.IsDatabaseValid(string,string,Id,whatever)”。所以“IsDatabaseValid”方法将成为BLL-validity-checks的一部分,并且你在sp上有一个db-call。

答案 3 :(得分:-1)

我知道一个相当简单的答案,但由于每个图层都代表一个边界,您不能信任图层之外的任何代码,因此,虽然您可能在UI中进行了验证,但您应该查看在您的业务层中运行的逻辑(域)作为唯一真正的验证逻辑。

请参阅专家C#2008 Business Objects的第11页,业务逻辑。