Recently I added a new property to a DataContract, which broke the API for our Java clients because the deserializer did not recognize the newly added property.
The solution to this apparently is to set the order attribute on the new property, so that it appears last in the SOAP message, then the deserializer will simply ignore it.
The problem is that this new property exists in the base class, and WCF always serializes the base class properties first, so the derived class properties would always appear afterwards regardless of the order attribute.
The only two ways I can think of to fix this are:
First solution is the worst, but easiest. Second is much more difficult and risky, but the best.
Are there any other ways I can handle this situation? Is it possible to force the default WCF serializer to handle ordering differently?
For now I've gone with the first solution, by simply making the base property internal, and hiding it in the derived class with the "new" keyword, and now it appears at the end of the SOAP message. I haven't tested this with the clients yet, but will update here once I have.
Base class:
internal bool? MyNewProperty
{
get;
set;
}
Derived class:
[DataMember(Order = 2)]
public new bool? MyNewProperty
{
get { return base.MyNewProperty; }
set { base.MyNewProperty= value; }
}
If we want to add another new property that should be backwards compatible, the Order attribute should be set to 3 (Best practice to increment with every API update).
UPDATE:
Even though I was able to get the element to appear last in the SOAP message, it is still a breaking change for some of our clients who are using Axis2, and it doesn't handle deserializing the new unrecognized property gracefully, even if it appears last. Related SO question here.