C# 如何处理层之间的输入和参数验证?
如果我有一个接受用户输入的3层web表单应用程序,我知道我可以使用表示层中的验证控件验证该输入。我是否也应该在业务层和数据层进行验证,以防止SQL注入和其他问题?每一层应该进行哪些验证 另一个示例是传递ID以返回记录。数据层应该确保id有效还是应该在BLL/UI中发生?简短回答:是 在每个新层接收到输入并对其采取行动之前进行验证,通常我会在输入被使用或传递到下一层之前对其进行验证(javascript会检查它是否是有效的电子邮件并且没有恶意输入,同样,业务层在使用它构建查询之前也会进行验证) 最后一个问题:如果ID返回一条记录,那么它是有效的,您必须找到该记录的ID以确认它是否有效,因此如果您尝试这样做,您将进行大量不必要的查找C# 如何处理层之间的输入和参数验证?,c#,asp.net,C#,Asp.net,如果我有一个接受用户输入的3层web表单应用程序,我知道我可以使用表示层中的验证控件验证该输入。我是否也应该在业务层和数据层进行验证,以防止SQL注入和其他问题?每一层应该进行哪些验证 另一个示例是传递ID以返回记录。数据层应该确保id有效还是应该在BLL/UI中发生?简短回答:是 在每个新层接收到输入并对其采取行动之前进行验证,通常我会在输入被使用或传递到下一层之前对其进行验证(javascript会检查它是否是有效的电子邮件并且没有恶意输入,同样,业务层在使用它构建查询之前也会进行验证) 最
我希望这会有所帮助。我在模型视图Presenter中的Presenter层执行所有验证。验证有点棘手,因为它确实是一个横切的问题,很多次 我更喜欢在presenter层这样做,因为我可以简化对模型的调用 另一种方法是在模型层中进行验证,然后是错误通信问题,因为除了异常之外,您无法轻松地通知其他层错误。您可以始终使用数据打包异常,或者创建自己的自定义异常,您可以将错误消息或类似构造的列表附加到这些异常,但这些异常对我来说总是脏兮兮的 稍后,当我通过web服务公开我的模型时,我将在Presenter和模型中实现双重验证检查,因为如果调用web服务,则可以跳转Presenter层。另一个最大的优点是,它将presenter层的验证与模型分离,因为模型可能只需要对类型进行原始验证以匹配数据库,而我的UI的用户则需要输入更细粒度的规则,而不仅仅是物理上可以 其他问题:sql注入部分是一个模型问题,不应该位于任何中间层。但是,当文本字段不允许使用特殊字符时,大多数sql注入攻击将完全无效。另一方面,您几乎应该始终使用参数化sql,这使得sql注入不可用
关于ID的问题是一个模型问题,它可以获取具有该ID的记录,或者它应该返回null,或者根据您希望建立的约定为未找到的记录引发异常。
我是否也应该在业务层和数据层中进行验证,以防止SQL注入和问题?
是的,是的
在您的业务层代码中,您需要再次验证输入(因为客户端可能被欺骗),还需要验证您的业务逻辑,确保输入对您的应用程序有意义
至于数据层,您需要再次确保数据对数据库有效。使用参数化查询,因为这将确保不会发生SQL注入
至于您关于ID的具体问题,DB将知道是否存在ID。这是否有效,取决于它对您的业务层是否有意义。如果它纯粹是一个DB人工制品(不是对象模型的一部分),那么DB需要处理它,如果它是对象模型的一部分并且对它有意义,那么业务层应该处理它。您绝对需要在业务层和数据层中进行验证。UI是一个不受信任的层,总是有人可以绕过客户端验证,在某些情况下还可以绕过服务器端UI验证 防止SQL注入只是一个参数化查询的问题。“SQL注入”这个短语不应该再存在了,它已经解决了很多年了,但是每天我都看到人们使用字符串连接编写查询。不要这样做。参数化这些命令,你就会没事了 将应用程序分为多个层的主要原因之一是,每一层都是可重用的。如果各个层没有自己进行验证,那么它们就不是自治的,并且您没有适当的关注点分离。如果没有单个组件进行内置验证,您也无法进行任何彻底的测试 对于
内部的
或私有的
类或方法,我倾向于放宽这些限制,因为它们没有得到直接测试或使用。只要公共API得到充分验证,私有API通常可以假定类处于有效状态
因此,基本上,是的,每个层,实际上每个公共类和方法都需要验证自己的数据/参数
语义验证,如检查特定客户ID是否有效,将取决于您的设计需求。显然,在ID实际到达数据层之前,业务层无法知道ID是否存在,因此无法提前执行此检查。它是为缺少的ID引发异常,还是仅仅返回
null
/忽略错误,完全取决于类/方法的设计目的
但是,如果此ID需要采用特殊格式-例如,可能您使用的是特殊编码的帐号(“R-12345-a-678”)-则域/业务层的责任是验证输入并确保其符合正确的格式,尤其是当您的商务舱消费者试图创建新帐户时。您应该在应用程序的所有层中进行验证 什么验证