2013-06-13 2 views
6

오픈 소스 클라이언트 응용 프로그램에서 SOAP 오류와 관련된 자세한 정보를 추가하려고합니다. 클라이언트는 SOAP 오류가 발생할 때마다 "HandleFault"를 호출하도록 설정됩니다. 핸들 결함 방법은 다음과 같습니다WCF 오류 예외 처리 방법

여기
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 장애의 일부입니다. 그 오류가 발생 될 때마다

<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> 

, 클라이언트는 "요청 메시지가 요청을 처리하는 방지 오류가 있습니다."다시 반환, 나는 "AttributeRepresentationFailure"노드와 자식을 포함 할 것 노드에서 클라이언트에 예외를 다시 던지기 전에.

내가 이해하는 방식은 "CreateFault"에 대한 호출이 a를 반환 할 수 있도록 해당 내용이 포함 된 Fault 클래스를 정의해야한다는 것입니다. 내가 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() { 

    } 
} 

답변

1

다음과 같이 정의된다 당신은 언급. 오류 클래스 생성 :

[DataContract(Namespace="http://Microsoft.ServiceModel.Samples")] 
public class MathFault 
{  
... 
} 

OperationContract를 사용하여 메소드를 장식하십시오.

[OperationContract] 
[FaultContract(typeof(MathFault))] 
int Divide(int n1, int n2); 

현명한 데이터로 MathFault 개체를 만드십시오. 포장하고 던져 :

throw new FaultException<MathFault>(yourFault); 

희망이 도움이됩니다.

+0

감사합니다! 내가 올바른 방향으로 가고 있다고 생각하지만, Fault 클래스를 정의 할 때, 위에서 보낸 예제에서 오류 클래스를 올바르게 처리하려면 클래스가 어떻게 보이게해야합니까? 또한 클라이언트 코드에서 어떤 오류가 발생했는지 판단 할 수있는 방법은'System.ServiceModel.FaultException.CreateFault' 코드에서 처리했다고 가정합니다. –

3

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 
} 
+0

감사합니다 @ 제이슨,하지만 내 잘못은 InvalidRepresentation으로 잡히지 않습니다. 항상 일반적인 FaultException으로 간주됩니다. 내 InvalidRepresentation 클래스에 정의 된 DataContract 있습니다. 나는 어떤 종류의 결함이 던져지고 있는지를 어떻게 알 수 있는지 이해하지 못한다 ?? –

+0

서비스 측면에서 Fredrik이 아래에 설명 된 방식으로 오류를 던지고 있습니까? '새 오류 발생 <오류 코드> (사용자 오류);' – Jason

2

나는, 도움을 주신 모든 분께 감사 여기에 해결책을 찾을 마침내 수 있었다! 이것은 최상의 솔루션이 아니므로 정리해야하지만 WCF 및 SOAP 결함에 대해 자세히 알기 전까지는 작동합니다. 또한 서비스 코드에 액세스 할 수없고 클라이언트 코드 만 액세스 할 수 있습니다. 클라이언트 코드가 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<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; 
     } 
    } 
이제 서비스는 SOAP이는 "RepresentationFailures"클래스에 직렬화 복원됩니다 고장 발생시, 다시 던지기 전에 사용자 정의 할 수있는 업스트림 (이 경우 powershell)

+0

좋은 패턴 매퍼 ** FaultException ** ** 예외 **? – Kiquenet

+0

예외를 발생시키지 마십시오. 나만의 맞춤 예외를 만들고 필요한 것을 전달하십시오. – nashwan