Date: 2005-03-15T08:48:03
   Editor: DinoChiesa
   Wiki: Apache Web Services Wiki
   Page: DotNetInteropArrays
   URL: http://wiki.apache.org/ws/DotNetInteropArrays

   first edit.

New Page:

##language:en


AXIS and .NET can exchange Arrays.  Arrays of primitives, or Arrays of complex 
types. 

First thing to do is stay away from {{{SOAPENC:arrayType}}} since we all listen 
to WS-I. We'll doc/literal encoding. Agreed?
 
Ok, then Within the WSDL, in the <types> section, specify a type or element 
that wraps an array, using an element with maxOccurs != 1, like so:  

{{{
 <s:complexType name="Container">
   <s:sequence>
     <s:element minOccurs="1" maxOccurs="1" name="param1" nillable="true" 
type="s:string" /> 
     <s:element minOccurs="0" maxOccurs="unbounded" name="param2" 
type="s:string" /> 
   </s:sequence>
  </s:complexType>
}}}

The param2 above can be of any type (simple or complex or XSD primitive).  

Then, use WSDL2''''''Java to generate the Java classes for this.  The generated 
Java code will look like the following: 

{{{
 class Container{
       String param1;
       String[] param2;
        
       public String getParam2(index i) {
           return param2[i];
       }
       public void setParam2(index i, String value) {
           param2[i] = value;
       }
       public String[] getParam2() {
           return param2;
       }
       public void setParam2(String[] value) {
           param2 = value;
       }
   }
}}}

The XML on the wire will be: 

{{{ 
  <Container> 
    <param1> foo</param1> 
    <param2>bar</param2> 
    <param2>blah</param2> 
        ... 
   </Container> 
}}}

And the .NET client will be completely happy with that.  

On the other hand if you structure your WSDL to use a wrapper type 
(Array''''''Of''''''Xxx) for the array, like so: 

{{{
 
  <s:complexType name="Container">
     <s:sequence>
       <s:element minOccurs="1" maxOccurs="1" name="param1" nillable="true" 
type="s:string" />
       <s:element minOccurs="1" maxOccurs="1" name="wrapper" nillable="true" 
type="tns:ArrayOfString" />
     </s:sequence>
   </s:complexType>
   <s:complexType name="ArrayOfString">
     <s:sequence>
       <s:element minOccurs="0" maxOccurs="unbounded" name="param2" 
type="s:string" />
     </s:sequence>
   </s:complexType>
 
}}}

(the Array''''''Of''''''Xxx name is actually not significant, just the 
structure is important.) 
... then the generated Java code will look like: 
{{{
   class Container {
       String param1;
       ArrayOfString wrapper;
   }

  class ArrayOfString{
      String[] param2;
  }
}}}


... and the XML on the wire will be like this:
{{{
  <Container> 
    <param1> foo</param1> 
    <wrapper> 
        <param2>bar</param2> 
        <param2>blah</param2> 
        ... 
    </wrapper>  
   </Container> 
}}}


and .NET will be happy with that also.  

Using the wrapper type specified in the WSDL, the programming model in the 
generated Java/AXIS code explicitly exposes the Array''''''Of''''''Xxx type.  
On the other hand, with .NET, the programming model is the same: both styles of 
WSDL will generate simple arrays like My''''''Type[].  What varies on the .NET 
side is the metadata attached to the artifacts in the form of inline 
attributes.  
  
.NET can go either way.  It takes its cue from the WSDL.  
  
So you can do whatever. 

At one point, there was a bug in AXIS dealing with an operation that returns an 
array
directly, rather than a structure containing an array  (ie, an operation
like {{{String[] getInfo()}}} rather than {{{ Container getInfo()}}}).  This 
may still be present in AXIS V1.2RC3.  Dims?



Reply via email to