如何处理WCF故障exception
我试图在开源客户端应用程序中添加有关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的一部分,当我尝试执行诸如从客户端将电话号码更改为无效格式之类的操作时,将其作为“消息”传递。
Sender a:InvalidRepresentation
The request message contains errors that prevent processing the request. OfficePhone (123)456-7890 ValueViolatesRegularExpression The specified attribute value does not satisfy the regular expression. 11042dda-3ce9-4563-b59e-d1c1355819a4
每当遇到那个Fault时,客户端只返回“请求消息包含阻止处理请求的错误。”,我想在客户端重新抛出exception之前包含“ AttributeRepresentationFailure ”节点和子节点。
我理解它的方式是我需要定义一个Fault类,其中包含要去除的那些细节,以便对“CreateFault”的调用可以返回一个。 我已经阅读了http://msdn.microsoft.com/en-us/library/ms733841.aspx,但我只是不明白如何定义类,以便客户端知道抛出了什么类型的错误。
UPDATE
在我添加的客户端处理故障方法
try { throw faultexcept; } catch (System.ServiceModel.FaultException 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类可以是将您的自定义错误的详细信息传达给客户端所需的任何内容。 它不必从其他类inheritance或实现接口。 它只需要用DataContract属性标记。
至于在客户端捕获它:
try { ... } catch (FaultException mathFault) { // handle a math fault } catch (FaultException otherFault) { // handle another type of custom fault } catch (Exception ex) { // regular exception handling }
感谢所有帮助过的人,我终于能够找到解决方案! 这不是最好的解决方案,需要清理,但在我了解有关WCF和SOAP Faults的更多信息之前,它一直有效。 此外,我无权访问服务代码,只访问客户端代码。 客户端代码作为powershell模块运行。
InvalidRepresentationFault类
using System.Runtime.Serialization; namespace Client.Faults { public class InvalidRepresentationFault { public InvalidRepresentationFault() {} } [DataContract(Namespace = Constants.Rm.Namespace)] public class RepresentationFailures { [DataMember()] public FailureDetail AttributeRepresentationFailure; [DataContract(Namespace = Constants.Rm.Namespace)] public class FailureDetail { [DataMember(Order = 1)] public string AttributeType; [DataMember(Order = 2)] public string AttributeValue; [DataMember(Order = 3)] public string AttributeFailureCode; [DataMember(Order = 4)] public string AdditionalTextDetails; } [DataMember] public string CorrelationId; }
}
客户端HandleFault代码
public static void HandleFault(Message message) { MessageFault fault = MessageFault.CreateFault(message, Int32.MaxValue); //Let the fault exception choose the best fault to handle? System.ServiceModel.FaultException faultexcept = System.ServiceModel.FaultException.CreateFault(fault, typeof(PermissionDeniedFault), typeof(AuthenticationRequiredFault), typeof(AuthorizationRequiredFault), typeof(EndpointUnavailable), typeof(FragmentDialectNotSupported), typeof(InvalidRepresentationFault), typeof(UnwillingToPerformFault), typeof(CannotProcessFilter), typeof(FilterDialectRequestedUnavailable), typeof(UnsupportedExpiration), typeof(AnonymousInteractionRequiredFault), typeof(RepresentationFailures) ); try { throw faultexcept; } catch (System.ServiceModel.FaultException invalidRepresentationFault) { throw new Exception( String.Format( "{0}\r\nfor Attribute \"{1}\" with Value \"{2}\"", invalidRepresentationFault.Detail.AttributeRepresentationFailure.AdditionalTextDetails, invalidRepresentationFault.Detail.AttributeRepresentationFailure.AttributeType, invalidRepresentationFault.Detail.AttributeRepresentationFailure.AttributeValue ), invalidRepresentationFault ); } catch (System.ServiceModel.FaultException otherFault) { throw otherFault; } catch (Exception ex) { throw ex; } }
现在,当服务抛出SOAP Fault时,它会被反序列化为“RepresentationFailures”类,我可以在重新向上游重新抛出之前自定义它(在本例中为powershell)
我正在使用您提到的文章中的数学示例。 创建故障类:
[DataContract(Namespace="http://Microsoft.ServiceModel.Samples")] public class MathFault { ... }
用OperationContract装饰你的方法,例如
[OperationContract] [FaultContract(typeof(MathFault))] int Divide(int n1, int n2);
使用合理的数据创建MathFault对象。 把它包起来扔掉它:
throw new FaultException(yourFault);
希望这可以帮助。