Anne,

First a correction, I meant to say Java2WSDL.

I looked for a bug and I can't find anything, do you know if there's a bug filed already? If not, I will file one.

I wonder if there's still enough time to get it fixed for the 1.2 release.

Can any of the Axis developers please comment on this?

Thanks.

Tim


Anne Thomas Manes wrote:
I think so.


On Fri, 18 Mar 2005 12:38:03 -0800, Tim K. (Gmane) <[EMAIL PROTECTED]> wrote:

Anne,

Would this then be an Axis bug? Shouldn't Axis generate the proper WSDL
for custom exceptions when using WSDL2Java?

Thanks.

Tim


Anne Thomas Manes wrote:

Per both the SOAP 1.1 spec and the WS-I BP, faults must be described
as document/literal -- even if the input and output messages are
rpc/encoded. Perhaps that's why .NET is having so much trouble.

Anne


On Tue, 15 Mar 2005 20:11:45 -0800, Dino Chiesa <[EMAIL PROTECTED]> wrote:



Does .NET uses XMLSerializer behind the scenes to perform

serialization/deserialization of SOAP messages?

Yes, it can, but not SOAP Section-5 encoded messages.  In .NET, that is done
by the SOAP serializer.



Is there an alternative preferred/standard mechanism to define array types

in the WSDL?

Yes, see
http://wiki.apache.org/ws/DotNetInteropArrays?action=show



Assuming I was not using the funky array stuff, and just trying to

deserialize a standard object with xsd string/int attributes etc by using the detail element inside a SoapException, do you know how you would go about doing this?

Like this?

    catch (System.Web.Services.Protocols.SoapException ex1) {
      Console.WriteLine("SOAP Exception: '{0}'", ex1.ToString());
      if (ex1.Detail != null) {

        System.Xml.Serialization.XmlSerializer ser= new
System.Xml.Serialization.XmlSerializer(typeof(FdkException));

        System.IO.StringReader sr= new
System.IO.StringReader(ex1.Detail.InnerXml);
        FdkException fault= (FdkException) ser.Deserialize(new
System.Xml.XmlTextReader(sr));

        Console.WriteLine("fault.errorCode: '{0}'", fault.errorCode);
        Console.WriteLine("fault.stack: '{0}'", fault.serverStackTraceId);
        // etc
      }
      else
        Console.WriteLine("detail is null!");
    }


The FdkException has to be exposed into the WSDL, so that it gets generated into the client-side proxy class. or it must otherwise be known to the client.


________________________________ From: M S [mailto:[EMAIL PROTECTED] Sent: Tuesday, March 15, 2005 9:23 PM To: [email protected] Subject: RE: Using .NET how to deserialize obj from detail element of SOAP fault sentby AXIS?






Hi Dino,

Thanks for your reply.

Does .NET uses XMLSerializer behind the scenes to perform
serialization/deserialization of SOAP messages?

If so, it seems to support these complex array types (defined in the same
.WSDL file) fine - and I didn't do anything tricky to make this happen
either.  I just used the web reference tool to point to the WSDL file and
woila!


For example, on a successful login, the server returns a loginResponse message that is defined as following:

<wsdl:message name="loginResponse">
<wsdl:part name="loginReturn" type="impl:ArrayOfNamedValue" />
</wsdl:message>

<complexType name="NamedValue">
<sequence>
  <element name="name" nillable="true" type="xsd:string" />
  <element name="value" nillable="true" type="xsd:anyType" />
</sequence>
</complexType>

<complexType name="ArrayOfNamedValue">
<complexContent>
  <restriction base="soapenc:Array">
<attribute ref="soapenc:arrayType" wsdl:arrayType="impl:NamedValue[]" />
  </restriction>
</complexContent>
</complexType>

<complexType name="Item">
<sequence>
  <element name="id" type="xsd:long" />
  <element name="name" nillable="true" type="xsd:string" />
  <element name="requestedAttributes" nillable="true"
type="impl:ArrayOfNamedValue" />
  <element name="type" nillable="true" type="xsd:string" />
</sequence>
</complexType>


Where: xmlns:impl="http://xmlns.mycompany.com/app/ws"; and: xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"; and: xmlns:xsd="http://www.w3.org/2001/XMLSchema";


In my code, the following works perfectly:

int sessionTimeout = -1, transactionTimeout = -1;
Item user = null;
NamedValue[] nvArray = null;
try
{
nvArray = rlManager.login(username,password);
}
catch(System.Web.Services.Protocols.SoapException e)
{
throw;
}
for (int i=0; i <nvArray.Length; i++)
{
switch (nvArray[i].name)
{
  case WebServiceConstants.LOGIN_USER:
    if (!(nvArray[i].value is Item))
      throw new
exception.UnexpectedTypeException(WebServiceConstants.LOGIN_USER + " not an
Item.");
    user = (Item) nvArray[i].value;
    if (user.type != ItemTypes.USER)
      throw new
exception.UnexpectedTypeException(WebServiceConstants.LOGIN_USER + " not an
Item of type " + ItemTypes.USER);
    break;
  case WebServiceConstants.SESSION_TIMEOUT:
    if (!(nvArray[i].value is Int32))
      throw new
exception.UnexpectedTypeException(WebServiceConstants.SESSION_TIMEOUT + "
not an Int32.");
    sessionTimeout = (Int32) nvArray[i].value;
    break;
  case WebServiceConstants.TRANSACTION_TIMEOUT:
    if (!(nvArray[i].value is Int32))
      throw new
exception.UnexpectedTypeException(WebServiceConstants.TRANSACTION_TIMEOUT +
" not an Int32.");
    transactionTimeout = (Int32) nvArray[i].value;
    break;
  default:
    break;
}
}
if (user == null)
{
throw new exception.AccessDeniedException();
}

Is there an alternative preferred/standard mechanism to define array types
in the WSDL?

Assuming I was not using the funky array stuff, and just trying to
deserialize a standard object with xsd string/int attributes etc by using
the detail element inside a SoapException, do you know how you would go
about doing this?

many thanks,

Matt.







From: "Dino Chiesa" <[EMAIL PROTECTED]>
Reply-To: [email protected]
To: <[email protected]>
Subject: RE: Using .NET how to deserialize obj from detail element of SOAP

fault sentby AXIS?


Date: Tue, 15 Mar 2005 17:32:05 -0800

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:[EMAIL PROTECTED]
Sent: Tuesday, March 15, 2005 6:53 PM
To: [email protected]
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>

________________________________ Try the new Beta version of MSN Messenger - it's FREE!







Reply via email to