2008-09-17 67 views
37

我们目前正在辩论是否最好在WCF通道上抛出错误,而不是传递指示服务状态或响应的消息。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)相关信息

回答

31

然而,这架空携带在抛出异常返回AuthenticatedDTO。 NET可能会相当昂贵。

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

我平时坚持抛出异常,因为他们清楚地传达出了问题,所有 Web服务工具包有处理它们的好方法。

在你的示例中,我会抛出一个UnauthorizedAccessException与消息“账户锁定”。

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

+0

我不同意。由于WCF应该是语言不可知的(至少在某种形式中),你不能保证在线路上传递一个Exception对象不会导致buig问题。 Java客户端。 FaultContract对象类型可以确保互操作性,因为它是OASIS规范的一部分。 – ZombieSheep 2008-09-17 09:39:40

0

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

不幸的是,我在目前的培训课程,所以不能写了一个完整的答案,但幸运的是我学习WCF中的应用程序异常管理。今晚我会回复更多的信息。 (对不起,这是一个微弱的答案)

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进来后只是开始打电话给您的服务,忘记因为不抛出异常而导致任何错误。这是另一个例外的强大力量,当出现问题并需要照顾时,他们给了我们一个良好的面子。