I received no reply on the axis-user list and thought I would post here before I submit a bug.

 

Thanks.


From: Brian Fitzpatrick
Sent: Monday, July 10, 2006 12:50 PM
To: 'axis-user@ws.apache.org'
Subject: Nulls within arrays

 

I’m working with a complexType that contains various arrays. It appears that Axis 1.4 is not properly handling null items that occur within the array. Instead of using the nillable=”true/false” setting on the <element> that defines the Array, it is determining whether to send xsi:nil based on whether the complexType that contains the arrays, can be omitted (minOccurs=0).  So, it doesn’t seem to matter the settings on the <element> tag of the arrays, only whether the enclosing complexType can be omitted.

 

This causes several problems, especially with .NET interoperability:

 

(Axis client to .NET server) .NET will define the parameters of a service method as omittable (minOccurs=0), so an Axis client will never send xsi:nil to the .NET server, which throws off the size of the array, since the null array item is just omitted.

 

(.NET client to .NET server) When the same service is used from a .NET client, it will correctly use the nillable=”true/false” setting of the array to determine whether to send xsi:nil or omit the array item. So a single complexType could have multiple arrays, in which some of them are allowed to be null and others are not

 

(Axis client to Axis server) Axis will define the parameters of a service method as required (minOccurs=1), so an Axis client will ALWAYS send xsi:nil when an array item is null.  It does not look at the <element> declaration for that array to determine if it should be sending xsi:nil or omitting the item, based on the nillable=”true/false” setting. So an Axis client will sometimes be sending xsi:nil when it should not be.

 

From my interpretation, it should be looking at the nillable=”true/false” setting on the <element> tag that defines the array to determine whether to send the xsi:nil or not.  Is this a known problem?  Should I submit a bug report?  Thanks.

 

 

Detailed info:

 

I created a very simple .NET web service that defined a complexType named “TestObject”. TestObject contains one string array call StringItems, which is set for nillable=”true”. The WSDL snippets that follow were generated by .NET.

      <s:complexType name="TestObject">

        <s:sequence>

          <s:element minOccurs="0" maxOccurs="1" name="StringItems" type="tns:ArrayOfString" />

        </s:sequence>

      </s:complexType>

      <s:complexType name="ArrayOfString">

        <s:sequence>

          <s:element minOccurs="0" maxOccurs="unbounded" name="string" nillable="true" type="s:string" />

        </s:sequence>

      </s:complexType>

 

I created one method to send and receive this type:

      <s:element name="SendObjectWithArray">

        <s:complexType>

          <s:sequence>

            <s:element minOccurs="0" maxOccurs="1" name="test" type="tns:TestObject" />

          </s:sequence>

        </s:complexType>

      </s:element>

 

I created an Axis client and a .NET client to call this service. I called the service with the following array:

obj.StringItems = new string[] { "first", "second", null, "fourth (after null)", "fifth" };

 

The axis client omitted the null parameter in the request.  However, when a null was sent back from the server, it correctly preserved it in the return array.

 

The .NET client sent xsi:nil for the null parameter and correctly preserved the return xsi:nil as a null in the return array.

 

The full WSDL:

<?xml version="1.0" encoding="utf-8"?>

<wsdl:definitions xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tm="http://microsoft.com/wsdl/mime/textMatching/" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/" xmlns:tns="urn:test" xmlns:s="http://www.w3.org/2001/XMLSchema" xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/" xmlns:http="http://schemas.xmlsoap.org/wsdl/http/" targetNamespace="urn:test" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/">

  <wsdl:types>

    <s:schema elementFormDefault="qualified" targetNamespace="urn:test">

      <s:element name="SendObjectWithArray">

        <s:complexType>

          <s:sequence>

            <s:element minOccurs="0" maxOccurs="1" name="test" type="tns:TestObject" />

          </s:sequence>

        </s:complexType>

 

      </s:element>

      <s:complexType name="TestObject">

        <s:sequence>

          <s:element minOccurs="0" maxOccurs="1" name="StringItems" type="tns:ArrayOfString" />

        </s:sequence>

      </s:complexType>

      <s:complexType name="ArrayOfString">

        <s:sequence>

          <s:element minOccurs="0" maxOccurs="unbounded" name="string" nillable="true" type="s:string" />

 

        </s:sequence>

      </s:complexType>

      <s:element name="SendObjectWithArrayResponse">

        <s:complexType>

          <s:sequence>

            <s:element minOccurs="0" maxOccurs="1" name="SendObjectWithArrayResult" type="tns:TestObject" />

          </s:sequence>

        </s:complexType>

      </s:element>

 

    </s:schema>

  </wsdl:types>

  <wsdl:message name="SendObjectWithArraySoapIn">

    <wsdl:part name="parameters" element="tns:SendObjectWithArray" />

  </wsdl:message>

  <wsdl:message name="SendObjectWithArraySoapOut">

    <wsdl:part name="parameters" element="tns:SendObjectWithArrayResponse" />

  </wsdl:message>

  <wsdl:portType name="ArrayTestSoap">

 

    <wsdl:operation name="SendObjectWithArray">

      <wsdl:input message="tns:SendObjectWithArraySoapIn" />

      <wsdl:output message="tns:SendObjectWithArraySoapOut" />

    </wsdl:operation>

  </wsdl:portType>

  <wsdl:binding name="ArrayTestSoap" type="tns:ArrayTestSoap">

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

    <wsdl:operation name="SendObjectWithArray">

      <soap:operation soapAction="urn:test/SendObjectWithArray" style="document" />

 

      <wsdl:input>

        <soap:body use="literal" />

      </wsdl:input>

      <wsdl:output>

        <soap:body use="literal" />

      </wsdl:output>

    </wsdl:operation>

  </wsdl:binding>

  <wsdl:binding name="ArrayTestSoap12" type="tns:ArrayTestSoap">

 

    <soap12:binding transport="http://schemas.xmlsoap.org/soap/http" />

    <wsdl:operation name="SendObjectWithArray">

      <soap12:operation soapAction="urn:test/SendObjectWithArray" style="document" />

      <wsdl:input>

        <soap12:body use="literal" />

      </wsdl:input>

      <wsdl:output>

        <soap12:body use="literal" />

      </wsdl:output>

 

    </wsdl:operation>

  </wsdl:binding>

  <wsdl:service name="ArrayTest">

    <wsdl:port name="ArrayTestSoap" binding="tns:ArrayTestSoap">

      <soap:address location="http://localhost:1792/arraytest/ArrayTest.asmx" />

    </wsdl:port>

    <wsdl:port name="ArrayTestSoap12" binding="tns:ArrayTestSoap12">

      <soap12:address location="http://localhost:1792/arraytest/ArrayTest.asmx" />

    </wsdl:port>

 

  </wsdl:service>

</wsdl:definitions>

Reply via email to