How to handle WCF error exception

I am trying to add additional SOAP error information in an open source client application. The client is configured to call "HandleFault" whenever it encounters any SOAP error. The following is a descriptor processing method:

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 the part of the SOAP error that gets passed as a β€œmessage” when I try to do something like changing the phone number to an 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 this error occurs, the client only returns back. "The request message contains errors that prevent request processing." I would like to enable the " AttributeRepresentationFailure " node and child nodes before re-throwing the exception in the client.

As I understand it, I need to define a Fault class containing these details that need to be removed, so a call to "CreateFault" can return a. I read http://msdn.microsoft.com/en-us/library/ms733841.aspx , but I just don’t understand how to define a class so that the client knows what type of error will be reset.

UPDATE

In the client side error correction 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 error always falls under the base class of failures "otherFault". My InvalidRepresentation class is defined 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() { } } 
+6
source share
3 answers

To add an answer to Fredrik, your Fault class may be what you need to pass the details of your custom error to the client. It should not inherit from another class or implement an interface. It just needs to be marked with the DataContract attribute.

How to catch it on the client side:

 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 } 
+3
source

Finally, I was able to find a solution, thanks to everyone who helped! This is not a good solution and needs to be cleaned up, but it works until I learn more about WCF and SOAP Faults. In addition, I do not have access to the service code, namely the client code. Client code runs 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 that the service issues a SOAP Fault, it is deserialized into the "RepresentationFailures" class, which I can configure before flushing back up again (in this case, in powershell).

+2
source

I use the math example from the article you talked about. Create a crash class:

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

Decorate your method with OperationContract, for example.

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

Build your MathFault object with smart data. Wrap it and throw it away:

 throw new FaultException<MathFault>(yourFault); 

Hope this helps.

+1
source

Source: https://habr.com/ru/post/947252/


All Articles