Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/wcf/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Wcf 挑毛病还是不挑毛病_Wcf_Exception_Architecture_Faults - Fatal编程技术网

Wcf 挑毛病还是不挑毛病

Wcf 挑毛病还是不挑毛病,wcf,exception,architecture,faults,Wcf,Exception,Architecture,Faults,我正在和一位同事讨论什么时候在WCF服务中抛出错误,什么时候不抛出错误 一种观点认为,只有当服务操作由于某些错误而无法工作时,我们才会抛出错误;某些东西可能因此而处于无效状态。因此,有一些例子: ValidateMember(字符串名称、字符串密码、字符串国家/地区) ->如果强制参数未通过,将抛出错误,因为验证本身无法执行; ->如果发生某些内部错误(如数据库关闭),将抛出错误 ->将在所有其他情况下返回状态协定,该协定指定验证结果(MemberValidated、ErrorPassword

我正在和一位同事讨论什么时候在WCF服务中抛出错误,什么时候不抛出错误

一种观点认为,只有当服务操作由于某些错误而无法工作时,我们才会抛出错误;某些东西可能因此而处于无效状态。因此,有一些例子:

  • ValidateMember(字符串名称、字符串密码、字符串国家/地区) ->如果强制参数未通过,将抛出错误,因为验证本身无法执行; ->如果发生某些内部错误(如数据库关闭),将抛出错误 ->将在所有其他情况下返回状态协定,该协定指定验证结果(MemberValidated、ErrorPassword、MemberNotKnown,…)

  • GetMember(int memberId) ->只有当某个对象出现故障时才会抛出fault,在所有其他情况下,如果未找到,它将返回成员或null

另一种观点是,当GetMember没有找到成员时,或者在ValidateMember的情况下,密码错误时,我们也应该抛出错误


你觉得怎么样

这是一个常见的常规故障,那么抛出故障就是一个错误。软件的编写应该能够处理日常事务,比如输入错误的密码。故障处理用于异常故障,这些异常故障不被视为程序正常设计的一部分

例如,如果您的程序在编写时始终具有对数据库的访问权限,而数据库不可访问,那么“修复”就远远超出了软件的限制。应该抛出一个错误


故障处理在编程语言的结构中使用不同的逻辑流,并且只有在“离开”编程问题的正常处理时才使用它,您将使您的解决方案以一种更自然的方式利用编程语言的功能。

我认为将错误处理和故障处理分开是一种很好的做法。任何错误情况都应该由您的程序来处理-故障处理是为特殊情况保留的。作为将两者分离的指南,我发现在考虑此类情况时,记住只有三种类型的错误(在处理数据和消息时)和一种类型的错误是有用的。 错误类型与不同类型的验证相关:

  • 消息验证-您可以从消息内容确定数据是否有效

    示例:打算作为出生日期的内容-您可以从数据中判断其是否有效

  • 上下文验证-您只能通过引用消息来确定内容无效 结合系统状态

    示例:加入公司的有效日期早于该人员的出生日期

  • 对系统撒谎-您只能在稍后发送消息时确定消息出错 抛出一个异常

    示例:存储的有效出生日期和对此人出生证明的检查表明这是不正确的。纠正系统中的谎言通常需要系统外的行动,例如援引法律或纪律补救措施

  • 您的系统必须处理所有类型的错误——尽管在第三种情况下,这可能仅限于发出警报

    相反,故障(异常)只有一个原因——数据损坏(包括数据截断)。示例:未传递验证参数

    在这里,适当的机制是故障或异常处理-基本上是将问题交给系统中能够处理它的其他部分(这就是为什么应该有未处理故障的最终目的地)。

    我对此的看法

    失败的原因有三个:

  • 服务代码引发异常,例如数据库错误、代码中的逻辑错误。这是你的错
  • 客户端代码未能根据您的文档正确使用您的服务,例如,它没有设置所需的标志值,它未能传递ID。这是客户端软件开发人员的错误
  • 最终用户在屏幕上输入了一些愚蠢的内容,例如缺少出生日期、负工资。这是最终用户的错误
  • 这取决于您如何选择将实际故障契约映射到每个故障原因。例如,我们这样做:

    • 对于原因1和原因2,客户端代码需要知道的只是服务失败。我们定义了一个非常简单的“致命错误”故障协定,它只包含一个唯一的错误ID。错误的完整详细信息记录在服务器上
    • 对于原因3,最终用户需要确切地知道他/她做错了什么。我们定义了一个“validation errors”错误契约,其中包含一组友好的错误消息,供客户端代码显示在屏幕上
    我们借用原因3,并使用声明方式处理原因1和原因2。这使得代码非常简单

    澄清:

    我们在服务内部处理以下三个原因:

  • 服务代码中引发了意外异常。我们在顶层捕获它(实际上异常屏蔽捕获它,但原理是一样的)。记录完整的详细信息,然后向仅包含错误ID的客户端抛出一个
    FaultException
  • 我们验证输入数据并故意抛出异常。它通常是一个
    参数异常
    ,但任何合适的类型都可以。一旦抛出它,它将以与(1)完全相同的方式处理,因为我们希望使它在客户机上看起来相同
  • 我们验证输入数据并故意抛出异常。这一次,它是一个
    故障异常
    。我们将异常屏蔽配置为通过unwrapped传递该异常,因此它在客户端上显示为
    FaultException
    而不是
    FaultException
  • 最终结果:

    • 在所有insi中都没有捕捉块