In the "
Data Member Order " article in the
MSDN Library (
http://msdn.microsoft.com/en-us/library/ms729813.aspx ) we see:
"...The basic rules for data ordering include:
If a data contract type is a part of an inheritance hierarchy, data members of its base types are always first in the order..."
And there is no way to change this behaviour.
That's exactly how my client proxy is working. It is waiting the base class properties on the first place and have not get them, and because these properties have minOccurs="0" and nillable="true" attributes the proxy just decided that Xml message does not have properties at all and silently goes on to the first derived class property.
Unfortunately the third-part service uses the opposite order (it uses a java Axis2 service), data members of its base types are always last in the order in the serialized Xml messages.
Jeff W. Barnes in (
http://jeffbarnes.net/portal/blogs/jeff_barnes/archive/2007/05/08/wcf-serialization-order-in-data-contracts.aspx) mentioned thet there is the solution but does not give it.
Is it possible to change the proxy code on my side to follow the service order? I don't know such options. Seems the WCF-classes where the whole deserialization occurs cannot be tuned up to change this order. Look one more time to the wsdl code (
Pict.2). There is nothing about this order, ther is only the complexType the AddNewCreditCardResponse with the extension base="ax21:ResponseData".
Seems the only way to fix the problem is to change the auto generated code for the response message classes and force the right order. (
Pict.6) OK from the point of view of WCF it is a wrong code, but what else we could do in this situation?
After these changes we've got the right result (see Pict.7).
=======================================================================
[Pict.1: autogenerated proxy code]
[System.SerializableAttribute()]
[System.Xml.Serialization.XmlTypeAttribute(Namespace="http://data.transaction.com/xsd")]
public partial class AddNewCreditCardResponse : ResponseData {
private string crnField;
[System.Xml.Serialization.XmlElementAttribute(IsNullable=true, Order=0)]
public string crn {
get { return this.crnField; }
set { this.crnField = value; }
}
}
...
[System.Xml.Serialization.XmlIncludeAttribute(typeof(AddNewCreditCardResponse))]
[System.Xml.Serialization.XmlTypeAttribute(Namespace="http://data.transaction.com/xsd")]
public partial class ResponseData {
private string errorCodeField;
[System.Xml.Serialization.XmlElementAttribute(IsNullable=true, Order=0)]
public string errorCode{
get { return this.errorCodeField; }
set { this.errorCodeField= value; }
}
private string errorMessageField;
[System.Xml.Serialization.XmlElementAttribute(IsNullable=true, Order=1)]
public string errorMessage{
get { return this.errorMessageField; }
set { this.errorMessageField= value; }
}
}
[Pict.2: wsdl code]
<xs:complexType name="AddNewCreditCardResponse">
<xs:complexContent mixed="false">
<xs:extension base="ax21:ResponseData">
<xs:sequence>
<xs:element minOccurs="0" name="crn" nillable="true" type="xs:string" />
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
...
<xs:complexType name="ResponseData">
<xs:sequence>
<xs:element minOccurs="0" name="errorCode" nillable="true" type="xs:string" />
<xs:element minOccurs="0" name="errorMessage" nillable="true" type="xs:string" />
</xs:sequence>
</xs:complexType>...
[Pict.3.1: original response message]
...
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Body>
<ns:addNewCreditCardResponse xmlns:ns="http://service.transaction.com">
<ns:return type="com.transaction.data.AddNewCreditCardResponseData" xmlns:ax21="http://data.transaction.com/xsd">
<ax21:crn/>
<ax21:errorCode>TXN056</ax21:errorCode>
<ax21:errorMessage>Process auth with create profile error</ax21:errorMessage>
</ns:return>
</ns:addNewCreditCardResponse>
</soapenv:Body>
</soapenv:Envelope>
[Pict.3.2: response sample with "WCF" order]
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Body>
<ns:addNewCreditCardResponse xmlns:ns="http://service.transaction.com">
<ns:return type="com.transaction.data.AddNewCreditCardResponse" xmlns:ax21="http://data.transaction.com/xsd">
<ax21:errorCode>TXN0544</ax21:errorCode>
<ax21:errorMessage>Process authentification with profile error</ax21:errorMessage>
<ax21:crn/>
</ns:return>
</ns:addNewCreditCardResponse>
</soapenv:Body>
</soapenv:Envelope>
[Pict.4: test code]
...
Transaction_Ref.TransactionSvcClient client = new TestTxsServiceConsoleApplication.Transaction_Ref.TransactionSvcClient ("TransactionSvcSOAP11port_http");
Transaction_Ref.addNewCreditCardResponse addNewCreditCardResponse = client.addNewCreditCard(...);
Console.WriteLine("crn: [{0}]", (addNewCreditCardResponse.crn == null ? "null" : addNewCreditCardResponse.crn));
Console.WriteLine("errorCode: [{0}]", (addNewCreditCardResponse.errorCode == null ? "null" : addNewCreditCardResponse.errorCode));
Console.WriteLine("errorMessage: [{0}]", (addNewCreditCardResponse.errorMessage == null ? "null" : addNewCreditCardResponse.errorMessage));
...
[Pict.5: output with original proxy code]
crn: []
errorCode: [null]
errorMessage: [null]
[Pict.6: changed proxy code]
[System.SerializableAttribute()]
[System.Xml.Serialization.XmlTypeAttribute(Namespace="http://data.transaction.com/xsd")]
public partial class AddNewCreditCardResponse {
private string crnField;
[System.Xml.Serialization.XmlElementAttribute(IsNullable=true, Order=0)]
public string crn {
get { return this.crnField; }
set { this.crnField = value; }
}
private string errorCodeField;
[System.Xml.Serialization.XmlElementAttribute(IsNullable=true, Order=1)]
public string errorCode{
get { return this.errorCodeField; }
set { this.errorCodeField= value; }
}
private string errorMessageField;
[System.Xml.Serialization.XmlElementAttribute(IsNullable=true, Order=2)]
public string errorMessage{
get { return this.errorMessageField; }
set { this.errorMessageField= value; }
}
...
[Pict.7: output with changed proxy code]
crn: []
errorCode: [TXN0544]
errorMessage: [Process authentification with profile error]
=========================================
Please, give me a feedback!