none
Problem to process a fault generated by a axis web service implementation.

    Question

  • With WCF I have to connect to a web service generated with axis toolkit.

    All seems to be ok except soap fault processing.

    In the web service a fault is defined: The fault Name is errorMessage and is composed by a Code and a text that describe the error.

    A faultContract is associated to each method used in the web service.

    When the fault is catched by the proxy y obtain the following stack exception:

    <Message>Additional XML content is present in the fault detail element. Only a single element is allowed.</Message><StackTrace>   at System.ServiceModel.Dispatcher.FaultFormatter.Deserialize(MessageFault messageFault, String action)
       at System.ServiceModel.Channels.ServiceChannel.HandleReply(ProxyOperationRuntime operation, ProxyRpc&amp;amp; rpc)
       at System.ServiceModel.Channels.ServiceChannel.Call(String action, Boolean oneway, ProxyOperationRuntime operation, Object[] ins, Object[] outs, TimeSpan timeout)
       at System.ServiceModel.Channels.ServiceChannel.Call(String action, Boolean oneway, ProxyOperationRuntime operation, Object[] ins, Object[] outs)
       at System.ServiceModel.Channels.ServiceChannelProxy.InvokeService(IMethodCallMessage methodCall, ProxyOperationRuntime operation)
       at System.ServiceModel.Channels.ServiceChannelProxy.Invoke(IMessage message)
       at System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData&amp;amp; msgData, Int32 type)
       at AgilePartner.PNS.Production.Planete.PartnerMessagingPortType.send(sendRequest request)
       at AgilePartner.PNS.Production.Planete.PartnerMessagingPortTypeClient.AgilePartner.PNS.Production.Planete.PartnerMessagingPortType.send(sendRequest request)
       at AgilePartner.PNS.Production.Planete.PartnerMessagingPortTypeClient.send(SendMessageType sendReq)
       at PlaneteWebServiceTest.Program.Main(String[] args)
       at System.AppDomain.nExecuteAssembly(Assembly assembly, String[] args)
       at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
       at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
       at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
       at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
       at System.Threading.ThreadHelper.ThreadStart()

     

    The detail of the soap fault is here:

    ><soapenv:Envelope xmlnsTongue Tiedoapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><s:Header xmlnsTongue Tied="http://schemas.xmlsoap.org/soap/envelope/"></s:Header><soapenv:Body><soapenv:Fault><faultcode xmlns="">soapenvTongue Tiederver.generalException</faultcode><faultstring xmlns=""></faultstring><detail xmlns=""><ns1:errorMessage xmlns:ns1="http://planete.notaires.fr/partenaires/V1.0"><ns1:code>100</ns1:code><ns1:label>Plateforme Planete Indisponible</ns1:label></ns1:errorMessage><ns2:exceptionName xmlns:ns2="http://xml.apache.org/axis/">not.real.planete.gate.partners.connector.impl.ErrorMessageType</ns2:exceptionName><ns3:hostname xmlns:ns3="http://xml.apache.org/axis/">S300MSMECA16</ns3:hostname></detail></soapenv:Fault></soapenv:Body></soapenv:Envelope>

     

    When you observe the detail element in the fault after </errorMessage> you have twoo other elements and I think that the source of the problem is here. I could not modify the implementation generated by axis, how it is possible to consume this kind of fault detail with WCF.

     

    Angelo 

    Thursday, May 31, 2007 8:03 AM

Answers

  • It would be good to try to push on Axis to fix it, only one element is allowed in the <detail>.

     

    That said, the first thing I would try on the WCF side would be to remove the [FaultContract] attribute (which will then cause the exception to arrive as a FaultException rather than a FaultException<T>), and then parse the XML in the detail yourself, using code along these lines

                    catch (FaultException ex)

            {

                Console.WriteLine(ex.Message);

                MessageFault mf = ex.CreateMessageFault();

                XmlReader xr = mf.GetReaderAtDetailContents();

                // use xr yourself

     

    I am not certain if this will work or not, but it's a good first try.
    Thursday, May 31, 2007 5:59 PM
  •  

    It is NOT correct that only one element is allowed in the <detail>

     

    Look into WS-I Basic Profile R1002:

    A RECEIVER MUST accept faults that have any number of elements, including zero, appearing as children of the detail element. Such children can be qualified or unqualified. 

     

    Dont blame Axis for every interoperability problem ;-)

     

    Regards Benny 

    Tuesday, June 12, 2007 12:34 PM

