Search code examples
wcfsoapdatacontract

Effect of Soap message in Adding a new member in Data Contract


Adding new members in the Data contract are harmless for all versions of clients. Its a known fact.

I wanted to test this.

I created a Book Data Contract. Its first version had the following members.

public class Book
{
    [DataMember(IsRequired = false)]
    public long BookID;

    [DataMember(IsRequired = true)]
    public string Title;

    [DataMember(IsRequired = false)]
    public string Author;
}

The client was created for this version of Contract.

Then I added another member "Edition" to the Book and the new version of the Book is

public class Book
{
    [DataMember(IsRequired = false)]
    public long BookID;

    [DataMember(IsRequired = true)]
    public string Title;

    [DataMember(IsRequired = false)]
    public string Author;

    [DataMember(IsRequired = false)]
    public string Edition;
}

The newer version of the contract works flawlessly with the older vesion of client. I wanted to Physically see the on wire soap message. I have enabled the client and server side message logging.

I understand that new member "Edition" would be taken as Nil and would be while serializing.

But on the client side message, I saw something strange, the following.

The soap envelop looks like this

  <s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Header>
  <Action s:mustUnderstand="1" xmlns="http://schemas.microsoft.com/ws/2005/05/addressing/none">http://www.8fingergenie.com/BookShop/CheckAvailability</Action>
  <ActivityId CorrelationId="631f540a-915b-4203-8fd8-e251da2fab85" xmlns="http://schemas.microsoft.com/2004/09/ServiceModel/Diagnostics">68a15797-124d-47f7-a85a-cf5c661e8011</ActivityId>
</s:Header>
<s:Body>
  <CheckAvailability xmlns="http://www.8fingergenie.com/">
    <book xmlns:d4p1="http://8fingergenie.com" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
      <d4p1:Author>Spensor Johnson</d4p1:Author>
      <d4p1:BookID>1</d4p1:BookID>
      <d4p1:Edition i:nil="true"></d4p1:Edition>
      <d4p1:Title>Who Moved My Cheese</d4p1:Title>
    </book>
  </CheckAvailability>
</s:Body>

My question is how did the client with older version of Data contract know about edition while making communication? or am I missing something here.

Following is the structure of the client side Book's schema.

  <xs:schema xmlns:tns="http://8fingergenie.com" elementFormDefault="qualified" targetNamespace="http://8fingergenie.com" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:complexType name="Book">
  <xs:sequence>
    <xs:element minOccurs="0" name="Author" nillable="true" type="xs:string" />
    <xs:element minOccurs="0" name="BookID" type="xs:long" />
    <xs:element name="Title" nillable="true" type="xs:string" />
  </xs:sequence>
</xs:complexType>
<xs:element name="Book" nillable="true" type="tns:Book" />


Solution

  • On Further research I have found the following.

    I was using Service reference in the client. The service reference by default creates the Data contract as type derived from IExtensibleDataObject. I didn't notice this would be the default.

    So since the type is derived from IExtensibleDataObject, the new members from the other end is wraped inside the ExtensionDataObject. This is how the client was aware of the datacontract's new member.

    Thank you for everyone who tried to help me.