验证:在课堂上或数据库中进行验证?
我正在使用.NET 3.5中的LINQ-To-SQL,并且已经构建了一些基于底层数据库的类。我现在面临这样的决定:我是否验证班级代码或数据库中的数据?验证:在课堂上或数据库中进行验证?
我可以看到优点和缺点。如果我在数据库中进行验证,则无论使用哪个应用程序都会进行验证。 (我目前认为任何其他应用程序都不会访问此数据库,但是谁知道。)
OTOH,该类提供了一个更强大的编程环境来执行我的验证。当然,它允许我在UI处于用户可以纠正问题的状态下捕获问题,而不是等到项目提交给数据库。 Linq-to-SQL可以捕获列的数据类型,但不支持(AFAIK)对基础数据库中的任何CHECK或DEFAULT约束进行编程实施。因此,例如,实体的“Last Modified”属性:我可以使用数据库中的ON INSERT触发器更新该属性,或者我可以在类本身中对PropertyChanged事件进行响应(具有类订阅自己的事件听起来很奇怪,但由于该类在两个定义为部分类的文件中,并且其中一个文件是由IDE自动生成的,因此这样做意味着我不必篡改自动生成的文件,所以如果必须重新生成.dbml,它不会中断),或者当实体提交到数据库时,我可以在应用程序中执行此操作。
我不想在数据库和类中复制验证。我喜欢在课堂代码中验证的强大环境。但我的纯粹主义者认为,即使另一个应用程序(我再也不认为这种应用程序会发生)使用数据库,在数据库中进行验证可确保一致性。
别人怎么看待这个话题?
恕我直言,验证最好在多个层面完成。在UI层,业务逻辑层和最后的数据库本身中,我看不到执行不同类型验证的问题。
在我看来,最理想的情况是UI层验证用户提交的数据是否有可能的恶意输入,非法值,正则表达式匹配和必填字段。第二层将验证数据的类型以及是否将它们网格化在一起以形成可传播到数据存储库的具体可更新对象。数据库会强加一些基本的约束,比如你提到的所有操作。
此外,所需的验证级别会随着每个级别的降低而降低......从UI层严格到数据库层基本层。
我相信,在一个规则 - “所有输入是邪恶的,除非证实。”
我会在课堂上做。 IMAO,UI好处彻底胜过绕过您的API假设的应用程序的任何担心。
通常情况下最好是尽快发现验证错误并将其显示给用户。有时这意味着您必须在客户端进行验证才能节省服务器往返时间。但。你的DAO对象可能有自己的一些语义。这意味着你也必须验证它们(否则如果你对模式有一定的限制,你会得到数据库异常)。
我不认为这是一个非此即彼/或命题。不同类型的验证更适合不同的领域。通常,我在数据库中处理数据层中的内容验证 - 字段长度,空/非空值,格式,值等 - 以及关系验证 - 外键,唯一性等。一般来说,我会说采取务实的方法,并做出最有意义和/或容易实现的验证。
请注意,我也会尽可能多地验证客户端,因为这很容易实现。在一个网络应用程序中,除非我有理由确定它包含有效数据 - 对于用户而言,我宁愿不回复帖子。这不会消除在服务器上进行验证的需要,但它可以提供更好的用户体验,因为用户无需等待请求周期即可了解他们错过了某个字段。
如其他地方所述:做各级验证。不幸的是,这是更多的工作。但是,你真的想要想要保护你的数据库免受错误的戳或更新的应用程序。尽管如此,考虑制作某种“规则”代码生成器,它可以读取您的验证描述,并生成适合每个上下文的代码。更好的是,搜索周围,看看是否有一个可用于您正在使用的DB /中/客户端堆栈。
我想像做这样的事情:
- 有一个或多个“规则”的文件。
- 为目标代码文件(SQL,Java,C#,javascipt,其他)提供模板,其中包含将用生成的代码替换的“宏”钩子。
- 有一个make/ant/maven/rake /任何目标来生成代码作为你的构建过程的一部分。 (显然,这是假定你是不是在一个“点和流口水”建设环境 - 我用的IDE的时候,但我真的讨厌依靠他们做的版本)
嗯,这是我的蓝无论如何,天空都会接受它。
在数据库中定义约束还可以帮助防范应用程序中的任何错误,并在新功能稍后添加到应用程序时保留不变式/断言。 – ChrisW 2009-07-07 17:37:27