All replies

  • It would be good to try to push on Axis to fix it, only one element is allowed in the <detail>.

     

    That said, the first thing I would try on the WCF side would be to remove the [FaultContract] attribute (which will then cause the exception to arrive as a FaultException rather than a FaultException<T>), and then parse the XML in the detail yourself, using code along these lines

                    catch (FaultException ex)

            {

                Console.WriteLine(ex.Message);

                MessageFault mf = ex.CreateMessageFault();

                XmlReader xr = mf.GetReaderAtDetailContents();

                // use xr yourself

     

    I am not certain if this will work or not, but it's a good first try.
    Thursday, May 31, 2007 5:59 PM
  •  

    It is NOT correct that only one element is allowed in the <detail>

     

    Look into WS-I Basic Profile R1002:

    A RECEIVER MUST accept faults that have any number of elements, including zero, appearing as children of the detail element. Such children can be qualified or unqualified. 

     

    Dont blame Axis for every interoperability problem ;-)

     

    Regards Benny 

    Tuesday, June 12, 2007 12:34 PM
  • You're right, I misremembered the spec here.
    Tuesday, June 12, 2007 3:43 PM
  • I have followed your proposition to catch the exception as a not typed faultexception. It works but I have to parse the xml contains in the fault tag. It's a work around...

    That means that except a Microsoft like implementation for the fault you do not have a standard mecanism to trap typed fault exeption!! Could It be possible for Microsoft to change this implemention to facilitate the integration with other web service toolkit implemention?

     

    Angelo

    Wednesday, June 13, 2007 12:52 PM
  • I am experiencing the same problem with services deployed with WSIT and Glassfish.  I also need to support typed fault exceptions.  Is this going to be fixed my MS anytime soon?

     

    Thanks

    Monday, June 18, 2007 10:00 PM
  • I have the same issue. Reading through the specs I see nothing that indicates the fault detail element may contain only one child element.

     

    It is disturbing that the exception text claims that there can be only one and that the data is "extra".

     

    However, is there a way to tell WCF to just ignore extra data received in a fault message, like you can in the service versioning scenarios?

     

    Otherwise, is there yet a MS fix for this? I'm running around touting the wonderous interop and WS-* support WCF has, and this seemingly basic support for fault <detail> elements seems broken (and it's been around since at least SOAP 1.1).

     

    Help!

    Friday, November 02, 2007 6:17 AM
  • So is MSFT going to resolve this issue?  If I understand this correctly, WCF is falling short of the spec...

     

     

    Friday, September 26, 2008 9:44 PM
  • I am hitting this exact same issue with consuming an axis webservice.   Could someone share how they are catching the exception and parsing the fault tag?  I am using Visual Studio 2008 and have consumed the service.  All of the plumbing is being done for me so I am not sure how to get to the response before getting the exceptoin "Additional XML content is present in the fault detail element. Only a singel element is allowed"
    Wednesday, November 12, 2008 9:12 PM
  • That's exact what I meet!

    No one knows how to fix it?
    Wednesday, December 10, 2008 6:49 AM
  • Hi there... any update on this issue? We really need MSFT to fix this!
    Tuesday, May 12, 2009 2:09 AM
  • HiIs there some update on this bug?

    Would be nice to avoid extra work in WCF ;)
    Friday, June 26, 2009 2:40 PM
  • Any updates here?
    Additional information. I get System.FormatException with "Additional XML content is present in the fault detail element. Only a single element is allowed."
    The inner exeption is null.

    Is there any workaroud?
    Can I some how substitute Fault handling with my own implementetion in WCF?
    Tuesday, September 08, 2009 9:13 AM
  • Ok. How I solve the problem:

    assume you have web-service client inherited from System.ServiceModel.ClientBase<T>
    1) You shoul register new endpoint behavior
    2) Register niew message inspector

    see code
    EndpointAddress endpointAddress = new EndpointAddress(url);
    MyServiceClient client = new MyServiceClient(GetBinding(), endpointAddress);
    
    client.Endpoint.Behaviors.Add(new FaultFormatingBehavior());
    ....
    
    
    internal class FaultFormatingBehavior : IEndpointBehavior
        {
            public void Validate(ServiceEndpoint endpoint){}
    
            public void AddBindingParameters(ServiceEndpoint endpoint, BindingParameterCollection bindingParameters){}
    
            public void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher){}
    
            public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime)
            {            
                clientRuntime.MessageInspectors.Add(new FaultMessageInspector());         
            }
        }
    
    public class FaultMessageInspector : IClientMessageInspector
        {
            public object BeforeSendRequest(ref Message request, IClientChannel channel)
            {
                return null;
            }
    
            public void AfterReceiveReply(ref Message reply, object correlationState)
            {
                if (reply.IsFault)
                {
                    using (XmlDictionaryReader reader = reply.GetReaderAtBodyContents())
                    {
                        XmlDocument document = new XmlDocument();
                        document.Load(reader);
                        XmlNamespaceManager nsmgr = new XmlNamespaceManager(document.NameTable);
                        //string xml = reader.ReadInnerXml();
                        XmlNode detailNode = document.SelectSingleNode("//detail", nsmgr);
                        XmlNode faultNode = detailNode.FirstChild;
    
                        //Provide your handling of additional XML
    
                        string errorCode = faultNode.SelectSingleNode("//errorCode").InnerText;
                        string errorMessage = faultNode.SelectSingleNode("//message").InnerText;
    
                        FaultCode fc = new FaultCode(errorCode);
    
                        Message newFaultMessage = Message.CreateMessage(reply.Version, fc, errorMessage, "");
                        reply = newFaultMessage;                                        
                    }
                    
                }
            }
    

    • Proposed as answer by viperguyaz Wednesday, June 16, 2010 9:34 PM
    Thursday, October 29, 2009 2:04 PM
  • Hi vasiliy,

    The methods BeforeSendRequest(.., ..),  AfterReciveReply(.., ..) are not firing.

    I inherited my web service client from System.ServiceModel.ClientBase<T>
    I defined my endpoint in web.config file.
    I register new message inspector also like this
    client.Endpoint.Behaviors.Add(new FaultFormatingBehavior());
    I am calling one operation of that service, but the two methods are not working.
    Can you please help me.

    SrinivasaRao Narra
    Friday, March 18, 2011 7:39 AM
  •  

    In proxy class, commenting out following line worked for me:

    //[System.ServiceModel.FaultContractAttribute(typeof(test.java.Exception), Action = "", Name = "Exception")]

     

    After calling the Java web service use following code to see the exception:

    catch (FaultException ex)
                {
                    logger.Error("Exception: " + ex.Message, ex);            
                }

    Wednesday, October 26, 2011 12:18 AM