Lets say I have WSDL that defines an operation that accepts a complex type, the very usual webmethod stuff like this one:
<xs:element name="createBill">
<xs:complexType>
<xs:sequence>
<xs:element minOccurs="0" name="customer" nillable="true" type="xs:string" />
<xs:element minOccurs="0" name="billId" nillable="true" type="xs:string" />
</xs:sequence>
</xs:complexType>
</xs:element>
<wsdl:message name="createBillRequest">
<wsdl:part name="parameters" element="ns:createBill" />
</wsdl:message>
<wsdl:operation name="creatBill">
<wsdl:input wsaw:Action="urn:createBill" message="axis2:createBillRequest" />
...
</wsdl:operation>
What is the WebServices standard implementation rule for the two different calls, one specifying billId as xsi:nil and the other completely omitting the node?
<creatBill ...>
<customer>1332400</customer>
<billId xsi:nil="true"/>
</createBill>
vs
<creatBill ...>
<customer>1332400</customer>
</createBill>
To reveal more background, I have an issue with one Java guy. His web service is done in Axis2 and (for reasons strange to me) treats omission of bill element differently than the nil value. My claim is that they are one and the same and that it should behave the same in both cases (e.g. create a dynamic billID). His claim is that its not the same and he only generates dynamic ID when node is missing, otherwise returns an error (“billId missing”) when node is nilled.
The practical problem I have with his claim is that both WCF and WS stack in .NET treat these as one and the same and do not even make a provision for omitting nillable parameters, making it virtually impossible for me to implement a client without writing my own WS-stack, together with WS-Security he implements. As it stands I can only call the service specifying null:
serv.createBill("1332400", null);
serv.createBill("1332400"); // ERROR: no such method
I don’t even understand how he implemented server side in Java so that one web method has different calling patterns, what is billID parameter set to by Axis2 when node is omitted? He is very uncooperative and I need some arguments (if there are any) to present to him and later to his managers because they are under support contract.
Since we cannot both be right, does anyone know what the WS standard stipulates here? Who is at fault with the standard? I am not starting a wcf vs axis flame (please refrain), I need the look on this issue from the perspective of SOAP/WSDL standards and specifications as the parent of both.
Your Web service uses the document/literal style. In that case, the Web service specifications only require that the message content (more specifically the single child of the SOAP body) is described by an XML Schema element declaration, and of course that it conforms to that declaration. Now, XML Schema indeed allows using minOccurs=”0″ and nillable=”true” at the same time, but the specification doesn’t attach any particular meaning to the absence of the element vs. an element with xsi:nil=”true”; in particular it doesn’t declare these two cases to be equivalent. It is up to the designer of the schema to define the meaning of these two cases.
Also note that there is no universal standard that describes how to translate a WSDL and schema into language specific constructs.
That being said, minOccurs=”0″ and nillable=”true” together is problematic because most languages only have a single concept, namely the null value, to represent the absence of a value. While using the null value works well if the element is declared with either minOccurs=”0″ or nillable=”true”, there is no natural way to handle elements declared with both. The JAX-WS specification addresses this issue as described in the following question:
Jaxb generated class used JAXBElement instead of specified type
In contrast to JAX-WS, some other language specific Web service binding conventions don’t address this issue properly, and using minOccurs=”0″ together with nillable=”true” often causes interoperability issues. Therefore this should be considered as a bad practice, but there is unfortunately nothing in the Web service specifications that forbids this.