views:

78

answers:

2

I am trying to catch a given FaultException on a WCF client. I basically need to extract a inner description from the fault class so that I can then package it in another exception for the upper layers to do whatever.

I've done this successfully a number of time, what makes it different this time is that fault is declared as an array, as you can see from the service reference attribute declared on top of the method that throws the exception:

[System.ServiceModel.FaultContractAttribute(typeof(FaultClass[]), Action = "http://whatever/", Name = "whateverBusinessFault")] 

This is my code:

try
{
  // call service here
}
catch (FaultException<FaultClass[]> ex)
{
  if (ex.Detail != null && ex.Detail.Length > 0)
  {
    throw new CustomException(ex.Detail[0].description);
  }
  else
  {
    throw;
  }
}

Problem is Detail (which is an array) is always coming back empty in the code even if I can see the data (description field etc.) in the SOAP response from WCF trace.

So the stuff I need is definitely coming back but for some reason either it doesn't get deserialized or I can't get to it from code.

Any help appreciated!

UPDATE:

Trying with @Darin suggestion but no luck, the string I am extracting from the XmlReader is "/r/n":

var sb = new StringBuilder();

using (XmlReader reader = fault.GetReaderAtDetailContents())
{
  while (reader.Read())
     sb.AppendLine(reader.ReadOuterXml()); 
}

var detail = sb.ToString();

Looks like the detail section is not coming up at all!

A: 

I came up with the simplest test case I could. I hope it will help you. Server side:

[ServiceContract]
public interface IService1
{
    [OperationContract]
    [FaultContract(typeof(FaultClass[]))]
    string Crash();
}

public class Service1 : IService1
{
    public string Crash()
    {
        var exception = new FaultException<FaultClass[]>(new FaultClass[] { new FaultClass { Data = "TEST" } }, new FaultReason("Boom"));

        throw exception;
    }
}

[DataContract]
public class FaultClass
{
    [DataMember]
    public string Data { get; set; }
}

Client side:

try
{
    using (var client = new Service1Client())
    {
        client.Crash();
    }
}
catch(FaultException<FaultClass[]> e)
{
    //Break here
}
Johann Blais
Thanks, I have no access the service itself (it's a java axis service). I am consuming with a WCF client and it does catch the fault but the array is empty, even though I can see (from the trace) there is one item in the response from the service.
JohnIdol
It may be due to a difference in a XML namespace that would prevent the data in the Fault from being deserialized. Did you compare the content of the FaultClass from WCF with the content of a FaultClass from Java?
Johann Blais
the only thing I have is the wsdl, from which I generate the WCF service reference. I compared the content of the wsdl to the generated service reference and it looks ok. If this were to be case (namespace problems) I would expect to have deserialization issues on other types too as faults are in the same namespace as the rest of the types
JohnIdol
+1  A: 

It is difficult to say where the problem is but I suspect the smoking gun is this axis web service not generating standard message. One way to workaround this would be to parse the XML yourself:

try
{
    proxy.CallSomeMethod();
}
catch (FaultException ex)
{
    var fault = ex.CreateMessageFault();
    using (XmlReader reader = fault.GetReaderAtDetailContents())
    {
        // TODO: read the XML fault and extract the necessary information.
    }
}
Darin Dimitrov
will give it a shot - tnx
JohnIdol
I think we're getting closer! problem is I don't know how that detail is formed so don't know which elements/attributes I should be looking for. Is it gonna look exactly like the response that I see in the soap that comes back from the service?
JohnIdol
(for some reason SO doesn't let me upvote you, says I already voted which is not the case)
JohnIdol
@Johnldol, yes it will look the same as the response you got from SoapUI.
Darin Dimitrov
OK - no luck. See update, I am simply putting the detail from the xmlReader in a string (to see what it looks like) and all is there is a "/r/n". Looks like it's coming up empty this way too :(
JohnIdol