WCF - 错误/异常与消息

时间:2008-09-17 09:03:07

标签: wcf exception

我们目前正在争论是否最好在WCF频道上抛出错误,而不是传递指示服务状态或响应的消息。

故障来自WCF的内置支持,您可以使用内置的错误处理程序并做出相应的反应。然而,这会带来开销,因为在.NET中抛出异常可能会非常昂贵。

消息可以包含必要的信息,以确定服务调用发生的情况,而不会产生抛出异常的开销。但是,它确实需要几行重复代码来分析消息并确定其内容后面的操作。

我们开始创建一个我们可以在服务中使用的通用消息对象,这就是我们提出的:

public class ReturnItemDTO<T>
{
    [DataMember]
    public bool Success { get; set; }

    [DataMember]
    public string ErrorMessage { get; set; }

    [DataMember]
    public T Item { get; set; }
}

如果我的所有服务调用都返回此项,我可以一直检查“成功”属性以确定是否一切顺利。然后我在事件中有一个错误消息字符串表示出现了问题,并且在需要时包含Dto的通用项目。

异常信息必须记录到中央记录服务,而不是从服务传回。

思考?评论?想法?建议

对我的问题进一步澄清

我遇到的与错误合同有关的问题是沟通业务规则。

例如,如果有人登录,并且他们的帐户被锁定,我该如何沟通呢?他们的登录显然失败了,但由于“帐户锁定”的原因而失败。

我也是这样:

A)使用布尔值,抛出错误消息帐户锁定

B)返回带有相关信息的AuthenticatedDTO

3 个答案:

答案 0 :(得分:31)

  然而,这会带来开销,因为在.NET中抛出异常会非常昂贵。

您将对象序列化并反序列化为XML并通过慢速网络发送它们。抛出异常的开销与此相比可以忽略不计。

我通常坚持抛出异常,因为他们清楚地传达了出错的地方,所有 webservice工具包都有一个很好的方法来处理它们。

在你的示例中,我会抛出一个UnauthorizedAccessException并显示“Account Locked”消息。

澄清:默认情况下,.NET wcf服务会将异常转换为FaultContracts,但您可以更改此行为。 MSDN:Specifying and Handling Faults in Contracts and Services

答案 1 :(得分:6)

如果你考虑像调用任何其他方法一样调用服务,它可能有助于把事情放在眼里。想象一下,如果您调用的每个方法都返回了一个状态,那么您需要检查它是真还是假。这会非常繁琐。

result = CallMethod();
if (!result.Success) handleError();

result = CallAnotherMethod();
if (!result.Success) handleError();

result = NotAgain();
if (!result.Success) handleError();

这是结构化错误处理系统的优点之一,您可以将实际逻辑与错误处理分开。您不必继续检查,如果没有抛出异常,您就知道它是成功的。

try 
{
    CallMethod();
    CallAnotherMethod();
    NotAgain();
}
catch (Exception e)
{
    handleError();
}

同时,通过返回结果,您将对客户承担更多责任。您可能知道检查结果对象中的错误,但是John Doe进来并且刚开始调用您的服务,忘记了任何错误,因为没有抛出异常。这是另一个例外的强项,就是当出现问题并需要照顾时,它们会给我们一个好的耳光。

答案 2 :(得分:0)

我会认真考虑使用FaultContract和FaultException对象来解决这个问题。这将允许您将有意义的错误消息传递回客户端,但仅在发生故障时才会发送。

不幸的是,我现在正在参加培训课程,因此无法写出完整的答案,但幸运的是,我正在学习WCF应用程序中的异常管理。今晚我会回复更多信息。 (对不起,这是一个微弱的答案)