我之前就这个话题问过一个类似的问题,并得到了一些很好的反馈,但我仍然对如何进行有一些疑问。
这是场景...
应用允许用户发布和删除他们对视频的评论。
当用户发表评论时,UI 层将评论字符串和 userId (guid) 传递给 BLL,然后将评论字符串和 userId (guid) 传递给 DAL。
在 UI 层,我假设我需要进行全面验证,因此我使用客户端(如果适用)和服务器端验证来确保以下内容:
- userId其实就是一个guid
- userId存在于用户数据库中(通过调用BLL方法)
- userId 是与 commentId 关联的那个(用于删除)(通过调用 BLL 方法)
- 评论不为空
- 评论不超过最大长度
- commentId > 0
- commentId存在于数据库中(通过调用BLL方法)
- videoId > 0
- videoId存在于数据库中(通过调用BLL方法)
完成所有这些验证后,我将调用 BLL 方法
保存(字符串评论, int videoId, string userId) 或者 删除(int commentId, string userId)
由于 BLL 也可以用作网络服务或用于其他页面/应用程序,我知道我也需要在 BLL 中进行验证。据我了解,我认为我需要重做我刚刚在 UI 层中所做的所有相同验证:
- userId其实就是一个guid
- userId存在于用户数据库中(通过调用BLL方法)
- userId 是与 commentId 关联的那个(用于删除)(通过调用 BLL 方法)
- 评论不为空
- 评论不超过最大长度
- commentId > 0
- commentId存在于数据库中(通过调用BLL方法)
- videoId > 0
- videoId存在于数据库中(通过调用BLL方法)
这是正确的吗?除非必须,否则我讨厌进行额外的数据库调用!
现在我需要调用关联的 DAL 调用来实际进行数据库更改。我需要在 DAL 中再次执行上述哪些验证?
这个应用程序没有被出售或任何东西,但我想了解处理验证的最佳方法,而不会通过我可能需要或不需要的额外数据库调用来降低性能。
最佳答案
我在 UI 层只对可能是无辜的用户错误的事情进行验证。这里的验证纯粹是为了可用性。根据您的列表,那将是
- 评论不为空
- 评论不超过最大长度
幸运的是,这些不需要数据库调用。
在后端,您需要验证列表中的所有内容。只有这样才能真正保证有效性、安全性、完整性等。
如果某些内容通过了 UI 层验证但未通过后端验证,则说明发生了非常非常错误的事情 - 恶意用户或代码中的错误。如果这是您代码中的错误,向用户显示验证消息对他们并没有真正的帮助。如果是恶意用户,验证消息实际上是有害的,因为它们使坏人更容易确定您执行的验证检查并发现漏洞。当后端验证失败时,您的应用应该只向用户提供一条通用错误消息。
关于c# - 每层应该进行哪些参数验证?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4898975/