问题描述
我想在开源客户端应用程序中添加有关SOAP故障的更多信息。客户端设置为在遇到任何SOAP错误时调用HandleFault。 Handle Fault方法如下所示:
public static void HandleFault(消息消息){
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故障的一部分,当我尝试并做某事,例如将一个电话号码更改为无效的格式从客户端。
< 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>请求消息包含阻止处理请求的错误。
< / Reason>
< Detail>
< RepresentationFailures xmlns =http://schemas.microsoft.com/2006/11/ResourceManagementxmlns:xsi =http://www.w3.org/2001/XMLSchema-instancexmlns:xsd =http://www.w3.org/2001/XMLSchema>
< AttributeRepresentationFailure>
< AttributeType> OfficePhone< / AttributeType>
< AttributeValue>(123)456-7890< / AttributeValue>
< AttributeFailureCode> ValueViolatesRegularExpression< / AttributeFailureCode>
< AdditionalTextDetails>指定的属性值不满足正则表达式。< / AdditionalTextDetails>
< / AttributeRepresentationFailure>
< CorrelationId> 11042dda-3ce9-4563-b59e-d1c1355819a4< / CorrelationId>
< / RepresentationFailures>
< / Detail>
< / Fault>
遇到此故障时,客户端只返回请求消息包含阻止处理请求的错误,我想在客户端中重新抛出异常之前包括 AttributeRepresentationFailure 节点和子节点。 / p>
我理解的方式是,我需要定义一个Fault类,包含那些要退化的细节,以便调用CreateFault可以返回一个。我已阅读了但我只是不明白如何定义类,以便客户端知道什么类型的错误抛出。
strong> UPDATE
在客户端处理错误方法中添加
code> try
{
throw faultexcept;
}
catch(System.ServiceModel.FaultException< InvalidRepresentation> invalidRepresentationFault)
{
throw invalidRepresentationFault;
}
catch(System.ServiceModel.FaultException otherFault)
{
throw otherFault;
}
catch(Exception ex)
{
throw ex;
}
故障始终在基本故障类otherFault下捕获。
My InvalidRepresentation类定义如下[DataContract(Namespace = Constants.Rm.Namespace)]
pre>
public class InvalidRepresentation
{
私有字符串_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(){
}
}
解决方案我终于能找到一个解决方案,谢谢大家谁帮助!这不是最好的解决方案,需要清理,但它工作,直到我了解更多关于WCF和SOAP故障。此外,我没有访问服务代码,只是客户端代码。客户端代码作为powershell模块运行。
无效的表示故障类
使用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;
}
}
客户端处理失败代码
public static void HandleFault(Message message){
MessageFault fault = MessageFault.CreateFault(message,Int32.MaxValue);
//让故障异常选择最好的故障处理?
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< RepresentationFailures> invalidRepresentationFault)
{
throw new Exception(
String.Format(
{0} \r\ n for 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错误时,它会反序列化放入RepresentationFailures类中,我可以在重新上传(在这种情况下为powershell)之前自定义
I am trying to add more information regarding a SOAP fault in a open source client application. The client is setup to call "HandleFault" whenever it encounters any SOAP fault. The Handle Fault method is shown below:
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) ); }
Here is a portion of the SOAP Fault that is passed in as "message" when I try and do something like change a phone number to invalid format from the client.
<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>
Whenever that Fault is encountered, the client only returns back "The request message contains errors that prevent processing the request.", I would like to include the "AttributeRepresentationFailure" node and child nodes before re-throwing the exception in the client.
The way I understand it is that I need to define a Fault class that contains those details to be deseralized, so that the call to "CreateFault" can return a . I've read through http://msdn.microsoft.com/en-us/library/ms733841.aspx but I just don't understand exactly how to define the class so that the client knows what type of fault is thrown.
UPDATE
In the client side handle fault method I added
try { throw faultexcept; } catch (System.ServiceModel.FaultException<InvalidRepresentation> invalidRepresentationFault) { throw invalidRepresentationFault; } catch (System.ServiceModel.FaultException otherFault) { throw otherFault; } catch (Exception ex) { throw ex; }
The fault is always caught under the base fault class "otherFault".My InvalidRepresentation class is defined as below
[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() { } }
解决方案I was finally able to find a resolution to this, thanks to everyone who helped! This isn't the best solution and needs to be cleaned up, but it works while until I learn more about WCF and SOAP Faults. Also, I don't have access to the service code, just the client code. The client code is being ran as a powershell module.
InvalidRepresentationFault Class
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; }
}
Client HandleFault Code
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<RepresentationFailures> 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; } }
Now when the service throws a SOAP Fault it gets deserialized into the "RepresentationFailures" class, which I can customize before re-throwing back upstream (in this case to powershell)
这篇关于如何处理WCF错误异常的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!