无效用户输入是否是抛出异常的正当理由?

时间:2009-10-23 17:42:15

标签: .net architecture exception-handling

根据.NET Framework General Reference: Error Raising and Handling Guidelines例外,在“正常”操作期间不应抛出异常。无效的用户输入到Web表单,比如用户输入重复的名称,被认为是正常的吗?的 !!重要!!:我确信我们几乎都对此有意见,请参考可靠来源。

编辑:

更多背景:我正在质疑我正在阅读的一本书提倡的模型验证方法。本书建议您在提供无效数据时从存储库中抛出自定义异常。现在,在我看来,这违反了MS指南,因为您使用异常作为流控制...除非在“正常”操作之外考虑接收无效数据。我只是想看看是否有可靠来源的进一步指导来解决这个问题。

另一个编辑:

确定 两年半之后 ,我正在将此存储库移动到WCF服务,并且在此方法中使用异常被证明是个坏主意。哦,好吧。

9 个答案:

答案 0 :(得分:13)

一般来说,无效或格式错误的输入不被视为“例外”,应使用异常以外的其他方式处理。但请注意,这是一个指导原则 - 可能会出现使用异常来处理问题会导致代码更好的情况。

答案 1 :(得分:6)

无效的用户输入是EXPECTED情况。你希望它经常像有效输入一样发生​​。这样,抛出异常可能太多了。

另一方面,如果您出于某些原因喜欢此代码样式,则可能会抛出自定义异常并在内部捕获它们。但是无效的用户输入不应该抛出那种会完全停止你的应用程序的异常。

答案 2 :(得分:3)

这是你如何做到的:

在数据库端,如果尝试创建具有重复名称的新用户记录,则抛出。这是一种特殊情况,你无法在数据库方面做任何事情。您还提供方法来检查用户名的可用性。

在UI端,您允许用户选择名称,然后检查其可用性。 UI方面负责与用户交互并告诉他们选择其他名称。由于能够检查名称的有效性,UI不应传递重复的名称...... 除非发生异常情况


我同意本案中的这本书。您的数据库是应用程序的最低级别,不应该在其中编写太多业务逻辑(如果A发生,则执行B,除非C,然后是D)。这并不意味着您无法在数据层中提供可用于避免异常的有用方法。

答案 3 :(得分:2)

异常是例外 - 这就是它们被称为异常的原因。作为一般规则,错误的用户输入不是例外,并且应该通过向所述用户发送某种类型的通知来优雅地处理。另外,不要忘记异常确实会破坏代码的性能。

http://blogs.msdn.com/kcwalina/archive/2005/03/16/396787.aspx http://msdn.microsoft.com/en-us/magazine/dd419661.aspx

答案 4 :(得分:1)

如果您根据某些标准明确验证用户输入,并计划根据该验证的结果采取行动,那么如果不抛出异常,您会发现它更容易。

答案 5 :(得分:1)

一般不会,但我可以想到我个人遇到的规则有一个例外。

我们要求我们的域对象始终有效。如果尝试创建或传递错误数据,我们会从域对象中抛出异常。但在这种情况下,这是一种“特殊情况”。为什么?逻辑是坏数据永远不会进入域。在该调用堆栈的某个地方,无法将数据输入到系统中 - 无论是通过错误计算,来自底层数据源的错误数据还是来自用户输入。

我们这样做的另一个辅助原因是域对象及其规则被封装在物理上分离的程序集中。通过这样做,我们确保尽可能多地向调用者提供信息。由于正在发生的事情的影响,假设调用者将记录这一点,以便能够看到真正的问题 - 不验证数据。

因此,如果您要查看数据是否未经过验证,或者验证自身的规则是否与您的数据持久性方法/功能不一致,我认为抛出它是完全有效的。在所有其他情况下,我倾向于避免投掷无效输入。

答案 6 :(得分:1)

我听说过,好的OO做法不会引起用户输入的异常。然而,这种逻辑确实让我有点头疼。想想这里的历史。回到C编程,我可能会写一个函数,如:

int validateUserInfo(struct info)
{
    //...
}

来电者可以这样做:

int errorCode = validateUserInfo(info);
if (errorCode != 0)
    handleError(errorcode);

据我所知,编写异常处理是为了避免返回错误条件,作为上述方法的返回值。然而,如果我不使用异常处理来验证用户信息,我是不是要回到一些关于坏数据的条件,导致我有一个if语句来检查无效数据以改变我的“成功”执行流程?

现在好像我必须检查返回值并包装在try / catch中。 C ++ / C#/ Java类中的validateUserInfo方法可能会因“异常错误”而抛出异常,并将“错误数据”验证错误作为返回值或其他某种机制返回。是不是为了某些“OO规则”而使代码更复杂?

当然,一个OO纯粹主义者会带来一些替代方案,这样我就不必实际返回“错误数据”验证错误,试图使这种情况无效,但事实是,有人会编写代码来检查用于验证错误以及为异常编写try / catch块。

如果异常处理速度很慢,那么编译器开发人员应该修复它以使其更快。这不应成为避免例外的原因。

答案 7 :(得分:0)

Steve McConnell完成的代码提供了一个非常好的防守编程检查表。在例外情况下,他包括:

  • 您的项目是否有标准(其他所有标准)
  • 有其他选择吗?
  • 你能在内部适当处理方法吗?

我的感觉是防御性编程应始终通过接收数据的方法来管理。因此,抛出异常是不合适的。

当然,总会有缓解的情况。

答案 8 :(得分:0)

我同意其他答案人员的意见,即预期输入错误,不应以异常处理。但是,如果您发现恶意输入(sql注入尝试或类似的东西),那么异常可能是合适的。