本文介绍了如何处理WCF错误异常的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想在开源客户端应用程序中添加有关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)] 
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(){

}
}
pre>

解决方案

我终于能找到一个解决方案,谢谢大家谁帮助!这不是最好的解决方案,需要清理,但它工作,直到我了解更多关于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错误异常的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-05 21:22