我们目前正在争论是否通过 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以及相关信息

有帮助吗?

解决方案

然而,这会带来开销,因为在 .NET 中抛出异常的成本可能相当高。

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

我通常坚持抛出异常,因为它们清楚地表明出了问题并且 全部 Webservice 工具包有一个很好的方法来处理它们。

在您的示例中,我将抛出 UnauthorizedAccessException 并显示消息“帐户已锁定”。

澄清: 默认情况下,.NET wcf 服务将异常转换为FaultContracts,但您可以更改此行为。 MSDN:指定和处理合同和服务中的错误

其他提示

如果您考虑像调用任何其他方法一样调用该服务,这可能有助于您正确看待事情。想象一下,如果您调用的每个方法都返回一个状态,并且您需要检查它是真还是假。这会变得相当乏味。

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 进来并开始调用您的服务,而没有注意到任何错误,因为没有抛出异常。这是例外的另一个巨大优势,那就是当出现问题并需要处理时,它们会给我们一个很好的耳光。

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

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

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top