我试图在开源客户端应用程序中添加有关SOAP错误的更多信息.客户端设置为在遇到任何SOAP故障时调用“HandleFault”. Handle Fault方法如下所示:
public static void HandleFault(Message message) { MessageFault fault = MessageFault.CreateFault(message,Int32.MaxValue); throw System.ServiceModel.FaultException.CreateFault(fault,typeof(PermissionDeniedFault),typeof(EndpointUnavailable),typeof(InvalidRepresentation),typeof(UnwillingToPerformFault),typeof(CannotProcessFilter),typeof(AnonymousInteractionrequiredFault) ); }
以下是SOAP Fault的一部分,当我尝试执行诸如从客户端将电话号码更改为无效格式之类的操作时,将其作为“消息”传递.
<s:Body u:Id="_2"> <Fault xmlns="http://www.w3.org/2003/05/soap-envelope"> <Code> <Value>Sender</Value> <Subcode> <Value xmlns:a="http://schemas.xmlsoap.org/ws/2004/09/transfer">a:InvalidRepresentation</Value> </Subcode> </Code> <Reason> <Text xml:lang="en-US">The request message contains errors that prevent processing the request.</Text> </Reason> <Detail> <RepresentationFailures xmlns="http://schemas.microsoft.com/2006/11/ResourceManagement" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <AttributeRepresentationFailure> <AttributeType>OfficePhone</AttributeType> <AttributeValue>(123)456-7890</AttributeValue> <AttributeFailureCode>ValueViolatesRegularExpression</AttributeFailureCode> <AdditionalTextDetails>The specified attribute value does not satisfy the regular expression.</AdditionalTextDetails> </AttributeRepresentationFailure> <CorrelationId>11042dda-3ce9-4563-b59e-d1c1355819a4</CorrelationId> </RepresentationFailures> </Detail> </Fault>
每当遇到该Fault时,客户端只返回“请求消息包含阻止处理请求的错误.”,我想在客户端重新抛出异常之前包含“AttributeRepresentationFailure”节点和子节点.
我理解它的方式是我需要定义一个Fault类,其中包含要解除序列化的细节,以便对“CreateFault”的调用可以返回一个.我已经阅读了http://msdn.microsoft.com/en-us/library/ms733841.aspx但我只是不明白如何定义类,以便客户端知道抛出了什么类型的错误.
UPDATE
try { throw faultexcept; } catch (System.ServiceModel.FaultException<InvalidRepresentation> invalidRepresentationFault) { throw invalidRepresentationFault; } catch (System.ServiceModel.FaultException otherFault) { throw otherFault; } catch (Exception ex) { throw ex; }
故障总是在基本故障类“otherFault”下捕获.
我的InvalidRepresentation类定义如下
[DataContract(Namespace = Constants.Rm.Namespace)] public class InvalidRepresentation { private string _attributeType; private string _attributeValue; private string _attributeFailureCode; private string _additionalTextDetails; [DataMember] public string AttributeType { get { return _attributeType; } set { _attributeType = value; } } [DataMember] public string AttributeValue { get { return _attributeValue; } set { _attributeValue = value; } } [DataMember] public string AttributeFailureCode { get { return _attributeFailureCode; } set { _attributeFailureCode = value; } } [DataMember] public string AdditionalTextDetails { get { return _additionalTextDetails; } set { _additionalTextDetails = value; } } public InvalidRepresentation() { } }
解决方法
要添加到Fredrik的答案,您的Fault类可以是您将自定义错误的详细信息传达给客户端所需的任何内容.它不必从其他类继承或实现接口.它只需要用DataContract属性标记.
至于在客户端捕获它:
try { ... } catch (FaultException<MathFault> mathFault) { // handle a math fault } catch (FaultException<OtherCustomFault> otherFault) { // handle another type of custom fault } catch (Exception ex) { // regular exception handling }