WCF:DataContract 类中的 SOAP 错误或正常异常
我的服务的OperationContract 的主要参数是一个名为Preapproval 的类。在 Preapproval 类中,有一些针对 DataMember 属性的公共 getter/setter。我有验证设置器输入的代码,这样我会抛出一个 ArgumentException,如果参数为空或超出域的正确范围。
如果输入无效,我通常会在这里抛出 ArgumentException。由于这是 WCF 情况,我必须在这里抛出预定义的FaultException 而不是ArgumentException 吗?我知道,在其他地方,我可能会捕获一般异常并将它们作为故障异常重新抛出,但此活动将发生在堆栈的更高层,在 WCF 管道自动执行的某些工作中。
例如,当调用者调用我的服务时,序列化程序将反序列化其 SOAP,尝试调用我的对象上的 setter,并在实际调用我的操作之前体验 ArgumentException 的抛出。因此,在 DataContract 类中,立即抛出故障异常是良好的设计实践吗?我真的不想将自定义处理程序连接到通道调度程序。
我知道我可以直接抛出FaultExceptions,但我真的很想将这种事情限制在服务中。如果无法避免,我也可以在支持类中执行此操作,但我更愿意尽可能编写典型代码,而不是与 System.ServiceModel 等紧密耦合。
谢谢!
The main parameter to my Service's OperationContract is a class called Preapproval. In the Preapproval class, there are a few public getters/setters for the DataMember attributes. I have code that validates the input to the setters, such that I would throw an ArgumentException, if say, a parameter is blank or out of the proper bounds for the domain.
If the inputs are invalid, I usually would throw an ArgumentException here. Since this is a WCF situation, must I throw a pre-defined FaultException here rather than ArgumentException? I understand that, elsewhere, I may catch general exceptions and rethrow them as FaultExceptions, but this activity will occur higher up the stack, in some work performed automatically by WCF plumbing.
For example, when a caller invokes my service, the serializer will deserialize their SOAP, attempt to call the setters on my object, and experience the throwing of the ArgumentException, way before my operation is actually invoked. Thus, is it good design practice, in DataContract classes, to simply throw FaultExceptions right away? I really don't want to wire a custom handler up to the channel dispatcher.
I understand that I could simply throw FaultExceptions directly, but I would really like to confine that sort of thing to the service. If it cannot be avoided, I can do it in the supporting classes as well, but I would prefer to write typical code as much as possible, that is not so tightly coupled to System.ServiceModel, etc.
Thanks!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我会将FaultExceptions 保留在您的DataContract 类之外——您可能希望在WCF 上下文之外使用这些类。
防止 WCF 特定代码潜入 DataContracts(除了属性之外)的一种方法是让 DataContract 类抛出异常并在服务层中使用 企业库的WCF异常屏蔽将这些异常映射到故障合约。
基本上,企业库实现了
IErrorHandler
并将异常转换为FaultException。我认为处理程序是实现您想要的目标的唯一方法(因为您的服务中不会抛出异常)。好消息是您实际上不需要做太多事情就可以让它工作。只需向您的服务添加一个属性:
然后添加一些配置(为了节省空间而省略配置)以将异常映射到故障契约。请注意,您的操作仍然必须声明FaultContracts。
I would leave the FaultExceptions out of your DataContract class -- you might want to use those classes outside of a WCF context.
One approach that would prevent WCF specific code from sneaking into your DataContracts (besides attributes) would be to have the DataContract class throw exceptions and in the service layer use Enterprise Library's WCF Exception Shielding to map those exceptions to fault contracts.
Basically Enterprise Library implements
IErrorHandler
and converts Exceptions to FaultExceptions. I think a handler is the only way to achieve what you want (since the exceptions are not thrown in your service). The good news is that you really don't have to do much to get it working.Just add an attribute to your service:
and then add some configuration (configuration omitted to save space) to map Exceptions to a FaultContract. Note that your operations will still have to declare FaultContracts.
您的
PreApproval
类不应该知道它正在 Web 服务中使用。让它抛出如果从任何其他类型的应用程序调用它会抛出的任何异常。服务的“顶层”应该捕获异常并将其转换为适当的
FaultException
。Your
PreApproval
class should not be aware that it's being used in a web service. Let it throw whatever exception it would have thrown if it were being called from any other type of application.The "top level" of your service should catch exceptions and translate them to the appropriate
FaultException
.