We've built a client to an existing SOAP web service using WCF and C#. Recently, the web service was updated and our client stopped working. The problem as I see it is best explained in this blog post - Interoperability Gotcha: Order of XML Elements by Yaron Naveh.
I'll borrow Yaron's example for my question. Originally, the wsdl looked like:
<s:element name="root">
<s:complexType>
<s:sequence>
<s:element name="elem1" type="s:string" />
<s:element name="elem2" type="s:string" />
</s:sequence>
</s:complexType>
</s:element">
The WCF generated proxy used explicit element ordering like:
[XmlElement(Order=0)]
public string Elem1
{
...
}
[XmlElement(Order=1)]
public string Elem2
{
...
}
In the update, a new element was added to to the type, but this element was added to the middle of the sequence.
<s:element name="root">
<s:complexType>
<s:sequence>
<s:element name="elem1" type="s:string" />
<s:element name="NewElement" type="s:string" />
<s:element name="elem2" type="s:string" />
</s:sequence>
</s:complexType>
</s:element">
My WCF proxy cannot deserialize any elements that are ordered after the NewElement that was added.
The provider of the web service expected this change to be backwards compatible with older clients. Apparently, my client is the only one that stopped working.
Is this a breaking change in the WSDL?
Should new elements be added to the end of the sequence to prevent breaking existing clients? would that have made this backwards compatible?
If I remove the order parameter on the XmlElement Attribute would my proxies be better prepared for future changes like this? What do I give up if I remove Order?
Yes, that is a breaking change in their WSDL. You are correct, adding the new elements to the end of the sequence would make it backward compatible.
If they wanted consumers to accept elements in any order, they should have used <xsd:all>
instead of <xsd:sequence>
. And when they added the new element, it is a required element unless they add a minOccurs='0'
attribute to its schema definition to make it optional.
They could also make their schemas more forward-compatible by adding an <xsd:any>
element to the end of their sequence as a placeholder for future elements.
The main issue you may run into if you remove Order from your proxy is if they allow repetitions of elements with the same name in their sequence:
<s:element name="root">
<s:complexType>
<s:sequence>
<s:element name="elem1" type="s:string" />
<s:element name="elem2" type="s:string" />
<s:element name="elem1" type="s:string" />
</s:sequence>
</s:complexType>
</s:element">
Without your ordering indicator, WCF wouldn't know which element repetition to map to which property. If they're generating their XML from something like .NET or Java, this is very unlikely to be a problem since those usually turn arrays and Lists into a single parent element that wraps repeating child elements.
Another benefit of using <xsd:all>
is that it disallows repeating elements of the same name, thereby avoiding this issue. <xsd:sequence>
has the "feature" of allowing multiple elements of the same name, differentiated only by their location in the list.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With