1

我的 Service 的 OperationContract 的主要参数是一个名为 Preapproval 的类。在 Preapproval 类中,有一些用于 DataMember 属性的公共 getter/setter。我有验证设置器输入的代码,这样我会抛出 ArgumentException,如果说参数为空白或超出域的正确范围。

如果输入无效,我通常会在这里抛出 ArgumentException。由于这是 WCF 情况,我是否必须在此处抛出预定义的 FaultException 而不是 ArgumentException?我知道,在其他地方,我可能会捕获一般异常并将它们作为 FaultExceptions 重新抛出,但是在 WCF 管道自动执行的某些工作中,此活动将发生在堆栈的更高层。

例如,当调用者调用我的服务时,序列化程序将反序列化他们的 SOAP,尝试调用我的对象上的设置器,并在实际调用我的操作之前体验到 ArgumentException 的抛出。因此,在 DataContract 类中,简单地立即抛出 FaultExceptions 是一种好的设计实践吗?我真的不想将自定义处理程序连接到通道调度程序。

我知道我可以简单地直接抛出 FaultExceptions,但我真的很想将这种事情限制在服务中。如果无法避免,我也可以在支持类中进行,但我更愿意尽可能编写典型代码,与 System.ServiceModel 等耦合不那么紧密。

谢谢!

4

2 回答 2

3

我会将 FaultExceptions 排除在您的 DataContract 类之外——您可能希望在 WCF 上下文之外使用这些类。

防止 WCF 特定代码潜入您的 DataContracts(除了属性)的一种方法是让 DataContract 类引发异常,并在服务层中使用Enterprise Library 的 WCF 异常屏蔽将这些异常映射到故障协定。

基本上企业库实现IErrorHandler并将异常转换为故障异常。我认为处理程序是实现您想要的唯一方法(因为您的服务中不会引发异常)。好消息是你真的不需要做太多事情来让它工作。

只需向您的服务添加一个属性:

[ServiceContract]
[ExceptionShielding]
public interface IApproval
{
    [OperationContract]
    [FaultContract(typeof(ApplicationServiceFault))]
    [FaultContract(typeof(SystemServiceFault))]
    void PreApprove(Preapproval preapproval);
}

然后添加一些配置(省略配置以节省空间)将异常映射到故障合同。请注意,您的操作仍然必须声明 FaultContracts。

于 2011-03-29T22:40:29.360 回答
1

您的PreApproval班级不应该知道它正在 Web 服务中使用。如果从任何其他类型的应用程序调用它,让它抛出它会抛出的任何异常。

您的服务的“顶级”应该捕获异常并将它们转换为适当的FaultException.

于 2011-03-30T02:31:25.027 回答