You are viewing a plain text version of this content. The canonical link for it is here.
Posted to java-user@axis.apache.org by Dino Chiesa <di...@microsoft.com> on 2005/03/16 02:32:05 UTC

RE: Using .NET how to deserialize obj from detail element of SOAP fault sentby AXIS?

first, 
get rid of that 
soapenc:Array
stuff.   
 
.NET's XML Serializer won't handle that !
 
The SOAP serializer might, but .... 
I can't help you there. 
 
 
 


________________________________

From: M S [mailto:mjherod@hotmail.com] 
Sent: Tuesday, March 15, 2005 6:53 PM
To: axis-user@ws.apache.org
Subject: Using .NET how to deserialize obj from detail element of SOAP
fault sentby AXIS?



Hello,

I'm trying to build a C# client to consume an AXIS Web Service (running
SOAP over HTTP).  The Web Service encodes full server-side exception
traces in the Soap Fault > Detail element using complex type structures
declared in the WSDL file.

 

I have had absolutely no luck working out how I can deserialize the
custom server exception object out of the detail element using .NET
(C#).  I' wondering if anyone in the AXIS community has done this
before?

 

I have tried both SoapFormatter, and XmlSerializer with absolutely no
luck.

 

try

{

    <<<< e.g. login operation >>>> 

}

catch (System.Web.Services.Protocols.SoapException e)

{

  XmlReader reader = null;

  XmlWriter writer = null;

  MemoryStream mem = new MemoryStream();

  FdkException fe = null;

 

  try

  {

    reader = new XmlNodeReader(e.Detail.FirstChild);

    writer = new XmlTextWriter(mem, System.Text.Encoding.UTF8);

    writer.WriteNode(reader,true);

    writer.Flush();

    mem.Position = 0;

 

    <<<< Add deserialization code here >>>>

    fe = (FdkException) ....

  }

  catch (Exception ex)

  {

    System.Console.WriteLine(ex.toString());

    throw;

  }

}

 

The first deserialization mechansim I tried was using
System.Runtime.Serialization.Formatters.Soap.SoapFormatter

 

SoapFormatter sf = new SoapFormatter();

sf.Binder = new FdkExceptionDeserializationBinder();

fe = (FdkException) sf.Deserialize(mem);

 

With FdkExceptionDeserializationBinder.cs looking like the following:

 

public class FdkExceptionDeserializationBinder :
System.Runtime.Serialization.SerializationBinder

{

  public override Type BindToType(string assemblyName, string typeName)

  {

    if (assemblyName.Equals("http://xmlns.mycompany.com/app/ws"))

    {

      switch (typeName)

      {

        case "FdkException" : return typeof(FdkException); break;

        case "ArrayOfFdkExceptionEntry" : return
typeof(FdkExceptionEntry[]); break;

      }

    }

    return Type.GetType(String.Format("{0}, {1}", typeName,
assemblyName));

  }

}

 

This deserialization approach resulted in an exception:

Exception Type: System.Runtime.Serialization.SerializationException

Message: No Top Object

Source: System.Runtime.Serialization.Formatters.Soap

 

 

The second deserialization mechanism I tried was using XmlSerializer:

XmlTypeMapping myMapping = (new
SoapReflectionImporter().ImportTypeMapping(typeof(FdkException)));

XmlSerializer serializer = new XmlSerializer(myMapping);

fe = (FdkException) serializer.Deserialize(mem);

 

I set Soap options in the FdkException class:

 

using System;

using System.Xml.Serialization;

...

[Serializable]

[SoapTypeAttribute(Namespace="http://xmlns.mycompany.com/app/ws",
TypeName="fault")]

public class FdkException

{

  public string errorCode;

  public FdkExceptionEntry[] exceptionEntries;

  public string serverStackTraceId;

}

 

using System;

using System.Xml.Serialization;

[Serializable]

[SoapTypeAttribute(Namespace="http://xmlns.mycompany.com/app/ws",
TypeName="FdkExceptionEntry")]

public class FdkExceptionEntry

{

  public string errorCode;

  public long id;

  public string serverStackTraceId;

}

 

 

I got the following exception:

Message: There is an error in XML Document (1,541).

Exception Type: System.InvalidOperationException

Source: System.Xml

 

Inner Exception:

Message: Cannot assign object of type System.Xml.XmlNode[] to an object
of type FdkException

Exception Type: System.InvalidCastException

 

 

Below is the SOAP message returned from the server on an invalid logon
attempt (including Fault):-

 

 

<soapenv:Envelope
xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">

  <soapenv:Body>

    <soapenv:Fault>

      <faultcode>soapenv:Server.userException</faultcode>

      <faultstring>AccessDenied</faultstring>

      <detail>

        <ns1:fault xsi:type="ns1:FdkException"
xmlns:ns1="http://xmlns.mycompany.com/app/ws">

          <errorCode xsi:type="soapenc:string"
xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/">AccessDenied -
Invalid Credentials</errorCode>

          <exceptionEntries xsi:type="ns1:ArrayOfFdkExceptionEntry"
xsi:nil="true"/>

          <serverStackTraceId xsi:type="soapenc:string"
xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"/>

        </ns1:fault>

      </detail>

    </soapenv:Fault>

  </soapenv:Body>

</soapenv:Envelope>

 

 

Below is relevant pieces of the WSDL file relating to the FdkException
object:

 

<wsdl:types>

  <schema xmlns="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://xmlns.mycompany.com/app/ws">

    <import namespace="http://schemas.xmlsoap.org/soap/encoding/"/>

    <complexType name="FdkExceptionEntry">

      <sequence>

        <element name="errorCode" nillable="true" type="xsd:string"/>

        <element name="id" type="xsd:long"/>

        <element name="serverStackTraceId" nillable="true"
type="xsd:string"/>

      </sequence>

    </complexType>

    <complexType name="ArrayOfFdkExceptionEntry">

      <complexContent>

        <restriction base="soapenc:Array">

          <attribute ref="soapenc:arrayType"
wsdl:arrayType="impl:FdkExceptionEntry[]"/>

        </restriction>

      </complexContent>

    </complexType>

    <complexType name="FdkException">

      <sequence>

        <element name="errorCode" nillable="true" type="xsd:string"/>

        <element name="exceptionEntries" nillable="true"
type="impl:ArrayOfFdkExceptionEntry"/>

        <element name="serverStackTraceId" nillable="true"
type="xsd:string"/>

      </sequence>

    </complexType>

  </schema>

</wsdl:types>

 

<wsdl:message name="FdkException">

  <wsdl:part name="fault" type="impl:FdkException"/>

</wsdl:message>

 

<wsdl:portType name="RemoteLoginManager">

  <wsdl:operation name="login" parameterOrder="username password">

    <wsdl:input name="loginRequest" message="impl:loginRequest"/>

    <wsdl:output name="loginResponse" message="impl:loginResponse"/>

    <wsdl:fault name="FdkException" message="impl:FdkException"/>

  </wsdl:operation>

</wsdl:portType>

 

<wsdl:binding name="RemoteLoginManagerSoapBinding"
type="impl:RemoteLoginManager">

  <wsdlsoap:binding style="rpc"
transport="http://schemas.xmlsoap.org/soap/http"/>

  <wsdl:operation name="login">

    <wsdlsoap:operation/>

    <wsdl:input>

      <wsdlsoap:body use="encoded"
encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
namespace="http://xmlns.mycompany.com/app/ws"/>

    </wsdl:input>

    <wsdl:output>

      <wsdlsoap:body use="encoded"
encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
namespace="http://xmlns.mycompany.com/app/ws"/>

    </wsdl:output>

    <wsdl:fault name="FdkException">

      <wsdlsoap:fault name="FdkException" use="encoded"
encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
namespace="http://xmlns.mycompany.com/app/ws"/>

    </wsdl:fault>

  </wsdl:operation>

</wsdl:binding>

 

 

Has anyone out there been able to deserialize from SOAP fault detail
element using C#?

 

many thanks,

 

Matt.


________________________________

Try the new Beta version of MSN Messenger - it's FREE!
<http://g.msn.com/8HMBENUS/2752??PS=47575>